--- /dev/null
+/*
+ * ReactOS test program -
+ *
+ * loadlib.c
+ *
+ * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <windows.h>
+#include "loadlib.h"
+#include <string.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+#define APP_VERSION 1
+#define MAX_LIBS 25
+
+#ifdef UNICODE
+#define TARGET "UNICODE"
+BOOL bUseAnsi = FALSE;
+#else
+#define TARGET "MBCS"
+BOOL bUseAnsi = TRUE;
+#endif
+BOOL verbose_flagged = FALSE;
+BOOL debug_flagged = FALSE;
+BOOL loop_flagged = FALSE;
+BOOL recursive_flagged = FALSE;
+
+HANDLE OutputHandle;
+HANDLE InputHandle;
+
+
+void dprintf(char* fmt, ...)
+{
+ va_list args;
+ char buffer[255];
+
+ va_start(args, fmt);
+ wvsprintfA(buffer, fmt, args);
+ WriteConsoleA(OutputHandle, buffer, lstrlenA(buffer), NULL, NULL);
+ va_end(args);
+}
+
+long getinput(char* buf, int buflen)
+{
+ DWORD result;
+
+ ReadConsoleA(InputHandle, buf, buflen, &result, NULL);
+ return (long)result;
+}
+
+DWORD ReportLastError(void)
+{
+ DWORD dwError = GetLastError();
+ if (dwError != ERROR_SUCCESS) {
+ PSTR msg = NULL;
+ if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ 0, dwError, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PSTR)&msg, 0, NULL)) {
+ if (msg != NULL) {
+ dprintf("ReportLastError() %d - %s\n", dwError, msg);
+ } else {
+ dprintf("ERROR: ReportLastError() %d - returned TRUE but with no msg string!\n", dwError);
+ }
+ } else {
+ dprintf("ReportLastError() %d - unknown error\n", dwError);
+ }
+ if (msg != NULL) {
+ LocalFree(msg);
+ }
+ }
+ return dwError;
+}
+
+const char* appName(const char* argv0)
+{
+ const char* name;
+
+ name = (const char*)strrchr(argv0, '\\');
+ if (name != NULL)
+ return name + 1;
+ return argv0;
+}
+
+int usage(const char* appName)
+{
+ dprintf("USAGE: %s libname [libname ...] [unicode]|[ansi] [loop][recurse]\n", appName);
+ dprintf("\tWhere libname(s) is one or more libraries to load.\n");
+ dprintf("\t[unicode] - perform tests using UNICODE api calls\n");
+ dprintf("\t[ansi] - perform tests using ANSI api calls\n");
+ dprintf("\t default is %s\n", TARGET);
+ dprintf("\t[loop] - run test process in continuous loop\n");
+ dprintf("\t[recurse] - load libraries recursively rather than sequentually\n");
+ dprintf("\t[debug] - enable debug mode (unused)\n");
+ dprintf("\t[verbose] - enable verbose output (unused)\n");
+ return 0;
+}
+
+DWORD LoadLibraryList(char** libnames, int counter, BOOL bUseAnsi)
+{
+ HMODULE hModule;
+
+ dprintf("Attempting to LoadLibrary");
+ if (bUseAnsi) {
+ dprintf("A(%s) - ", *libnames);
+ hModule = LoadLibraryA(*libnames);
+ } else {
+ int len;
+ wchar_t libnameW[500];
+ len = mbstowcs(libnameW, *libnames, strlen(*libnames));
+ if (len) {
+ libnameW[len] = L'\0';
+ dprintf("W(%S) - ", libnameW);
+ hModule = LoadLibraryW(libnameW);
+ } else {
+ return ERROR_INVALID_PARAMETER;
+ }
+ }
+ if (hModule == NULL) {
+ dprintf("\nERROR: failed to obtain handle to module %s - %x\n", *libnames, hModule);
+ return ReportLastError();
+ }
+ dprintf("%x\n", hModule);
+
+ if (counter--) {
+ LoadLibraryList(++libnames, counter, bUseAnsi);
+ }
+
+ if (!FreeLibrary(hModule)) {
+ dprintf("ERROR: failed to free module %s - %x\n", *libnames, hModule);
+ return ReportLastError();
+ } else {
+ dprintf("FreeLibrary(%x) - successfull.\n", hModule);
+ }
+ return 0L;
+}
+
+int __cdecl main(int argc, char* argv[])
+{
+ char* libs[MAX_LIBS];
+ int lib_count = 0;
+ int result = 0;
+ int i = 0;
+
+ AllocConsole();
+ InputHandle = GetStdHandle(STD_INPUT_HANDLE);
+ OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ dprintf("%s application - build %03d (default: %s)\n", appName(argv[0]), APP_VERSION, TARGET);
+ if (argc < 2) {
+ /*return */usage(appName(argv[0]));
+ }
+ memset(libs, 0, sizeof(libs));
+ for (i = 1; i < argc; i++) {
+ if (lstrcmpiA(argv[i], "ansi") == 0) {
+ bUseAnsi = TRUE;
+ } else if (lstrcmpiA(argv[i], "unicode") == 0) {
+ bUseAnsi = FALSE;
+ } else if (lstrcmpiA(argv[i], "loop") == 0) {
+ loop_flagged = 1;
+ } else if (lstrcmpiA(argv[i], "recurse") == 0) {
+ recursive_flagged = 1;
+ } else if (lstrcmpiA(argv[i], "verbose") == 0) {
+ verbose_flagged = 1;
+ } else if (lstrcmpiA(argv[i], "debug") == 0) {
+ debug_flagged = 1;
+ } else {
+ if (lib_count < MAX_LIBS) {
+ libs[lib_count] = argv[i];
+ ++lib_count;
+ }
+ }
+ }
+ if (lib_count) {
+ do {
+ if (recursive_flagged) {
+ result = LoadLibraryList(libs, lib_count - 1, bUseAnsi);
+ } else {
+ for (i = 0; i < lib_count; i++) {
+ result = LoadLibraryList(&libs[i], 0, bUseAnsi);
+ //if (result != 0) break;
+ }
+ }
+ } while (loop_flagged);
+ } else {
+ int len;
+ char buffer[500];
+ do {
+ dprintf("\nEnter library name to attempt loading: ");
+ len = getinput(buffer, sizeof(buffer) - 1);
+ if (len > 2) {
+ char* buf = buffer;
+ buffer[len-2] = '\0';
+ result = LoadLibraryList(&buf, 0, bUseAnsi);
+ } else break;
+ } while (!result && len);
+ }
+ dprintf("finished\n");
+ return result;
+}
+
+
+#ifdef _NOCRT
+char* args[] = { "loadlib.exe", "advapi32.dll", "user32.dll", "recurse"};
+int __cdecl mainCRTStartup(void)
+{
+ return main(3, args);
+}
+#endif /*__GNUC__*/
--- /dev/null
+/*
+ * ReactOS test program -
+ *
+ * loadlib.h
+ *
+ * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __LOADLIB_H__
+#define __LOADLIB_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern BOOL verbose_flagged;
+extern BOOL debug_flagged;
+extern BOOL loop_flagged;
+extern BOOL recursive_flagged;
+
+DWORD ReportLastError(void);
+long getinput(char* Buffer, int buflen);
+void dprintf(char* fmt, ...);
+
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // __LOADLIB_H__
--- /dev/null
+/*
+ * ReactOS test program -
+ *
+ * _tfileio.c
+ *
+ * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <tchar.h>
+#include <wchar.h>
+#include <stdio.h>
+
+
+#ifdef UNICODE
+#define _tfopen _wfopen
+#define _tunlink _wunlink
+#define _TEOF WEOF
+#define _gettchar getwchar
+#define _puttchar putwchar
+#define _THEX_FORMAT _T("0x%04x ")
+#else /*UNICODE*/
+#define _tfopen fopen
+#define _tunlink _unlink
+#define _TEOF EOF
+#define _gettchar getchar
+#define _puttchar putchar
+#define _THEX_FORMAT "0x%02x "
+#endif /*UNICODE*/
+
+
+#define TEST_BUFFER_SIZE 200
+#define TEST_FILE_LINES 4
+
+extern BOOL verbose_flagged;
+extern BOOL status_flagged;
+
+static TCHAR test_buffer[TEST_BUFFER_SIZE];
+
+static TCHAR dos_data[] = _T("line1: this is a bunch of readable text.\r\n")\
+ _T("line2: some more printable text and punctuation !@#$%^&*()\r\n")\
+ _T("line3: followed up with some numerals 1234567890\r\n")\
+ _T("line4: done.\r\n");
+
+static TCHAR nix_data[] = _T("line1: this is a bunch of readable text.\n")\
+ _T("line2: some more printable text and punctuation !@#$%^&*()\n")\
+ _T("line3: followed up with some numerals 1234567890\n")\
+ _T("line4: done.\n");
+
+#ifdef UNICODE
+#define TEST_B1_FILE_SIZE ((((sizeof(dos_data)/2)-1)+TEST_FILE_LINES)/2) // (166+4)/2=85
+#define TEST_B2_FILE_SIZE (((sizeof(dos_data)/2)-1)*2) // (166*2) =332
+#define TEST_B3_FILE_SIZE ((((sizeof(nix_data)/2)-1)+TEST_FILE_LINES)/2) // (162+4)/2=83
+#define TEST_B4_FILE_SIZE (((sizeof(nix_data)/2)-1)*2) // (162*2) =324
+#else /*UNICODE*/
+#define TEST_B1_FILE_SIZE (sizeof(dos_data)-1+TEST_FILE_LINES) // (166+4)=170
+#define TEST_B2_FILE_SIZE (sizeof(dos_data)-1-TEST_FILE_LINES) // (166-4)=162
+#define TEST_B3_FILE_SIZE (sizeof(nix_data)-1+TEST_FILE_LINES) // (162+4)=166
+#define TEST_B4_FILE_SIZE (sizeof(nix_data)-1) // (162) =162
+#endif /*UNICODE*/
+
+
+// result = create_test_file(file_name, _T("wb"), _T("rb"), file_data);
+
+static BOOL test_file_truncate(TCHAR* file_name)
+{
+ BOOL result = FALSE;
+ int count = -1;
+ int error_code;
+ TCHAR ch;
+ TCHAR* file_data = _T("this file should have been truncated to zero bytes...");
+ FILE *file = _tfopen(file_name, _T("wb"));
+
+ if (verbose_flagged) {
+ _tprintf(_T("test_file_truncate(\"%s\")\n"), file_name);
+ }
+
+ if (file != NULL) {
+ if (_fputts(file_data, file) != _TEOF) {
+ } else {
+ _tprintf(_T("ERROR: failed to write data to file \"%s\"\n"), file_name);
+ _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file));
+ }
+ fclose(file);
+ } else {
+ _tprintf(_T("ERROR: failed to open/create file \"%s\" for output\n"), file_name);
+ _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file));
+ }
+
+ file = _tfopen(file_name, _T("wb"));
+ if (file != NULL) {
+ error_code = ferror(file);
+ if (error_code) {
+ _tprintf(_T("ERROR: (%s) ferror returned %d\n"), file_name, error_code);
+ }
+ fclose(file);
+ } else {
+ _tprintf(_T("ERROR: (%s) failed to open file for truncating\n"), file_name);
+ }
+
+ file = _tfopen(file_name, _T("rb"));
+ if (file != NULL) {
+ count = 0;
+ while ((ch = _fgettc(file)) != _TEOF) {
+ if (verbose_flagged) {
+ _tprintf(_THEX_FORMAT, ch);
+ }
+ ++count;
+ }
+ error_code = ferror(file);
+ if (error_code) {
+ _tprintf(_T("ERROR: (%s) ferror returned %d after reading\n"), file_name, error_code);
+ perror("Read error");
+ }
+ fclose(file);
+ } else {
+ _tprintf(_T("ERROR: (%s) failed to open file for reading\n"), file_name);
+ }
+ if (count) {
+ result = TRUE;
+ }
+ return result;
+}
+
+static BOOL create_output_file(TCHAR* file_name, TCHAR* file_mode, TCHAR* file_data)
+{
+ BOOL result = FALSE;
+ FILE *file = _tfopen(file_name, file_mode);
+ if (file != NULL) {
+ if (_fputts(file_data, file) != _TEOF) {
+ result = TRUE;
+ } else {
+ _tprintf(_T("ERROR: failed to write data to file \"%s\"\n"), file_name);
+ _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file));
+ }
+ fclose(file);
+ } else {
+ _tprintf(_T("ERROR: failed to open/create file \"%s\" for output\n"), file_name);
+ _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file));
+ }
+ return result;
+}
+
+static BOOL verify_output_file(TCHAR* file_name, TCHAR* file_mode, TCHAR* file_data)
+{
+ int error_code;
+ int offset = 0;
+ int line_num = 0;
+ BOOL result = FALSE;
+ BOOL error_flagged = FALSE;
+ FILE* file = _tfopen(file_name, file_mode);
+ if (file == NULL) {
+ _tprintf(_T("ERROR: (%s) Can't open file for reading\n"), file_name);
+ _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file));
+ return FALSE;
+ } else if (status_flagged) {
+ _tprintf(_T("STATUS: (%s) opened file for reading\n"), file_name);
+ }
+ while (_fgetts(test_buffer, TEST_BUFFER_SIZE, file)) {
+ int length = _tcslen(test_buffer);
+ int req_len = _tcschr(file_data+offset, _T('\n')) - (file_data+offset) + 1;
+
+ ++line_num;
+ if (length > req_len) {
+ _tprintf(_T("ERROR: read excess bytes from line %d, length %d, but expected %d\n"), line_num, length, req_len);
+ error_flagged = TRUE;
+ break;
+ }
+ if (length < req_len) {
+ _tprintf(_T("ERROR: read to few bytes from line %d, length %d, but expected %d\n"), line_num, length, req_len);
+ error_flagged = TRUE;
+ break;
+ }
+ if (status_flagged) {
+ _tprintf(_T("STATUS: Verifying %d bytes read from line %d\n"), length, line_num);
+ }
+ if (_tcsncmp(test_buffer, file_data+offset, length - 1) == 0) {
+ result = TRUE;
+ } else {
+ if (status_flagged) {
+ int i;
+ _tprintf(_T("WARNING: (%s) failed to verify file\n"), file_name);
+ for (i = 0; i < length; i++) {
+ if (file_data[offset+i] != test_buffer[i]) {
+ _tprintf(_T("line %d, offset %d expected: 0x%04x found: 0x%04x\n"), line_num, i, (int)file_data[offset+i], (int)test_buffer[i]);
+ }
+ }
+ _tprintf(_T("\n"));
+ } else {
+ error_flagged = TRUE;
+ }
+ }
+ offset += length;
+ }
+ error_code = ferror(file);
+ if (error_code) {
+ _tprintf(_T("ERROR: (%s) ferror returned %d after reading\n"), file_name, error_code);
+ perror("Read error");
+ }
+ if (!line_num) {
+ _tprintf(_T("ERROR: (%s) failed to read from file\n"), file_name);
+ }
+ if (error_flagged == TRUE) {
+ _tprintf(_T("ERROR: (%s) failed to verify file\n"), file_name);
+ result = FALSE;
+ }
+ fclose(file);
+ return result;
+}
+
+static int create_test_file(TCHAR* file_name, TCHAR* write_mode, TCHAR* read_mode, TCHAR* file_data)
+{
+ if (status_flagged) {
+ _tprintf(_T("STATUS: Attempting to create output file %s\n"), file_name);
+ }
+ if (create_output_file(file_name, write_mode, file_data)) {
+ if (status_flagged) {
+ _tprintf(_T("STATUS: Attempting to verify output file %s\n"), file_name);
+ }
+ if (verify_output_file(file_name, read_mode, file_data)) {
+ if (status_flagged) {
+ _tprintf(_T("SUCCESS: %s verified ok\n"), file_name);
+ }
+ } else {
+ //_tprintf(_T("ERROR: failed to verify file %s\n"), file_name);
+ return 2;
+ }
+ } else {
+ _tprintf(_T("ERROR: failed to create file %s\n"), file_name);
+ return 1;
+ }
+ return 0;
+}
+
+static int check_file_size(TCHAR* file_name, TCHAR* file_mode, int expected)
+{
+ int count = 0;
+ FILE* file;
+ TCHAR ch;
+ int error_code;
+
+ if (status_flagged) {
+ //_tprintf(_T("STATUS: (%s) checking for %d bytes in %s mode\n"), file_name, expected, _tcschr(file_mode, _T('b')) ? _T("binary") : _T("text"));
+ _tprintf(_T("STATUS: (%s) checking for %d bytes with mode %s\n"), file_name, expected, file_mode);
+ }
+ file = _tfopen(file_name, file_mode);
+ if (file == NULL) {
+ _tprintf(_T("ERROR: (%s) failed to open file for reading\n"), file_name);
+ return 1;
+ }
+ while ((ch = _fgettc(file)) != _TEOF) {
+ if (verbose_flagged) {
+ _tprintf(_THEX_FORMAT, ch);
+ }
+ ++count;
+ }
+ error_code = ferror(file);
+ if (error_code) {
+ _tprintf(_T("ERROR: (%s) ferror returned %d after reading\n"), file_name, error_code);
+ perror("Read error");
+ }
+
+ if (verbose_flagged) {
+// _puttc(_T('\n'), stdout);
+ }
+ fclose(file);
+ if (count == expected) {
+ if (status_flagged) {
+ _tprintf(_T("PASSED: (%s) read %d bytes\n"), file_name, count);
+ }
+ } else {
+ _tprintf(_T("FAILED: (%s) read %d bytes but expected %d using mode \"%s\"\n"), file_name, count, expected, file_mode);
+ }
+ return (count == expected) ? 0 : -1;
+}
+
+static int test_console_io(void)
+{
+ TCHAR buffer[81];
+ TCHAR ch;
+ int i, j;
+
+ _tprintf(_T("Enter a line for echoing:\n"));
+
+ //for (i = 0; (i < 80) && ((ch = _gettchar()) != _TEOF) && (ch != _T('\n')); i++) {
+ for (i = 0; (i < 80) && ((ch = _gettc(stdin)) != _TEOF) && (ch != _T('\n')); i++) {
+ buffer[i] = (TCHAR)ch;
+ }
+ buffer[i] = _T('\0');
+ for (j = 0; j < i; j++) {
+ _puttc(buffer[j], stdout);
+ }
+ _puttc(_T('\n'), stdout);
+ _tprintf(_T("%s\n"), buffer);
+ return 0;
+}
+
+static int test_console_getchar(void)
+{
+ int result = 0;
+ TCHAR ch;
+
+ _tprintf(_T("Enter lines for dumping or <ctrl-z><nl> to finish:\n"));
+
+ //while ((ch = _gettchar()) != _TEOF) {
+ while ((ch = _gettc(stdin)) != _TEOF) {
+ _tprintf(_THEX_FORMAT, ch);
+ //printf("0x%04x ", ch);
+ }
+ return result;
+}
+
+static int test_console_putch(void)
+{
+ int result = 0;
+
+ _putch('1');
+ _putch('@');
+ _putch('3');
+ _putch(':');
+ _putch('\n');
+ _putch('a');
+ _putch('B');
+ _putch('c');
+ _putch(':');
+ _putch('\n');
+ return result;
+}
+
+static int test_unlink_files(void)
+{
+ int result = 0;
+
+ //printf("sizeof dos_data: %d\n", sizeof(dos_data));
+ //printf("sizeof nix_data: %d\n", sizeof(nix_data));
+
+ result |= _tunlink(_T("binary.dos"));
+ result |= _tunlink(_T("binary.nix"));
+ result |= _tunlink(_T("text.dos"));
+ result |= _tunlink(_T("text.nix"));
+ return result;
+}
+
+static int test_text_fileio(TCHAR* file_name, TCHAR* file_data, int tsize, int bsize)
+{
+ int result = 0;
+
+ result = create_test_file(file_name, _T("w"), _T("r"), file_data);
+ result = check_file_size(file_name, _T("r"), tsize);
+ result = check_file_size(file_name, _T("rb"), bsize);
+ return result;
+}
+
+static int test_binary_fileio(TCHAR* file_name, TCHAR* file_data, int tsize, int bsize)
+{
+ int result = 0;
+
+ result = create_test_file(file_name, _T("wb"), _T("rb"), file_data);
+ result = check_file_size(file_name, _T("r"), tsize);
+ result = check_file_size(file_name, _T("rb"), bsize);
+ return result;
+}
+
+static int test_files(int test_num, char* type)
+{
+ int result = 0;
+
+ printf("performing test: %d (%s)\n", test_num, type);
+
+
+ if (test_file_truncate(_T("zerosize.foo"))) {
+ printf("System unable to truncate files yet, unlinking:\n");
+ test_unlink_files();
+ }
+
+ switch (test_num) {
+ case 1:
+ result = test_text_fileio(_T("text.dos"), dos_data, 166, TEST_B1_FILE_SIZE);
+ break;
+ case 2:
+ result = test_binary_fileio(_T("binary.dos"), dos_data, TEST_B2_FILE_SIZE, 166);
+ break;
+ case 3:
+ result = test_text_fileio(_T("text.nix"), nix_data, 162, TEST_B3_FILE_SIZE);
+ break;
+ case 4:
+ result = test_binary_fileio(_T("binary.nix"), nix_data, TEST_B4_FILE_SIZE, 162);
+ break;
+ case 5:
+ result = test_console_io();
+ break;
+ case 6:
+ result = test_console_getchar();
+ break;
+ case 7:
+ result = test_console_putch();
+ break;
+ case -1:
+ result = test_unlink_files();
+ break;
+ default:
+ _tprintf(_T("no test number selected\n"));
+ break;
+ }
+ return result;
+}
--- /dev/null
+/*
+ * ReactOS test program -
+ *
+ * _fileio.c
+ *
+ * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#undef UNICODE
+#undef _UNICODE
+#include "_tfileio.c"
+
+
+int run_ansi_tests(int test_num)
+{
+ return test_files(test_num, "ANSI");
+}
--- /dev/null
+/*
+ * ReactOS test program -
+ *
+ * main.c
+ *
+ * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <tchar.h>
+#include <wchar.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "main.h"
+
+
+#define VERSION 1
+
+#ifdef UNICODE
+#define TARGET "UNICODE"
+#else
+#define TARGET "MBCS"
+#endif
+
+BOOL verbose_flagged = 0;
+BOOL status_flagged = 0;
+
+int usage(char* argv0)
+{
+ printf("USAGE: %s test_id [unicode]|[ansi] [clean]|[status][verbose]\n", argv0);
+ printf("\tWhere test_id is one of:\n");
+ printf("\t0 - (default) regression mode, run tests 1-4 displaying failures only\n");
+ printf("\t1 - Write DOS style eol data to file in text mode (text.dos)\n");
+ printf("\t2 - Write NIX style eol data to file in binary mode (binary.dos)\n");
+ printf("\t3 - Write DOS style eol data to file in text mode (text.nix)\n");
+ printf("\t4 - Write NIX style eol data to file in binary mode (binary.nix)\n");
+ printf("\t5 - Echo console line input\n");
+ printf("\t6 - Dump console line input in hex format\n");
+ printf("\t7 - The source code is your friend\n");
+ printf("\t[unicode] - perform tests using UNICODE versions of library functions\n");
+ printf("\t[ansi] - perform tests using ANSI versions of library functions\n");
+ printf("\t If neither unicode or ansi is specified build default is used\n");
+ printf("\t[clean] - delete all temporary test output files\n");
+ printf("\t[status] - enable extra status display while running\n");
+ printf("\t[verbose] - enable verbose output when running\n");
+ return 0;
+}
+
+int __cdecl main(int argc, char* argv[])
+{
+ int test_num = 0;
+ int version = 0;
+ int result = 0;
+ int i = 0;
+
+ printf("%s test application - build %03d (default: %s)\n", argv[0], VERSION, TARGET);
+ if (argc < 2) {
+ return usage(argv[0]);
+ }
+ for (i = 1; i < argc; i++) {
+ if (strstr(argv[i], "ansi") || strstr(argv[i], "ANSI")) {
+ version = 1;
+ } else if (strstr(argv[i], "unicode") || strstr(argv[i], "UNICODE")) {
+ version = 2;
+ } else if (strstr(argv[i], "clean") || strstr(argv[i], "CLEAN")) {
+ test_num = -1;
+ } else if (strstr(argv[i], "verbose") || strstr(argv[i], "VERBOSE")) {
+ verbose_flagged = 1;
+ } else if (strstr(argv[i], "status") || strstr(argv[i], "STATUS")) {
+ status_flagged = 1;
+ } else {
+ test_num = atoi(argv[1]);
+ //if (test_num < 0
+ }
+ }
+ for (i = test_num; i <= test_num; i++) {
+ if (!test_num) {
+ test_num = 4;
+ i = 1;
+ }
+ switch (version) {
+ case 1:
+ result = run_ansi_tests(i);
+ break;
+ case 2:
+ result = run_unicode_tests(i);
+ break;
+ default:
+ result = run_ansi_tests(i);
+ result = run_unicode_tests(i);
+ break;
+ }
+ }
+ printf("finished\n");
+ return result;
+}
+
+#ifndef __GNUC__
+
+char* args[] = { "fileio.exe", "0", "unicode", "verbose"};
+
+int __cdecl mainCRTStartup(void)
+{
+ main(2, args);
+ return 0;
+}
+
+#endif /*__GNUC__*/
--- /dev/null
+/*
+ * ReactOS test program -
+ *
+ * main.h
+ *
+ * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MAIN_H__
+#define __MAIN_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+int app_main(int argc, char* argv[]);
+DWORD GetInput(char* Buffer, int buflen);
+
+int test_ansi_files(int test_num);
+int test_unicode_files(int test_num);
+
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // __MAIN_H__
--- /dev/null
+/*
+ * ReactOS test program -
+ *
+ * wfileio.c
+ *
+ * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define UNICODE
+#define _UNICODE
+#include "_tfileio.c"
+
+
+int run_unicode_tests(int test_num)
+{
+ return test_files(test_num, "UNICODE");
+}
--- /dev/null
+#include <conio.h>
+#include <io.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+/** DEFINES *******************************************************************/
+
+#define PATCH_BUFFER_SIZE 4096 /* Maximum size of a patch */
+#define PATCH_BUFFER_MAGIC "\xde\xad\xbe\xef MaGiC MaRk "
+#define SIZEOF_PATCH_BUFFER_MAGIC (sizeof (PATCH_BUFFER_MAGIC) - 1)
+
+/** TYPES *********************************************************************/
+
+typedef struct _PatchedByte
+{
+ int offset; /*!< File offset of the patched byte. */
+ unsigned char expected; /*!< Expected (original) value of the byte. */
+ unsigned char patched; /*!< Patched (new) value for the byte. */
+} PatchedByte;
+
+typedef struct _PatchedFile
+{
+ const char *name; /*!< Name of the file to be patched. */
+ int fileSize; /*!< Size of the file in bytes. */
+ int patchCount; /*!< Number of patches for the file. */
+ PatchedByte *patches; /*!< Patches for the file. */
+} PatchedFile;
+
+typedef struct _Patch
+{
+ const char *name; /*!< Name of the patch. */
+ int fileCount; /*!< Number of files in the patch. */
+ PatchedFile *files; /*!< Files for the patch. */
+} Patch;
+
+/** FUNCTION PROTOTYPES *******************************************************/
+
+static void printUsage();
+
+/** GLOBALS *******************************************************************/
+
+static Patch m_patch = { NULL, 0, NULL };
+static int m_argc = 0;
+static char **m_argv = NULL;
+
+/* patch buffer where we put the patch info into */
+static unsigned char m_patchBuffer[SIZEOF_PATCH_BUFFER_MAGIC + PATCH_BUFFER_SIZE] =
+ PATCH_BUFFER_MAGIC;
+
+/** HELPER FUNCTIONS **********************************************************/
+
+static void *
+loadFile(const char *fileName, int *fileSize_)
+{
+ FILE *f;
+ struct stat sb;
+ int fileSize;
+ void *p;
+
+ /* Open the file */
+ f = fopen(fileName, "rb");
+ if (f == NULL)
+ {
+ printf("Couldn't open file %s for reading!\n", fileName);
+ return NULL;
+ }
+
+ /* Get file size */
+ if (fstat(fileno(f), &sb) < 0)
+ {
+ fclose(f);
+ printf("Couldn't get size of file %s!\n", fileName);
+ return NULL;
+ }
+ fileSize = sb.st_size;
+
+ /* Load file */
+ p = malloc(fileSize);
+ if (p == NULL)
+ {
+ fclose(f);
+ printf("Couldn't allocate %d bytes for file %s!\n", fileSize, fileName);
+ return NULL;
+ }
+
+ if (fread(p, fileSize, 1, f) != 1)
+ {
+ fclose(f);
+ free(p);
+ printf("Couldn't read file %s into memory!\n", fileName);
+ return NULL;
+ }
+
+ /* Close file */
+ fclose(f);
+
+ *fileSize_ = fileSize;
+ return p;
+}
+
+
+static int
+saveFile(const char *fileName, void *file, int fileSize)
+{
+ FILE *f;
+
+ /* Open the file */
+ f = fopen(fileName, "wb");
+ if (f == NULL)
+ {
+ printf("Couldn't open file %s for writing!\n", fileName);
+ return -1;
+ }
+
+ /* Write file */
+ if (fwrite(file, fileSize, 1, f) != 1)
+ {
+ fclose(f);
+ printf("Couldn't write file %s!\n", fileName);
+ return -1;
+ }
+
+ /* Close file */
+ fclose(f);
+ return 0;
+}
+
+
+static int
+compareFiles(
+ PatchedFile *patchedFile,
+ const char *originalFileName)
+{
+ const char *patchedFileName = patchedFile->name;
+ unsigned char *origChunk, *patchedChunk;
+ int origSize, patchedSize, i, patchCount;
+ PatchedByte *patches = NULL;
+ int patchesArrayCount = 0;
+
+ /* Load both files */
+ origChunk = loadFile(originalFileName, &origSize);
+ if (origChunk == NULL)
+ return -1;
+ patchedChunk = loadFile(patchedFileName, &patchedSize);
+ if (patchedChunk == NULL)
+ {
+ free(origChunk);
+ return -1;
+ }
+ if (origSize != patchedSize)
+ {
+ free(origChunk);
+ free(patchedChunk);
+ printf("File size of %s and %s differs (%d != %d)\n",
+ originalFileName, patchedFileName,
+ origSize, patchedSize);
+ return -1;
+ }
+
+ /* Compare the files and record any differences */
+ printf("Comparing %s to %s", originalFileName, patchedFileName);
+ for (i = 0, patchCount = 0; i < origSize; i++)
+ {
+ if (origChunk[i] != patchedChunk[i])
+ {
+ patchCount++;
+
+ /* Resize patches array if needed */
+ if (patchesArrayCount < patchCount)
+ {
+ PatchedByte *newPatches;
+ newPatches = realloc(patches, patchCount * sizeof (PatchedByte));
+ if (newPatches == NULL)
+ {
+ if (patches != NULL)
+ free(patches);
+ free(origChunk);
+ free(patchedChunk);
+ printf("\nOut of memory (tried to allocated %d bytes)\n",
+ patchCount * sizeof (PatchedByte));
+ return -1;
+ }
+ patches = newPatches;
+ }
+
+ /* Fill in patch info */
+ patches[patchCount - 1].offset = i;
+ patches[patchCount - 1].expected = origChunk[i];
+ patches[patchCount - 1].patched = patchedChunk[i];
+ }
+ if ((i % (origSize / 40)) == 0)
+ printf(".");
+ }
+ printf(" %d changed bytes found.\n", patchCount);
+
+ /* Unload the files */
+ free(origChunk);
+ free(patchedChunk);
+
+ /* Save patch info */
+ patchedFile->fileSize = patchedSize;
+ patchedFile->patchCount = patchCount;
+ patchedFile->patches = patches;
+
+ return 0;
+}
+
+
+static int
+outputPatch(const char *outputFileName)
+{
+ unsigned char *patchExe, *patchBuffer;
+ int i, size, patchExeSize, patchSize, stringSize, stringOffset, patchOffset;
+ Patch *patch;
+ PatchedFile *files;
+
+ printf("Putting patch into %s...\n", outputFileName);
+
+ /* Calculate size of the patch */
+ patchSize = sizeof (Patch) + sizeof (PatchedFile) * m_patch.fileCount;
+ stringSize = strlen(m_patch.name) + 1;
+ for (i = 0; i < m_patch.fileCount; i++)
+ {
+ stringSize += strlen(m_patch.files[i].name) + 1;
+ patchSize += sizeof (PatchedByte) * m_patch.files[i].patchCount;
+ }
+ if ((stringSize + patchSize) > PATCH_BUFFER_SIZE)
+ {
+ printf("Patch is too big - %d bytes maximum, %d bytes needed\n",
+ PATCH_BUFFER_SIZE, stringSize + patchSize);
+ return -1;
+ }
+
+ /* Load patch.exe file into memory... */
+ patchExe = loadFile(m_argv[0], &patchExeSize);
+ if (patchExe == NULL)
+ {
+ return -1;
+ }
+
+ /* Try to find the magic mark for the patch buffer */
+ for (i = 0; i < (patchExeSize - SIZEOF_PATCH_BUFFER_MAGIC); i++)
+ {
+ if (memcmp(patchExe + i, m_patchBuffer, SIZEOF_PATCH_BUFFER_MAGIC) == 0)
+ {
+ patchBuffer = patchExe + i + SIZEOF_PATCH_BUFFER_MAGIC;
+
+ break;
+ }
+ }
+ if (!(i < (patchExeSize - SIZEOF_PATCH_BUFFER_MAGIC)))
+ {
+ free(patchExe);
+ printf("Couldn't find patch buffer magic in file %s - this shouldn't happen!!!\n", m_argv[0]);
+ return -1;
+ }
+
+ /* Pack patch together and replace string pointers by offsets */
+ patch = (Patch *)patchBuffer;
+ files = (PatchedFile *)(patchBuffer + sizeof (Patch));
+ patchOffset = sizeof (Patch) + sizeof (PatchedFile) * m_patch.fileCount;
+ stringOffset = patchSize;
+
+ patch->fileCount = m_patch.fileCount;
+ patch->files = (PatchedFile *)sizeof (Patch);
+
+ patch->name = (const char *)stringOffset;
+ strcpy(patchBuffer + stringOffset, m_patch.name);
+ stringOffset += strlen(m_patch.name) + 1;
+
+ for (i = 0; i < m_patch.fileCount; i++)
+ {
+ files[i].fileSize = m_patch.files[i].fileSize;
+ files[i].patchCount = m_patch.files[i].patchCount;
+
+ files[i].name = (const char *)stringOffset;
+ strcpy(patchBuffer + stringOffset, m_patch.files[i].name);
+ stringOffset += strlen(m_patch.files[i].name) + 1;
+
+ size = files[i].patchCount * sizeof (PatchedByte);
+ files[i].patches = (PatchedByte *)patchOffset;
+ memcpy(patchBuffer + patchOffset, m_patch.files[i].patches, size);
+ patchOffset += size;
+ }
+ size = patchSize + stringSize;
+ memset(patchBuffer + size, 0, PATCH_BUFFER_SIZE - size);
+
+ /* Save file */
+ if (saveFile(outputFileName, patchExe, patchExeSize) < 0)
+ {
+ free(patchExe);
+ return -1;
+ }
+ free(patchExe);
+
+ printf("Patch saved!\n");
+ return 0;
+}
+
+
+static int
+loadPatch()
+{
+ char *p;
+ Patch *patch;
+ int i;
+
+ p = m_patchBuffer + SIZEOF_PATCH_BUFFER_MAGIC;
+ patch = (Patch *)p;
+
+ if (patch->name == NULL)
+ {
+ return -1;
+ }
+
+ m_patch.name = p + (int)patch->name;
+ m_patch.fileCount = patch->fileCount;
+ m_patch.files = (PatchedFile *)(p + (int)patch->files);
+
+ for (i = 0; i < m_patch.fileCount; i++)
+ {
+ m_patch.files[i].name = p + (int)m_patch.files[i].name;
+ m_patch.files[i].patches = (PatchedByte *)(p + (int)m_patch.files[i].patches);
+ }
+
+ printf("Patch %s loaded...\n", m_patch.name);
+ return 0;
+}
+
+
+/** MAIN FUNCTIONS ************************************************************/
+
+static int
+createPatch()
+{
+ int i, status;
+ const char *outputFileName;
+
+ /* Check argument count */
+ if (m_argc < 6 || (m_argc % 2) != 0)
+ {
+ printUsage();
+ return -1;
+ }
+
+ outputFileName = m_argv[3];
+ m_patch.name = m_argv[2];
+
+ /* Allocate PatchedFiles array */
+ m_patch.fileCount = (m_argc - 4) / 2;
+ m_patch.files = malloc(m_patch.fileCount * sizeof (PatchedFile));
+ if (m_patch.files == NULL)
+ {
+ printf("Out of memory!\n");
+ return -1;
+ }
+ memset(m_patch.files, 0, m_patch.fileCount * sizeof (PatchedFile));
+
+ /* Compare original to patched files and fill m_patch.files array */
+ for (i = 0; i < m_patch.fileCount; i++)
+ {
+ m_patch.files[i].name = m_argv[4 + (i * 2) + 1];
+ status = compareFiles(m_patch.files + i, m_argv[4 + (i * 2) + 0]);
+ if (status < 0)
+ {
+ for (i = 0; i < m_patch.fileCount; i++)
+ {
+ if (m_patch.files[i].patches != NULL)
+ free(m_patch.files[i].patches);
+ }
+ free(m_patch.files);
+ m_patch.files = NULL;
+ m_patch.fileCount = 0;
+ return status;
+ }
+ }
+
+ /* Output patch */
+ return outputPatch(outputFileName);
+}
+
+
+static int
+applyPatch()
+{
+ int c, i, j, fileSize, makeBackup;
+ unsigned char *file;
+ char *p;
+ const char *fileName;
+ char buffer[MAX_PATH];
+
+
+ if (m_argc > 1 && strcmp(m_argv[1], "-d") != 0)
+ {
+ printUsage();
+ return -1;
+ }
+
+ /* Load patch */
+ if (loadPatch() < 0)
+ {
+ printf("This executable doesn't contain a patch, use -c to create one.\n");
+ return -1;
+ }
+
+ if (m_argc > 1)
+ {
+ /* Dump patch */
+ printf("Patch name: %s\n", m_patch.name);
+ printf("File count: %d\n", m_patch.fileCount);
+ for (i = 0; i < m_patch.fileCount; i++)
+ {
+ printf("----------------------\n"
+ "File name: %s\n"
+ "File size: %d bytes\n",
+ m_patch.files[i].name, m_patch.files[i].fileSize);
+ printf("Patch count: %d\n", m_patch.files[i].patchCount);
+ for (j = 0; j < m_patch.files[i].patchCount; j++)
+ {
+ printf(" Offset 0x%x 0x%02x -> 0x%02x\n",
+ m_patch.files[i].patches[j].offset,
+ m_patch.files[i].patches[j].expected,
+ m_patch.files[i].patches[j].patched);
+ }
+ }
+ }
+ else
+ {
+ /* Apply patch */
+ printf("Applying patch...\n");
+ for (i = 0; i < m_patch.fileCount; i++)
+ {
+ /* Load original file */
+ fileName = m_patch.files[i].name;
+applyPatch_retry_file:
+ file = loadFile(fileName, &fileSize);
+ if (file == NULL)
+ {
+ printf("File %s not found! ", fileName);
+applyPatch_file_open_error:
+ printf("(S)kip, (R)etry, (A)bort, (M)anually enter filename");
+ do
+ {
+ c = getch();
+ }
+ while (c != 's' && c != 'r' && c != 'a' && c != 'm');
+ printf("\n");
+ if (c == 's')
+ {
+ continue;
+ }
+ else if (c == 'r')
+ {
+ goto applyPatch_retry_file;
+ }
+ else if (c == 'a')
+ {
+ return 0;
+ }
+ else if (c == 'm')
+ {
+ if (fgets(buffer, sizeof (buffer), stdin) == NULL)
+ {
+ printf("fgets() failed!\n");
+ return -1;
+ }
+ p = strchr(buffer, '\r');
+ if (p != NULL)
+ *p = '\0';
+ p = strchr(buffer, '\n');
+ if (p != NULL)
+ *p = '\0';
+
+ fileName = buffer;
+ goto applyPatch_retry_file;
+ }
+ }
+
+ /* Check file size */
+ if (fileSize != m_patch.files[i].fileSize)
+ {
+ free(file);
+ printf("File %s has unexpected filesize of %d bytes (%d bytes expected)\n",
+ fileName, fileSize, m_patch.files[i].fileSize);
+ if (fileName != m_patch.files[i].name) /* manually entered filename */
+ {
+ goto applyPatch_file_open_error;
+ }
+ return -1;
+ }
+
+ /* Ask for backup */
+ printf("Do you want to make a backup of %s? (Y)es, (N)o, (A)bort", fileName);
+ do
+ {
+ c = getch();
+ }
+ while (c != 'y' && c != 'n' && c != 'a');
+ printf("\n");
+ if (c == 'y')
+ {
+ char buffer[MAX_PATH];
+ snprintf(buffer, MAX_PATH, "%s.bak", fileName);
+ buffer[MAX_PATH-1] = '\0';
+ makeBackup = 1;
+ if (access(buffer, 0) >= 0) /* file exists */
+ {
+ printf("File %s already exists, overwrite? (Y)es, (N)o, (A)bort", buffer);
+ do
+ {
+ c = getch();
+ }
+ while (c != 'y' && c != 'n' && c != 'a');
+ printf("\n");
+ if (c == 'n')
+ makeBackup = 0;
+ else if (c == 'a')
+ {
+ free(file);
+ return 0;
+ }
+ }
+ if (makeBackup && saveFile(buffer, file, fileSize) < 0)
+ {
+ free(file);
+ return -1;
+ }
+ }
+ else if (c == 'a')
+ {
+ free(file);
+ return 0;
+ }
+
+ /* Patch file */
+ for (j = 0; j < m_patch.files[i].patchCount; j++)
+ {
+ int offset = m_patch.files[i].patches[j].offset;
+ if (file[offset] != m_patch.files[i].patches[j].expected)
+ {
+ printf("Unexpected value in file %s at offset 0x%x: expected = 0x%02x, found = 0x%02x\n",
+ fileName, offset, m_patch.files[i].patches[j].expected, file[offset]);
+ free(file);
+ return -1;
+ }
+ file[offset] = m_patch.files[i].patches[j].patched;
+ }
+
+ /* Save file */
+ if (saveFile(fileName, file, fileSize) < 0)
+ {
+ free(file);
+ return -1;
+ }
+ free(file);
+ }
+
+ printf("Patch applied sucessfully!\n");
+ }
+
+ return 0;
+}
+
+
+static void
+printUsage()
+{
+ printf("Usage:\n"
+ "%s -c - Create patch\n"
+ "%s -d - Dump patch\n"
+ "%s - Apply patch\n"
+ "\n"
+ "A patch can be created like this:\n"
+ "%s -c \"patch name\" output.exe file1.orig file1.patched[ file2.orig file2.patched[ ...]]\n",
+ m_argv[0], m_argv[0], m_argv[0], m_argv[0]);
+}
+
+
+int
+main(
+ int argc,
+ char *argv[])
+{
+ m_argc = argc;
+ m_argv = argv;
+
+ if (argc >= 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0))
+ {
+ printUsage();
+ return 0;
+ }
+ else if (argc >= 2 && argv[1][0] == '-')
+ {
+ if (strcmp(argv[1], "-c") == 0)
+ {
+ return createPatch();
+ }
+ else if (strcmp(argv[1], "-d") == 0)
+ {
+ return applyPatch();
+ }
+ else
+ {
+ printf("Unknown option: %s\n"
+ "Use -h for help.\n",
+ argv[1]);
+ return -1;
+ }
+ }
+
+ return applyPatch();
+}
+
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(int argc, char* argv[])
+{
+ int i;
+ FILE* in;
+ char ch;
+
+ for (i=1; i<argc; i++)
+ {
+ in = fopen(argv[i],"r");
+ if (in == NULL)
+ {
+ printf("Failed to open file %s\n", argv[i]);
+ return(0);
+ }
+
+ while ((ch = fgetc(in)) != EOF)
+ {
+ putchar(ch);
+ }
+ fclose(in);
+ }
+ return 0;
+}
--- /dev/null
+<group>
+<directory name="net">
+ <xi:include href="net/directory.xml" />
+</directory>
+<directory name="getfirefox">
+ <xi:include href="getfirefox/getfirefox.xml" />
+</directory>
+<directory name="shutdown">
+ <xi:include href="shutdown/shutdown.xml" />
+</directory>
+<directory name="ps">
+ <xi:include href="ps/ps.xml" />
+</directory>
+<directory name="rosperf">
+ <xi:include href="rosperf/rosperf.xml" />
+</directory>
+</group>
--- /dev/null
+/*
+ * Load a device driver
+ */
+#include <windows.h>
+#include <ntos/zw.h>
+
+int
+main(int argc, char *argv[])
+{
+ NTSTATUS Status;
+ UNICODE_STRING ServiceName;
+
+ if (argc != 2)
+ {
+ printf("Usage: load <ServiceName>\n");
+ return 0;
+ }
+ ServiceName.Length = (strlen(argv[1]) + 52) * sizeof(WCHAR);
+ ServiceName.Buffer = (LPWSTR)malloc(ServiceName.Length + sizeof(UNICODE_NULL));
+ wsprintf(ServiceName.Buffer,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\%S",
+ argv[1]);
+ wprintf(L"%s %d %d\n", ServiceName.Buffer, ServiceName.Length, wcslen(ServiceName.Buffer));
+ Status = NtLoadDriver(&ServiceName);
+ free(ServiceName.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ printf("Failed: %X\n", Status);
+ return 1;
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * Unload a device driver
+ */
+#include <windows.h>
+#include <ntos/zw.h>
+
+int
+main(int argc, char *argv[])
+{
+ NTSTATUS Status;
+ UNICODE_STRING ServiceName;
+
+ if (argc != 2)
+ {
+ printf("Usage: unload <ServiceName>\n");
+ return 0;
+ }
+ ServiceName.Length = (strlen(argv[1]) + 52) * sizeof(WCHAR);
+ ServiceName.Buffer = (LPWSTR)malloc(ServiceName.Length + sizeof(UNICODE_NULL));
+ wsprintf(ServiceName.Buffer,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\%S",
+ argv[1]);
+ wprintf(L"%s %d %d\n", ServiceName.Buffer, ServiceName.Length, wcslen(ServiceName.Buffer));
+ Status = NtUnloadDriver(&ServiceName);
+ free(ServiceName.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ printf("Failed: %X\n", Status);
+ return 1;
+ }
+ return 0;
+}
--- /dev/null
+/*
+ *
+ * dumprecbin - dumps a recycle bin database
+ *
+ * Copyright (c) 2005 by Thomas Weidenmueller <w3seek@reactos.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * TODO: - Support for Vista recycle bins (read the DeleteInfo NTFS streams, also NT 5.x)
+ * - Support for INFO databases (win95)
+ */
+#include <windows.h>
+#include <winternl.h>
+#include <sddl.h>
+#include <ntsecapi.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <tchar.h>
+
+#ifndef NT_SUCCESS
+#define NT_SUCCESS(status) ((LONG)(status) >= 0)
+#endif
+
+typedef struct _RECYCLE_BIN
+{
+ struct _RECYCLE_BIN *Next;
+ PSID Sid;
+ WCHAR User[255];
+ WCHAR Path[MAX_PATH + 1];
+} RECYCLE_BIN, *PRECYCLE_BIN;
+
+typedef enum
+{
+ ivUnknown = 0,
+ ivINFO2
+} INFO_VERSION, *PINFO_VERSION;
+
+typedef struct _INFO2_HEADER
+{
+ DWORD Version;
+ DWORD Zero1;
+ DWORD Zero2;
+ DWORD RecordSize;
+} INFO2_HEADER, *PINFO2_HEADER;
+
+typedef struct _INFO2_RECORD
+{
+ DWORD Unknown;
+ CHAR AnsiFileName[MAX_PATH];
+ DWORD RecordNumber;
+ DWORD DriveLetter;
+ FILETIME DeletionTime;
+ DWORD DeletedPhysicalSize;
+ WCHAR FileName[MAX_PATH - 2];
+} INFO2_RECORD, *PINFO2_RECORD;
+
+static HANDLE
+OpenAndMapInfoDatabase(IN LPTSTR szFileName,
+ OUT PVOID *MappingBasePtr,
+ OUT PLARGE_INTEGER FileSize)
+{
+ HANDLE hFile, hMapping = INVALID_HANDLE_VALUE;
+
+ hFile = CreateFile(szFileName,
+ FILE_READ_DATA,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM,
+ NULL);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ if (GetFileSizeEx(hFile,
+ FileSize) &&
+ FileSize->QuadPart >= 0xF)
+ {
+ hMapping = CreateFileMapping(hFile,
+ NULL,
+ PAGE_READONLY,
+ 0,
+ 0,
+ NULL);
+ if (hMapping == NULL ||
+ !(*MappingBasePtr = MapViewOfFile(hMapping,
+ FILE_MAP_READ,
+ 0,
+ 0,
+ 0)))
+ {
+ if (hMapping != NULL)
+ {
+ CloseHandle(hMapping);
+ }
+ hMapping = INVALID_HANDLE_VALUE;
+ }
+ }
+ CloseHandle(hFile);
+ }
+
+ return hMapping;
+}
+
+static VOID
+UnmapAndCloseDatabase(IN HANDLE hMapping,
+ IN PVOID MappingBasePtr)
+{
+ UnmapViewOfFile(MappingBasePtr);
+ CloseHandle(hMapping);
+}
+
+static INFO_VERSION
+DetectDatabaseVersion(PVOID Header)
+{
+ PINFO2_HEADER Info2 = (PINFO2_HEADER)Header;
+ INFO_VERSION Version = ivUnknown;
+
+ if (Info2->Version == 5 &&
+ Info2->Zero1 == 0 &&
+ Info2->Zero2 == 0 &&
+ Info2->RecordSize == 0x320)
+ {
+ Version = ivINFO2;
+ }
+
+ return Version;
+}
+
+static BOOL
+IsValidRecycleBin(IN LPTSTR szPath)
+{
+ TCHAR szFile[MAX_PATH + 1];
+ TCHAR szClsId[48];
+ INFO_VERSION DbVersion = ivUnknown;
+
+ _stprintf(szFile,
+ _T("%s\\desktop.ini"),
+ szPath);
+
+ /* check if directory contains a valid desktop.ini for the recycle bin */
+ if (GetPrivateProfileString(TEXT(".ShellClassInfo"),
+ TEXT("CLSID"),
+ NULL,
+ szClsId,
+ sizeof(szClsId) / sizeof(szClsId[0]),
+ szFile) &&
+ !_tcsicmp(_T("{645FF040-5081-101B-9F08-00AA002F954E}"),
+ szClsId))
+ {
+ HANDLE hDb;
+ LARGE_INTEGER FileSize;
+ PVOID pDbBase = NULL;
+
+ /* open the database and check the signature */
+ _stprintf(szFile,
+ _T("%s\\INFO2"),
+ szPath);
+ hDb = OpenAndMapInfoDatabase(szFile,
+ &pDbBase,
+ &FileSize);
+ if (hDb != INVALID_HANDLE_VALUE)
+ {
+ DbVersion = DetectDatabaseVersion(pDbBase);
+ UnmapAndCloseDatabase(hDb,
+ pDbBase);
+ }
+ }
+
+ return DbVersion != ivUnknown;
+}
+
+static BOOL
+OpenLocalLSAPolicyHandle(IN ACCESS_MASK DesiredAccess,
+ OUT PLSA_HANDLE PolicyHandle)
+{
+ LSA_OBJECT_ATTRIBUTES LsaObjectAttributes = {0};
+ NTSTATUS Status;
+
+ Status = LsaOpenPolicy(NULL,
+ &LsaObjectAttributes,
+ DesiredAccess,
+ PolicyHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(LsaNtStatusToWinError(Status));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL
+ConvertSIDToAccountName(IN PSID Sid,
+ OUT LPWSTR User)
+{
+ DWORD AccountNameLen = 0;
+ DWORD DomainNameLen = 0;
+ SID_NAME_USE NameUse;
+ DWORD Error = ERROR_SUCCESS;
+ LPWSTR AccountName, DomainName;
+ BOOL Ret = FALSE;
+
+ if (!LookupAccountSidW(NULL,
+ Sid,
+ NULL,
+ &AccountNameLen,
+ NULL,
+ &DomainNameLen,
+ &NameUse))
+ {
+ Error = GetLastError();
+ if (Error == ERROR_NONE_MAPPED ||
+ Error != ERROR_INSUFFICIENT_BUFFER)
+ {
+ /* some unexpected error occured! */
+ goto ConvertSID;
+ }
+ }
+
+ AccountName = (LPWSTR)HeapAlloc(GetProcessHeap(),
+ 0,
+ (AccountNameLen + DomainNameLen) * sizeof(WCHAR));
+ if (AccountName != NULL)
+ {
+ LSA_HANDLE PolicyHandle;
+ DomainName = AccountName + AccountNameLen;
+
+ if (!LookupAccountSidW(NULL,
+ Sid,
+ AccountName,
+ &AccountNameLen,
+ DomainName,
+ &DomainNameLen,
+ &NameUse))
+ {
+ goto BailFreeAccountName;
+ }
+
+ wcscpy(User,
+ AccountName);
+ Ret = TRUE;
+
+ if (OpenLocalLSAPolicyHandle(POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION,
+ &PolicyHandle))
+ {
+ PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain;
+ PLSA_TRANSLATED_NAME Names;
+ PLSA_TRUST_INFORMATION Domain;
+ PLSA_UNICODE_STRING DomainName;
+ PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo = NULL;
+ NTSTATUS Status;
+
+ Status = LsaLookupSids(PolicyHandle,
+ 1,
+ &Sid,
+ &ReferencedDomain,
+ &Names);
+ if (NT_SUCCESS(Status))
+ {
+ if (ReferencedDomain != NULL &&
+ Names->DomainIndex >= 0)
+ {
+ Domain = &ReferencedDomain->Domains[Names->DomainIndex];
+ DomainName = &Domain->Name;
+ }
+ else
+ {
+ Domain = NULL;
+ DomainName = NULL;
+ }
+
+ switch (Names->Use)
+ {
+ case SidTypeAlias:
+ if (Domain != NULL)
+ {
+ /* query the domain name for BUILTIN accounts */
+ Status = LsaQueryInformationPolicy(PolicyHandle,
+ PolicyAccountDomainInformation,
+ (PVOID*)&PolicyAccountDomainInfo);
+ if (NT_SUCCESS(Status))
+ {
+ DomainName = &PolicyAccountDomainInfo->DomainName;
+ }
+ }
+ /* fall through */
+
+ case SidTypeUser:
+ {
+ if (Domain != NULL)
+ {
+ WCHAR *s;
+
+ /* NOTE: LSA_UNICODE_STRINGs are not always NULL-terminated! */
+
+ wcscpy(User,
+ AccountName);
+ wcscat(User,
+ L" (");
+ s = User + wcslen(User);
+ CopyMemory(s,
+ DomainName->Buffer,
+ DomainName->Length);
+ s += DomainName->Length / sizeof(WCHAR);
+ *(s++) = L'\\';
+ CopyMemory(s,
+ Names->Name.Buffer,
+ Names->Name.Length);
+ s += Names->Name.Length / sizeof(WCHAR);
+ *(s++) = L')';
+ *s = L'\0';
+ }
+ break;
+ }
+
+ case SidTypeWellKnownGroup:
+ {
+ break;
+ }
+
+ default:
+ {
+ _ftprintf(stderr,
+ _T("Unhandled SID type: 0x%x\n"),
+ Names->Use);
+ break;
+ }
+ }
+
+ if (PolicyAccountDomainInfo != NULL)
+ {
+ LsaFreeMemory(PolicyAccountDomainInfo);
+ }
+
+ LsaFreeMemory(ReferencedDomain);
+ LsaFreeMemory(Names);
+ }
+
+ LsaClose(PolicyHandle);
+
+ if (!NT_SUCCESS(Status))
+ {
+ Ret = FALSE;
+ goto BailFreeAccountName;
+ }
+ }
+ else
+ {
+BailFreeAccountName:
+ HeapFree(GetProcessHeap(),
+ 0,
+ AccountName);
+ goto ConvertSID;
+ }
+ }
+
+ConvertSID:
+ if (!Ret)
+ {
+ LPWSTR StrSid;
+ Ret = ConvertSidToStringSidW(Sid,
+ &StrSid);
+ if (Ret)
+ {
+ wcscpy(User,
+ StrSid);
+ LocalFree((HLOCAL)StrSid);
+ }
+ }
+
+ return Ret;
+}
+
+static VOID
+FreeRecycleBinsList(IN OUT PRECYCLE_BIN *RecycleBinsListHead)
+{
+ PRECYCLE_BIN CurrentBin, NextBin;
+
+ CurrentBin = *RecycleBinsListHead;
+ while (CurrentBin != NULL)
+ {
+ NextBin = CurrentBin->Next;
+ LocalFree((HLOCAL)CurrentBin->Sid);
+ HeapFree(GetProcessHeap(),
+ 0,
+ CurrentBin);
+ CurrentBin = NextBin;
+ }
+
+ *RecycleBinsListHead = NULL;
+}
+
+static BOOL
+LocateRecycleBins(IN LPWSTR szDrive,
+ OUT PRECYCLE_BIN *RecycleBinsListHead)
+{
+ TCHAR szRecBinPath[MAX_PATH + 1];
+ HANDLE FindResult;
+ WIN32_FIND_DATA FindData;
+ PRECYCLE_BIN NewBin;
+ BOOL Ret = FALSE;
+
+ FreeRecycleBinsList(RecycleBinsListHead);
+
+ /*
+ * search for recycle bins on volumes that support file security (NTFS)
+ */
+ _stprintf(szRecBinPath,
+ _T("%lS\\RECYCLER\\*"),
+ szDrive);
+ FindResult = FindFirstFile(szRecBinPath,
+ &FindData);
+ if (FindResult != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY &&
+ _tcscmp(FindData.cFileName,
+ _T("..")) &&
+ _tcscmp(FindData.cFileName,
+ _T(".")))
+ {
+ PSID Sid;
+
+ if (ConvertStringSidToSid(FindData.cFileName,
+ &Sid))
+ {
+ _stprintf(szRecBinPath,
+ _T("%s\\RECYCLER\\%s"),
+ szDrive,
+ FindData.cFileName);
+ if (IsValidRecycleBin(szRecBinPath))
+ {
+ NewBin = (PRECYCLE_BIN)HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(RECYCLE_BIN));
+ if (NewBin != NULL)
+ {
+ _tcscpy(NewBin->Path,
+ szRecBinPath);
+
+ /* convert the SID to an account name */
+ ConvertSIDToAccountName(Sid,
+ NewBin->User);
+
+ /* append the recycle bin */
+ *RecycleBinsListHead = NewBin;
+ RecycleBinsListHead = &NewBin->Next;
+
+ Ret = TRUE;
+ }
+ else
+ goto ContinueFreeSid;
+ }
+ else
+ {
+ContinueFreeSid:
+ LocalFree((HLOCAL)Sid);
+ }
+ }
+ }
+ } while (FindNextFile(FindResult,
+ &FindData));
+
+ FindClose(FindResult);
+ }
+
+ /*
+ * search for recycle bins on volumes that don't support file security (FAT)
+ */
+ _stprintf(szRecBinPath,
+ _T("%s\\Recycled"),
+ szDrive);
+ FindResult = FindFirstFile(szRecBinPath,
+ &FindData);
+ if (FindResult != INVALID_HANDLE_VALUE)
+ {
+ if (IsValidRecycleBin(szRecBinPath))
+ {
+ SID_IDENTIFIER_AUTHORITY WorldSia = {SECURITY_WORLD_SID_AUTHORITY};
+ PSID EveryoneSid;
+
+ /* create an Everyone SID */
+ if (AllocateAndInitializeSid(&WorldSia,
+ 1,
+ SECURITY_WORLD_RID,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ &EveryoneSid))
+ {
+ NewBin = (PRECYCLE_BIN)HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(RECYCLE_BIN));
+ if (NewBin != NULL)
+ {
+ _tcscpy(NewBin->Path,
+ szRecBinPath);
+
+ /* convert the SID to an account name */
+ ConvertSIDToAccountName(EveryoneSid,
+ NewBin->User);
+
+ /* append the recycle bin */
+ *RecycleBinsListHead = NewBin;
+ RecycleBinsListHead = &NewBin->Next;
+
+ Ret = TRUE;
+ }
+ else
+ FreeSid(EveryoneSid);
+ }
+ }
+ FindClose(FindResult);
+ }
+
+ return Ret;
+}
+
+static VOID
+DiskFileNameFromRecord(OUT LPTSTR szShortFileName,
+ IN DWORD RecordNumber,
+ IN WCHAR cDriveLetter,
+ IN LPWSTR szFileName)
+{
+ LPWSTR FileExt;
+
+ FileExt = wcsrchr(szFileName,
+ L'.');
+ if (FileExt != NULL)
+ {
+ _stprintf(szShortFileName,
+ _T("D%lC%d%lS"),
+ cDriveLetter,
+ RecordNumber,
+ FileExt);
+ }
+ else
+ {
+ _stprintf(szShortFileName,
+ _T("D%lC%d"),
+ cDriveLetter,
+ RecordNumber);
+ }
+}
+
+static BOOL
+DumpRecycleBin(IN PRECYCLE_BIN RecycleBin)
+{
+ WCHAR szFile[MAX_PATH + 1];
+ HANDLE hDb;
+ LARGE_INTEGER FileSize;
+ PVOID pDbBase = NULL;
+ INFO_VERSION Version = ivUnknown;
+
+ _tprintf(_T("Dumping recycle bin of \"%lS\":\n"),
+ RecycleBin->User);
+ _tprintf(_T("Directory: %lS\n\n"),
+ RecycleBin->Path);
+
+ _stprintf(szFile,
+ _T("%s\\INFO2"),
+ RecycleBin->Path);
+ hDb = OpenAndMapInfoDatabase(szFile,
+ &pDbBase,
+ &FileSize);
+ if (hDb != INVALID_HANDLE_VALUE)
+ {
+ Version = DetectDatabaseVersion(pDbBase);
+
+ /* dump the INFO2 database */
+ switch (Version)
+ {
+ case ivINFO2:
+ {
+ DWORD nRecords;
+ PINFO2_HEADER Info2Header = (PINFO2_HEADER)pDbBase;
+ PINFO2_RECORD Info2 = (PINFO2_RECORD)(Info2Header + 1);
+ int i = 0;
+
+ nRecords = (FileSize.QuadPart - sizeof(INFO2_HEADER)) / Info2Header->RecordSize;
+
+ while (nRecords != 0)
+ {
+ /* if the first character of the AnsiFileName is zero, the record
+ is considered deleted */
+ if (Info2->AnsiFileName[0] != '\0')
+ {
+ _tprintf(_T(" [%d] Record: #%d \"%lS\"\n"),
+ ++i,
+ Info2->RecordNumber,
+ Info2->FileName);
+
+ DiskFileNameFromRecord(szFile,
+ Info2->RecordNumber,
+ (WCHAR)Info2->DriveLetter + L'a',
+ Info2->FileName);
+ _tprintf(_T(" Name on disk: \"%s\"\n"),
+ szFile);
+ _tprintf(_T(" Deleted size on disk: %d KB\n"),
+ Info2->DeletedPhysicalSize / 1024);
+ }
+ nRecords--;
+ Info2++;
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ UnmapAndCloseDatabase(hDb,
+ pDbBase);
+ }
+
+ return FALSE;
+}
+
+static BOOL
+SelectRecycleBin(IN LPWSTR szDrive)
+{
+ BOOL Ret;
+ PRECYCLE_BIN RecycleBinsList = NULL;
+
+ Ret = LocateRecycleBins(szDrive,
+ &RecycleBinsList);
+ if (Ret)
+ {
+ if (RecycleBinsList->Next != NULL)
+ {
+ PRECYCLE_BIN CurrentBin = RecycleBinsList;
+ int n = 0, i = 0;
+
+ /* if there are multiple recycle bins ask the user which one to dump */
+ _tprintf(_T("There are several recycle bins on this drive. Select one:\n"));
+
+ while (CurrentBin != NULL)
+ {
+ _tprintf(_T(" [%d] %lS\n"),
+ ++i,
+ CurrentBin->User);
+ CurrentBin = CurrentBin->Next;
+ n++;
+ }
+
+ _tprintf(_T("Enter the number: "));
+DisplayPrompt:
+ _tscanf(_T("%d"),
+ &i);
+ if (i > n || i < 1)
+ {
+ _tprintf(_T("Please enter a number between 1 and %d: "),
+ n);
+ goto DisplayPrompt;
+ }
+
+ /* walk to the selected recycle bin */
+ CurrentBin = RecycleBinsList;
+ while (CurrentBin != NULL && i != 1)
+ {
+ CurrentBin = CurrentBin->Next;
+ i--;
+ }
+
+ /* dump it */
+ Ret = DumpRecycleBin(CurrentBin);
+ }
+ else
+ {
+ /* dump the first (and only) recycle bin */
+ Ret = DumpRecycleBin(RecycleBinsList);
+ }
+ }
+ else
+ {
+ _ftprintf(stderr,
+ _T("No recycle bins on this volume!\n"));
+ }
+
+ FreeRecycleBinsList(&RecycleBinsList);
+
+ return Ret;
+}
+
+static VOID
+PrintHelp(VOID)
+{
+ _ftprintf(stderr,
+ _T("Usage: dumprecbin C:\n"));
+}
+
+int
+main(int argc,
+ char *argv[])
+{
+ if (argc != 2 ||
+ strlen(argv[1]) != 2 || argv[1][1] != ':' ||
+ toupper(argv[1][0]) < 'A' || toupper(argv[1][0]) > 'Z')
+ {
+ PrintHelp();
+ return 1;
+ }
+ else
+ {
+ WCHAR szDrive[3];
+ _stprintf(szDrive,
+ _T("%lC:"),
+ argv[1][0]);
+
+ if (!SelectRecycleBin(szDrive))
+ return 1;
+ else
+ return 0;
+ }
+}
+
--- /dev/null
+<module name="dumprecbin" type="win32cui" installbase="bin" installname="dumprecbin.exe">
+ <include base="dumprecbin">.</include>
+ <define name="__USE_W32API" />
+ <define name="UNICODE" />
+ <define name="_UNICODE" />
+ <define name="_WIN32_IE">0x0500</define>
+ <define name="_WIN32_WINNT">0x0600</define>
+ <define name="WINVER">0x0600</define>
+ <library>advapi32</library>
+ <library>kernel32</library>
+ <library>ntdll</library>
+ <file>dumprecbin.c</file>
+</module>
\ No newline at end of file
--- /dev/null
+/*
+ * ReactOS INF Helper
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * PROJECT: INF Helper
+ * FILE: infinst.c
+ * PURPOSE: Pass INF files to setupapi.dll for execution
+ * PROGRAMMER: Michael Biggins
+ * UPDATE HISTORY:
+ * Created 19/09/2004
+ */
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+
+#ifdef UNICODE
+VOID WINAPI InstallHinfSectionW(HWND hwnd, HINSTANCE handle, LPCWSTR cmdline, INT show);
+#define InstallHinfSection InstallHinfSectionW
+#else
+VOID WINAPI InstallHinfSectionA(HWND hwnd, HINSTANCE handle, LPCSTR cmdline, INT show);
+#define InstallHinfSection InstallHinfSectionA
+#endif
+
+#define FILEOPEN_FILTER TEXT("Inf Files (*.inf)\0*.inf\0All Files (*.*)\0*.*\0\0")
+#define FILEOPEN_TITLE TEXT("INF file to process")
+#define FILEOPEN_DEFEXT TEXT(".inf")
+#define INF_COMMAND TEXT("DefaultInstall 128 %s")
+
+int
+_tmain(int argc, TCHAR *argv[])
+{
+ TCHAR infCommand[MAX_PATH + 32];
+
+ if (argc <= 1)
+ {
+ TCHAR FileName[MAX_PATH + 1];
+ OPENFILENAME ofc;
+ int rv;
+
+ ZeroMemory(&ofc, sizeof(ofc));
+ ZeroMemory(FileName, MAX_PATH + 1);
+ ofc.lStructSize = sizeof(ofc);
+ ofc.lpstrFilter = FILEOPEN_FILTER;
+ ofc.nFilterIndex = 1;
+ ofc.lpstrTitle = FILEOPEN_TITLE;
+ ofc.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_PATHMUSTEXIST;
+ ofc.lpstrDefExt = FILEOPEN_DEFEXT;
+ ofc.lpstrFile = FileName;
+ ofc.nMaxFile = sizeof(FileName) / sizeof(TCHAR);
+
+ rv = GetOpenFileName(&ofc);
+
+ if (rv == 0)
+ return 1;
+
+ _stprintf(infCommand, INF_COMMAND, FileName);
+ }
+ else
+ {
+ if (_tcslen(argv[1]) > MAX_PATH)
+ {
+ MessageBox(NULL, TEXT("Command line too long to be a valid file name"), NULL, MB_OK | MB_ICONERROR);
+ return 2; /* User error */
+ }
+ _stprintf(infCommand, INF_COMMAND, argv[1]);
+ }
+
+ InstallHinfSection(NULL, NULL, infCommand, 0);
+
+ return 0;
+}
--- /dev/null
+/* $Id$
+ *
+ * Convert NTSTATUS codes to Win32 error codes: run it
+ * on a NT box AND on a ROS box, then diff the results.
+ *
+ * This utility should help keeping correct how Ros
+ * translates executive's errors codes into Win32 error
+ * codes.
+ *
+ * Usage: nts2w32err [MaxStatusCode] > log.txt
+ *
+ * 2004-01-10 Emanuele Aliberti
+ *
+ */
+#include <windows.h>
+#include <ntddk.h>
+
+#include <stdio.h>
+
+int main (int argc, char * argv [])
+{
+ NTSTATUS Severity = 0;
+ NTSTATUS StatusCode = STATUS_SUCCESS;
+ NTSTATUS Status = STATUS_SUCCESS;
+ DWORD LastError = ERROR_SUCCESS;
+ DWORD Maximum = 0x40000;
+
+ if (2 == argc)
+ {
+ sscanf (argv[1], "%lx", & Maximum);
+ }
+
+ printf ("NT error codes 0x0-0x%lx that get translated *not* to ERROR_MR_MID_NOT_FOUND (317)\n\n", Maximum);
+
+ for ( Severity = 0;
+ Severity < 4;
+ Severity ++)
+ {
+ printf ("--- Severity %ld ---\n", Severity);
+
+ for ( StatusCode = STATUS_SUCCESS;
+ StatusCode <= Maximum ;
+ StatusCode ++)
+ {
+ Status = ((Severity << 30) | StatusCode);
+ LastError = RtlNtStatusToDosError (Status);
+ if (ERROR_MR_MID_NOT_FOUND != LastError)
+ {
+ printf ("0x%08lx => %ldL\n", Status, LastError);
+ }
+ }
+ }
+ return EXIT_SUCCESS;
+}
+/* EOF */
--- /dev/null
+/* $Id$
+ *
+ * DESCRIPTION: Object Manager Simple Explorer
+ * PROGRAMMER: David Welch
+ * REVISIONS
+ * 2000-04-30 (ea)
+ * Added directory enumeration.
+ * (tested under nt4sp4/x86)
+ * 2000-08-11 (ea)
+ * Added symbolic link expansion.
+ * (tested under nt4sp4/x86)
+ * 2001-05-01 (ea)
+ * Fixed entries counter. Added more
+ * error codes check. Removed wprintf,
+ * because it does not work in .17.
+ * 2001-05-02 (ea)
+ * Added -r option.
+ */
+
+#include <ntddk.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define MAX_DIR_ENTRY 256
+
+
+static
+PCHAR
+STDCALL
+RawUszAsz (
+ PWCHAR szU,
+ PCHAR szA
+ )
+{
+ register PCHAR a = szA;
+
+ while (*szU) {*szA++ = (CHAR) (0x00ff & * szU++);}
+ *szA = '\0';
+ return a;
+}
+
+
+static
+PWCHAR
+STDCALL
+RawAszUsz (
+ PCHAR szA,
+ PWCHAR szW
+ )
+{
+ register PWCHAR w = szW;
+
+ while (*szA) {*szW++ = (WCHAR) *szA++;}
+ *szW = L'\0';
+ return w;
+}
+
+
+static
+const char *
+STDCALL
+StatusToName (NTSTATUS Status)
+{
+ static char RawValue [16];
+
+ switch (Status)
+ {
+ case STATUS_BUFFER_TOO_SMALL:
+ return "STATUS_BUFFER_TOO_SMALL";
+ case STATUS_INVALID_PARAMETER:
+ return "STATUS_INVALID_PARAMETER";
+ case STATUS_OBJECT_NAME_INVALID:
+ return "STATUS_OBJECT_NAME_INVALID";
+ case STATUS_OBJECT_NAME_NOT_FOUND:
+ return "STATUS_OBJECT_NAME_NOT_FOUND";
+ case STATUS_OBJECT_PATH_SYNTAX_BAD:
+ return "STATUS_PATH_SYNTAX_BAD";
+ case STATUS_NO_MORE_ENTRIES:
+ return "STATUS_NO_MORE_ENTRIES";
+ case STATUS_MORE_ENTRIES:
+ return "STATUS_MORE_ENTRIES";
+ case STATUS_ACCESS_DENIED:
+ return "STATUS_ACCESS_DENIED";
+ case STATUS_UNSUCCESSFUL:
+ return "STATUS_UNSUCCESSFUL";
+ case STATUS_INVALID_HANDLE:
+ return "STATUS_INVALID_HANDLE";
+ }
+ sprintf (RawValue, "0x%08lx", Status);
+ return (const char *) RawValue;
+}
+
+
+BOOL
+STDCALL
+ExpandSymbolicLink (
+ IN PUNICODE_STRING DirectoryName,
+ IN PUNICODE_STRING SymbolicLinkName,
+ IN OUT PUNICODE_STRING TargetObjectName
+ )
+{
+ NTSTATUS Status;
+ HANDLE hSymbolicLink;
+ OBJECT_ATTRIBUTES oa;
+ UNICODE_STRING Path;
+ WCHAR PathBuffer [MAX_PATH];
+ ULONG DataWritten = 0;
+
+
+ Path.Buffer = PathBuffer;
+ Path.Length = 0;
+ Path.MaximumLength = sizeof PathBuffer;
+
+ RtlCopyUnicodeString (& Path, DirectoryName);
+ if (L'\\' != Path.Buffer [(Path.Length / sizeof Path.Buffer[0]) - 1])
+ {
+ RtlAppendUnicodeToString (& Path, L"\\");
+ }
+ RtlAppendUnicodeStringToString (& Path, SymbolicLinkName);
+
+ oa.Length = sizeof (OBJECT_ATTRIBUTES);
+ oa.ObjectName = & Path;
+ oa.Attributes = 0; /* OBJ_CASE_INSENSITIVE; */
+ oa.RootDirectory = NULL;
+ oa.SecurityDescriptor = NULL;
+ oa.SecurityQualityOfService = NULL;
+
+ Status = NtOpenSymbolicLinkObject(
+ & hSymbolicLink,
+ SYMBOLIC_LINK_QUERY, /* 0x20001 */
+ & oa
+ );
+
+ if (!NT_SUCCESS(Status))
+ {
+ printf (
+ "Failed to open SymbolicLink object (Status: %s)\n",
+ StatusToName (Status)
+ );
+ return FALSE;
+ }
+ TargetObjectName->Length = TargetObjectName->MaximumLength;
+ memset (
+ TargetObjectName->Buffer,
+ 0,
+ TargetObjectName->MaximumLength
+ );
+ Status = NtQuerySymbolicLinkObject(
+ hSymbolicLink,
+ TargetObjectName,
+ & DataWritten
+ );
+ if (!NT_SUCCESS(Status))
+ {
+ printf (
+ "Failed to query SymbolicLink object (Status: %s)\n",
+ StatusToName (Status)
+ );
+ NtClose (hSymbolicLink);
+ return FALSE;
+ }
+ NtClose (hSymbolicLink);
+ return TRUE;
+}
+
+
+BOOL
+STDCALL
+ListDirectory (
+ IN PUNICODE_STRING DirectoryNameW,
+ IN BOOL Recurse
+ )
+{
+ CHAR DirectoryNameA [MAX_PATH];
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ NTSTATUS Status;
+ HANDLE DirectoryHandle;
+ BYTE DirectoryEntry [512];
+ POBJECT_DIRECTORY_INFORMATION pDirectoryEntry = (POBJECT_DIRECTORY_INFORMATION) DirectoryEntry;
+ POBJECT_DIRECTORY_INFORMATION pDirectoryEntries = (POBJECT_DIRECTORY_INFORMATION) DirectoryEntry;
+ ULONG Context = 0;
+ ULONG ReturnLength = 0;
+ ULONG EntryCount = 0;
+
+ /* For expanding symbolic links */
+ WCHAR TargetName [2 * MAX_PATH];
+ UNICODE_STRING TargetObjectName = {
+ sizeof TargetName,
+ sizeof TargetName,
+ TargetName
+ };
+
+ /* Convert to ANSI the directory's name */
+ RawUszAsz (DirectoryNameW->Buffer, DirectoryNameA);
+ /*
+ * Prepare parameters for next call.
+ */
+ InitializeObjectAttributes (
+ & ObjectAttributes,
+ DirectoryNameW,
+ 0,
+ NULL,
+ NULL
+ );
+ /*
+ * Try opening the directory.
+ */
+ Status = NtOpenDirectoryObject (
+ & DirectoryHandle,
+ DIRECTORY_QUERY,
+ & ObjectAttributes
+ );
+ if (!NT_SUCCESS(Status))
+ {
+ printf (
+ "Failed to open directory object \"%s\" (Status: %s)\n",
+ DirectoryNameA,
+ StatusToName (Status)
+ );
+ return (FALSE);
+ }
+ printf ("\n Directory of %s\n\n", DirectoryNameA);
+
+ for(;;)
+ {
+ /*
+ * Enumerate each item in the directory.
+ */
+ Status = NtQueryDirectoryObject (
+ DirectoryHandle,
+ pDirectoryEntries,
+ sizeof DirectoryEntry,
+ FALSE,/* ReturnSingleEntry */
+ FALSE, /* RestartScan */
+ & Context,
+ & ReturnLength
+ );
+ if (!NT_SUCCESS(Status) && Status != STATUS_NO_MORE_ENTRIES)
+ {
+ printf (
+ "Failed to query directory object (Status: %s)\n",
+ StatusToName (Status)
+ );
+ NtClose (DirectoryHandle);
+ return (FALSE);
+ }
+ if (Status == STATUS_NO_MORE_ENTRIES)
+ {
+ break;
+ }
+ pDirectoryEntry = pDirectoryEntries;
+ while (EntryCount < Context)
+ {
+ CHAR ObjectNameA [MAX_PATH];
+ CHAR TypeNameA [MAX_PATH];
+ CHAR TargetNameA [MAX_PATH];
+
+ if (0 == wcscmp (L"SymbolicLink", pDirectoryEntry->ObjectTypeName.Buffer))
+ {
+ if (TRUE == ExpandSymbolicLink (
+ DirectoryNameW,
+ & pDirectoryEntry->ObjectName,
+ & TargetObjectName
+ )
+ )
+ {
+
+ printf (
+ "%-16s %s -> %s\n",
+ RawUszAsz (pDirectoryEntry->ObjectTypeName.Buffer, TypeNameA),
+ RawUszAsz (pDirectoryEntry->ObjectName.Buffer, ObjectNameA),
+ RawUszAsz (TargetObjectName.Buffer, TargetNameA)
+ );
+ }
+ else
+ {
+ printf (
+ "%-16s %s -> (error!)\n",
+ RawUszAsz (pDirectoryEntry->ObjectTypeName.Buffer, TypeNameA),
+ RawUszAsz (pDirectoryEntry->ObjectName.Buffer, ObjectNameA)
+ );
+ }
+ }
+ else
+ {
+ printf (
+ "%-16s %s\n",
+ RawUszAsz (pDirectoryEntry->ObjectTypeName.Buffer, TypeNameA),
+ RawUszAsz (pDirectoryEntry->ObjectName.Buffer, ObjectNameA)
+ );
+ }
+ ++ pDirectoryEntry;
+ ++ EntryCount;
+ }
+ };
+ printf ("\n\t%lu object(s)\n", EntryCount);
+ /*
+ * Free any resource.
+ */
+ NtClose (DirectoryHandle);
+ /*
+ * Recurse into, if required so.
+ */
+ if (FALSE != Recurse)
+ {
+ pDirectoryEntry = (POBJECT_DIRECTORY_INFORMATION) DirectoryEntry;
+ while (0 != pDirectoryEntry->ObjectTypeName.Length)
+ {
+ if (0 == wcscmp (L"Directory", pDirectoryEntry->ObjectTypeName.Buffer))
+ {
+ WCHAR CurrentName [MAX_PATH];
+ UNICODE_STRING CurrentDirectory;
+
+ CurrentName [0] = L'\0';
+ wcscpy (CurrentName, DirectoryNameW->Buffer);
+ if (wcslen (CurrentName) > 1)
+ {
+ wcscat (CurrentName, L"\\");
+ }
+ wcscat (CurrentName, pDirectoryEntry->ObjectName.Buffer);
+ RtlInitUnicodeString (& CurrentDirectory, CurrentName);
+ ListDirectory (& CurrentDirectory, Recurse);
+ }
+ ++ pDirectoryEntry;
+ }
+ }
+ return (TRUE);
+}
+
+
+int main(int argc, char* argv[])
+{
+ WCHAR DirectoryNameW [MAX_PATH];
+ UNICODE_STRING DirectoryName;
+ BOOL Recurse = FALSE;
+
+ /*
+ * Check user arguments.
+ */
+ switch (argc)
+ {
+ case 2:
+ RawAszUsz (argv[1], DirectoryNameW);
+ break;
+ case 3:
+ if (strcmp (argv[1], "-r"))
+ {
+ fprintf (
+ stderr,
+ "%s: unknown option '%s'.\n",
+ argv [0], argv[1]
+ );
+ return EXIT_FAILURE;
+ }
+ RawAszUsz (argv[2], DirectoryNameW);
+ Recurse = TRUE;
+ break;
+ default:
+ fprintf (
+ stderr,
+ "\nUsage: %s [-r] directory\n\n"
+ " -r recurse\n"
+ " directory a directory name in the system namespace\n\n",
+ argv [0]
+ );
+ return EXIT_FAILURE;
+ }
+ /*
+ * List the directory.
+ */
+ RtlInitUnicodeString (& DirectoryName, DirectoryNameW);
+ return (FALSE == ListDirectory (& DirectoryName, Recurse))
+ ? EXIT_FAILURE
+ : EXIT_SUCCESS;
+}
+
+
+/* EOF */
--- /dev/null
+/*
+ * partinfo - partition info program
+ */
+
+#include <windows.h>
+//#include <winioctl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <ntddk.h>
+
+//#define DUMP_DATA
+#define DUMP_SIZE_INFO
+#define UNICODE
+
+#ifdef DUMP_DATA
+void HexDump(char *buffer, ULONG size)
+{
+ ULONG offset = 0;
+ unsigned char *ptr;
+
+ while (offset < (size & ~15))
+ {
+ ptr = (unsigned char*)((ULONG)buffer + offset);
+ printf("%08lx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx-%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx\n",
+ offset,
+ ptr[0],
+ ptr[1],
+ ptr[2],
+ ptr[3],
+ ptr[4],
+ ptr[5],
+ ptr[6],
+ ptr[7],
+ ptr[8],
+ ptr[9],
+ ptr[10],
+ ptr[11],
+ ptr[12],
+ ptr[13],
+ ptr[14],
+ ptr[15]);
+ offset += 16;
+ }
+
+ ptr = (unsigned char*)((ULONG)buffer + offset);
+ printf("%08lx ", offset);
+ while (offset < size)
+ {
+ printf(" %02hx", *ptr);
+ offset++;
+ ptr++;
+ }
+
+ printf("\n\n\n");
+}
+#endif
+
+
+void Usage(void)
+{
+ puts("Usage: partinfo <drive number>");
+}
+
+
+int main (int argc, char *argv[])
+{
+ HANDLE hDisk;
+ DWORD dwRead;
+ DWORD i;
+ char *Buffer;
+ DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
+ DISK_GEOMETRY DiskGeometry;
+ ULONG ulDrive;
+ CHAR DriveName[40];
+ SYSTEM_DEVICE_INFORMATION DeviceInfo;
+ NTSTATUS Status;
+
+ if (argc != 2)
+ {
+ Usage();
+ return(0);
+ }
+
+ ulDrive = strtoul(argv[1], NULL, 10);
+ if (errno != 0)
+ {
+ printf("Error: Malformed drive number\n");
+ return(0);
+ }
+
+ /* Check drive number */
+ Status = NtQuerySystemInformation(SystemDeviceInformation,
+ &DeviceInfo,
+ sizeof(SYSTEM_DEVICE_INFORMATION),
+ &i);
+ if (!NT_SUCCESS(Status))
+ {
+ printf("NtQuerySystemInformation() failed (Status %lx)\n", Status);
+ return(0);
+ }
+
+ if (DeviceInfo.NumberOfDisks == 0)
+ {
+ printf("No disk drive installed!\n");
+ return(0);
+ }
+
+ if (ulDrive >= DeviceInfo.NumberOfDisks)
+ {
+ printf("Invalid disk drive number! Valid drive numbers [0-%lu]\n",
+ DeviceInfo.NumberOfDisks-1);
+ return(0);
+ }
+
+ /* Build full drive name */
+ sprintf(DriveName, "\\\\.\\PHYSICALDRIVE%lu", ulDrive);
+
+ /* Open drive */
+ hDisk = CreateFile(DriveName,
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+ if (hDisk == INVALID_HANDLE_VALUE)
+ {
+ printf("Invalid disk handle!");
+ return 0;
+ }
+
+ /* Get drive geometry */
+ if (!DeviceIoControl(hDisk,
+ IOCTL_DISK_GET_DRIVE_GEOMETRY,
+ NULL,
+ 0,
+ &DiskGeometry,
+ sizeof(DISK_GEOMETRY),
+ &dwRead,
+ NULL))
+ {
+ CloseHandle(hDisk);
+ printf("DeviceIoControl failed! Error: %lu\n",
+ GetLastError());
+ return 0;
+ }
+
+#ifdef DUMP_DATA
+ HexDump((char*)&DiskGeometry, dwRead);
+#endif
+ printf("Drive number: %lu\n", ulDrive);
+ printf("Cylinders: %I64u\nMediaType: %x\nTracksPerCylinder: %lu\n"
+ "SectorsPerTrack: %lu\nBytesPerSector: %lu\n\n",
+ DiskGeometry.Cylinders.QuadPart,
+ DiskGeometry.MediaType,
+ DiskGeometry.TracksPerCylinder,
+ DiskGeometry.SectorsPerTrack,
+ DiskGeometry.BytesPerSector);
+
+
+ Buffer = (char*)malloc(8192);
+ if (Buffer == NULL)
+ {
+ CloseHandle(hDisk);
+ printf("Out of memory!");
+ return 0;
+ }
+ memset(Buffer, 0, 8192);
+
+ if (!DeviceIoControl(hDisk,
+ IOCTL_DISK_GET_DRIVE_LAYOUT,
+ NULL,
+ 0,
+ Buffer,
+ 8192,
+ &dwRead,
+ NULL))
+ {
+ CloseHandle(hDisk);
+ printf("DeviceIoControl(IOCTL_DISK_GET_DRIVE_LAYOUT) failed! Error: %lu\n",
+ GetLastError());
+ free(Buffer);
+ return 0;
+ }
+
+ CloseHandle(hDisk);
+
+#ifdef DUMP_DATA
+ HexDump(Buffer, dwRead);
+#endif
+
+ LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)Buffer;
+
+ printf("Partitions %lu Signature %lx\n",
+ LayoutBuffer->PartitionCount,
+ LayoutBuffer->Signature);
+
+ for (i = 0; i < LayoutBuffer->PartitionCount; i++)
+ {
+ printf(" %ld: nr: %ld boot: %1x type: %x start: 0x%I64x count: 0x%I64x\n",
+ i,
+ LayoutBuffer->PartitionEntry[i].PartitionNumber,
+ LayoutBuffer->PartitionEntry[i].BootIndicator,
+ LayoutBuffer->PartitionEntry[i].PartitionType,
+ LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart,
+ LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart);
+ }
+
+ free(Buffer);
+
+ return 0;
+}
--- /dev/null
+<!-- $Id$ -->
+<HTML>
+<HEAD>
+<TITLE>Using NVidia drivers on ReactOS How-to</TITLE>
+</HEAD>
+<BODY>
+<CENTER><H1>Using NVidia drivers on ReactOS How-to</H1></CENTER>
+
+<H2>1. Introduction</H2>
+There is little support for changing video drivers (or any other driver for that
+matter) in ReactOS at the moment. You have to know how to access the CVS repository
+and how to compile (simple) programs. If this is too complicated, please wait a few
+months, we should have better installation tools then.
+
+<H2>2. Supported hardware</H2>
+The NVidia drivers were tested on the following video card:
+<UL>
+<LI>NVidia Riva TNT2 Model 64</LI>
+<LI>NVidia GeForce4 MX400</LI>
+</UL>
+However, according to the NVidia website, the same driver supports a whole series
+of video cards. If you find this driver works under ReactOS with other cards, please
+let us know on the <A HREF="mailto:ros-general@reactos.com">ros-general mailing list</A>
+
+<H2>3. Download the drivers</H2>
+First, go to the NVidia website, <A HREF="http://www.nvidia.com">www.nvidia.com</A>,
+choose "DOWNLOAD DRIVERS" from the menu at the top of the page (and
+"Download Drivers" again from the drop-down menu). Choose "Graphics Driver"
+in the first box, "GeForce and TNT2" in the second box and "Windows NT4"
+in the third box, then click "Go!". This How-to assumes you see a page identifying the
+driver you are about to download as version 43.45, release on April 10, 2003.
+Download the English version.<BR>
+(<A HREF="http://www.nvidia.com/object/winnt_43.45">This</A> is a direct link to the
+download page.)
+
+<H2>4. Unpack the drivers</H2>
+Start the file you just downloaded (note: you need to do this on a MS-Windows computer,
+doesn't work on ReactOS yet). It will ask you for a directory where to save the files.
+You can accept the default of C:\NVIDIA\WinNT4\43.45 or change it to your liking, just
+remember where you put them.... After the files are unpacked, the install wizard will
+start. Just press "Cancel" on the Welcome screen and tell the thing that, yes, you
+are quite sure you want to cancel the installation.<BR>
+Open a Command Prompt window and cd to C:\NVIDIA\WinNT4\43.45 (or wherever you put
+the files). You should have a nv4_mini.sy_ and a nv4_disp.dl_ file. Issue the following
+commands:
+<PRE>
+expand nv4_mini.sy_ nv4_mini.sys
+expand nv4_disp.dl_ nv4_disp.dll
+</PRE>
+After this, you should have a nv4_mini.sys file of 1511936 bytes and a nv4_disp.dll file
+of 569807 bytes.
+
+<H2>5. Patch the miniport driver</H2>
+Since ReactOS is not 100% binary compatible with MS-Windows yet, the miniport driver
+(nv4_mini.sys) needs to be patched. There is a small patch program in the ReactOS CVS
+tree at reactos/apps/utils/patchnv4 which you need to compile. Copy the patchnv4.exe
+to the directory where you have your nv4_mini.sys file and run it. Afterwards, you
+should have a nv4_mini.sys.orig (the original) and a nv4_mini.sys (the patched
+version).<BR>
+Note that we're working towards binary compatibility, so if you're not reading this
+on the <A HREF="http://www.reactos.com">ReactOS website</A>, please go there and check
+if the patching is still necessary (ReactOS might have been fixed...).
+
+<H2>6. Install the drivers</H2>
+The first step is simple, copy the (patched) nv4_mini.sys file to \ReactOS\System32\drivers
+and the nv4_disp.dll file to \ReactOS\System32. The second step is to update the
+registry to actually load the driver. Check out the CVS tree and edit the file
+reactos/bootdata/hivesys.inf. Add the following lines:
+<PRE>
+; NVidia driver
+HKLM,"SYSTEM\CurrentControlSet\Services\nv4","ErrorControl",0x00010001,0x00000000
+HKLM,"SYSTEM\CurrentControlSet\Services\nv4","Group",0x00000000,"Video"
+HKLM,"SYSTEM\CurrentControlSet\Services\nv4","ImagePath",0x00020000,"system32\drivers\nv4_mini.sys"
+HKLM,"SYSTEM\CurrentControlSet\Services\nv4","Start",0x00010001,0x00000004
+HKLM,"SYSTEM\CurrentControlSet\Services\nv4","Type",0x00010001,0x00000001
+HKLM,"SYSTEM\CurrentControlSet\Services\nv4\Device0","CapabilityOverride",0x00010001,0x00000000
+HKLM,"SYSTEM\CurrentControlSet\Services\nv4\Device0","EnableVia4x",0x00010001,0x00000001
+HKLM,"SYSTEM\CurrentControlSet\Services\nv4\Device0","InstalledDisplayDrivers",0x00010000,"nv4_disp"
+HKLM,"SYSTEM\CurrentControlSet\Services\nv4\Device0","NVREGSWITCHES",0x00000001,43,52,54,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,36,34,30,2c,34,38,30,2c,38,2c,36,30,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,36,34,30,2c,34,38,30,2c,38,\
+ 2c,36,30,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,36,34,30,2c,\
+ 34,38,30,2c,38,2c,36,30,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,36,34,30,2c,34,38,30,2c,38,2c,36,30,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,36,34,30,2c,34,38,30,2c,38,2c,36,30,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,36,34,30,2c,34,38,30,2c,38,2c,36,30,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,36,34,30,2c,34,38,30,2c,38,\
+ 2c,36,30,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,36,34,30,2c,\
+ 34,38,30,2c,38,2c,36,30,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,36,30,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,36,30,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,36,30,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,36,30,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,44,4d,54,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
+ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,01,00,00,00,01,00,\
+ 00,00,00,04,00,00,40,00,00,00,00,04,00,00,00,06,00,00,00,00,00,00,01,00,00,\
+ 00,00,00,00,00,00,00,00,00,05,00,00,00,00,00,04,00,00,00,50,00,00,00,01,00,\
+ 00,00,00,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,99,99,99,99,99,\
+ 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,00,00,\
+ 00,00
+HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\nv4\Device0","Attach.ToDesktop",0x00010001,1
+HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\nv4\Device0","Attach.RelativeX",0x00010001,0
+HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\nv4\Device0","Attach.RelativeY",0x00010001,0
+HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\nv4\Device0","DefaultSettings.BitsPerPel",0x00010001,16
+HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\nv4\Device0","DefaultSettings.XResolution",0x00010001,1152
+HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\nv4\Device0","DefaultSettings.YResolution",0x00010001,864
+HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\nv4\Device0","DefaultSettings.VRefresh",0x00010001,85
+HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\nv4\Device0","DefaultSettings.Flags",0x00010001,0
+HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\nv4\Device0","DefaultSettings.XPanning",0x00010001,0
+HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\nv4\Device0","DefaultSettings.YPanning",0x00010001,0
+</PRE>
+Feel free to adjust the DefaultSettings.BitsPerPel, DefaultSettings.XResolution,
+DefaultSettings.YResolution and DefaultSettings.VRefresh (check the Display control
+panel applet in MS-Windows for available settings for your card/monitor combo).<BR>
+Search that same file for the "VGA miniport driver" section and change the "Start"
+line in that section to:
+<PRE>
+HKLM,"SYSTEM\CurrentControlSet\Services\Vga","Start",0x00010001,0x00000004
+</PRE>
+(i.e. set the last value on that line to 4).<BR>
+Rebuild the registry with the command "make registry" and copy the resulting SYSTEM file
+to /ReactOS/System32/config. Reboot and enjoy.
+
+</BODY>
+</HTML>
--- /dev/null
+/* $Id$
+ *
+ * Patch the NVidia miniport driver to work with ReactOS
+ *
+ * Should become obsolete
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+struct Patch
+{
+ long Offset;
+ unsigned char ExpectedValue;
+ unsigned char NewValue;
+};
+
+static struct Patch Patches[ ] =
+{
+ { 0x1EBA9, 0x30, 0x3C },
+ { 0x1EBAA, 0xC0, 0xF0 },
+ { 0x1EC0B, 0x04, 0x01 },
+ { 0x1EC67, 0x30, 0x3C },
+ { 0x1EC68, 0xC0, 0xF0 }
+};
+
+int
+main(int argc, char *argv[])
+{
+ static char OriginalName[] = "nv4_mini.sys";
+ static char TempName[] = "nv4_mini.tmp";
+ static char BackupName[] = "nv4_mini.sys.orig";
+ FILE *File;
+ unsigned char *Buffer;
+ long Size;
+ unsigned n;
+
+ /* Read the whole file in memory */
+ File = fopen(OriginalName, "rb");
+ if (NULL == File)
+ {
+ perror("Unable to open original file");
+ exit(1);
+ }
+ if (fseek(File, 0, SEEK_END))
+ {
+ perror("Unable to determine file length");
+ fclose(File);
+ exit(1);
+ }
+ Size = ftell(File);
+ if (-1 == Size)
+ {
+ perror("Unable to determine file length");
+ fclose(File);
+ exit(1);
+ }
+ Buffer = malloc(Size);
+ if (NULL == Buffer)
+ {
+ perror("Can't allocate buffer");
+ fclose(File);
+ exit(1);
+ }
+ rewind(File);
+ if (Size != fread(Buffer, 1, Size, File))
+ {
+ perror("Error reading from original file");
+ free(Buffer);
+ fclose(File);
+ exit(1);
+ }
+ fclose(File);
+
+ /* Patch the file */
+ for (n = 0; n < sizeof(Patches) / sizeof(struct Patch); n++)
+ {
+ if (Buffer[Patches[n].Offset] != Patches[n].ExpectedValue)
+ {
+ fprintf(stderr, "Expected value 0x%02x at offset 0x%lx but found 0x%02x\n",
+ Patches[n].ExpectedValue, Patches[n].Offset,
+ Buffer[Patches[n].Offset]);
+ free(Buffer);
+ exit(1);
+ }
+ Buffer[Patches[n].Offset] = Patches[n].NewValue;
+ }
+
+ /* Write the new file */
+ File = fopen(TempName, "wb");
+ if (NULL == File)
+ {
+ perror("Unable to open output file");
+ free(Buffer);
+ exit(1);
+ }
+ if (Size != fwrite(Buffer, 1, Size, File))
+ {
+ perror("Error writing to output file");
+ fclose(File);
+ remove(TempName);
+ free(Buffer);
+ exit(1);
+ }
+ fclose(File);
+ free(Buffer);
+
+ /* Rename the original file, removing an existing backup */
+ remove(BackupName);
+ if (0 != rename(OriginalName, BackupName))
+ {
+ perror("Failed to rename original file");
+ remove(TempName);
+ exit(1);
+ }
+
+ /* Rename the new file */
+ if (0 != rename(TempName, OriginalName))
+ {
+ perror("Failed to rename new file");
+ remove(TempName);
+ rename(BackupName, OriginalName);
+ exit(1);
+ }
+
+ return 0;
+}
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ main.c
+
+Abstract:
+
+ loader/translator for pIce LINUX
+
+Environment:
+
+ User mode only
+
+Author:
+
+ Klaus P. Gerlicher
+ Reactos Port by Eugene Ingerman
+
+Revision History:
+
+ 04-Aug-1998: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+///////////////////////////////////////////////////////////////////////////////////
+// includes
+#include "stdinc.h"
+#include <wchar.h>
+
+///////////////////////////////////////////////////////////////////////////////////
+// constant defines
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// global variables
+char SrcFileNames[2048][2048];
+ULONG ulCurrentSrcFile = 0;
+
+HANDLE debugger_file;
+
+ULONG ulGlobalVerbose = 0;
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// process_stabs()
+//
+///////////////////////////////////////////////////////////////////////////////////
+void process_stabs(
+ char* pExeName, // name of exe
+ HANDLE fileout, // symbol file handle
+ PIMAGE_SECTION_HEADER section, //Elf32_Shdr* pSHdr,
+ int sectionHeadersSize, //int nSHdrSize,
+ void* p, // ptr to memory where whole exe was read
+ PSTAB_ENTRY pStab, // ptr to stabs
+ int nStabLen, // size of stabs
+ char* pStr, // ptr to stabs strings
+ int nStrLen, // sizeof stabs strings
+ char* pGlobals, // ptr to global symbols
+ int nGlobalLen, // sizeof of globals
+ char* pGlobalsStr, // ptr to global strings
+ int nGlobalStrLen) // size of global strings
+{
+ unsigned i,strLen;
+ int nOffset=0,nNextOffset=0;
+ PSTAB_ENTRY pStabCopy = pStab;
+ char* pName,szCurrentPath[2048];
+ PICE_SYMBOLFILE_HEADER SymbolFileHeader;
+ LPSTR pSlash,pDot;
+ char temp[2048];
+ char* pCopyExeName = temp;
+ WCHAR tempstr[64];
+ DWORD wrote;
+
+ //printf("LOADER: enter process_stabs()\n");
+
+ //get the name of the executable file
+ memset((void*)&SymbolFileHeader,0,sizeof(SymbolFileHeader));
+ SymbolFileHeader.magic = PICE_MAGIC;
+ strcpy(temp,pExeName);
+ pSlash = strrchr(temp,'\\');
+ pDot = strchr(temp,'.');
+ if(pDot)
+ {
+ *pDot = 0;
+ }
+ if(pSlash)
+ {
+ pCopyExeName = pSlash+1;
+ }
+ strLen = MultiByteToWideChar(CP_ACP, NULL, pCopyExeName, -1, tempstr, 64 );
+ if( !strLen )
+ printf("Cannot convert string to multibyte: %s\n", pCopyExeName );
+ wcscpy(SymbolFileHeader.name,tempstr);
+
+ for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
+ {
+ pName = &pStr[pStabCopy->n_strx + nOffset];
+
+#if 0
+ //printf("LOADER: \n%.8x %.2x %.2x %.4x %.8x %s\n",
+ pStabCopy->n_strx,
+ pStabCopy->n_type,
+ pStabCopy->n_other,
+ pStabCopy->n_desc,
+ pStabCopy->n_value,
+ pName
+ );
+#endif
+ switch(pStabCopy->n_type)
+ {
+ case N_UNDF:
+ nOffset += nNextOffset;
+ nNextOffset = pStabCopy->n_value;
+ //printf("LOADER: changing string offset %x %x\n",nOffset,nNextOffset);
+ break;
+ case N_SO:
+ if((strLen = strlen(pName)))
+ {
+ if(pName[strLen-1]!='/')
+ {
+ if(strlen(szCurrentPath))
+ {
+ //printf("LOADER: ###########################################################################\n");
+ strcat(szCurrentPath,pName);
+ //printf("LOADER: changing source file %s\n",szCurrentPath);
+ strcpy(SrcFileNames[ulCurrentSrcFile++],szCurrentPath);
+ szCurrentPath[0]=0;
+ }
+ else
+ {
+ //printf("LOADER: ###########################################################################\n");
+ //printf("LOADER: changing source file %s\n",pName);
+ strcpy(SrcFileNames[ulCurrentSrcFile++],pName);
+ }
+ }
+ else
+ strcpy(szCurrentPath,pName);
+ }
+ else
+ {
+ //printf("LOADER: END source file\n");
+ //printf("LOADER: ###########################################################################\n");
+ }
+ break;
+/* case N_SLINE:
+ //printf("LOADER: code source line number #%u for addr. %x\n",pStabCopy->n_desc,pStabCopy->n_value);
+ break;
+ case N_DSLINE:
+ //printf("LOADER: data source line number #%u for addr. %x\n",pStabCopy->n_desc,pStabCopy->n_value);
+ break;
+ case N_BSLINE:
+ //printf("LOADER: BSS source line number #%u for addr. %x\n",pStabCopy->n_desc,pStabCopy->n_value);
+ break;
+ case N_GSYM:
+ //printf("LOADER: global symbol %s @ addr. %x (%x)\n",pName,pStabCopy->n_value,pStabCopy->n_desc);
+ break;
+ case N_BINCL:
+ //printf("LOADER: include file %s\n",pName);
+ break;
+ case N_EINCL:
+ break;
+ case N_FUN:
+ if(strlen(pName))
+ //printf("LOADER: function %s @ addr. %x (%x)\n",pName,pStabCopy->n_value,pStabCopy->n_desc);
+ else
+ //printf("LOADER: text segment %x (%x)\n",pName,pStabCopy->n_value,pStabCopy->n_desc);
+ break;
+ case N_PSYM:
+ //printf("LOADER: parameter %s @ [EBP%+d] (%x)\n",pName,pStabCopy->n_value,pStabCopy->n_desc);
+ break;
+ case N_RSYM:
+ //printf("LOADER: register variable %s @ reg. %x (%x)\n",pName,pStabCopy->n_value,pStabCopy->n_desc);
+ break;
+ case N_LBRAC:
+ //printf("LOADER: lexical block %s @ reg. %x (%x)\n",pName,pStabCopy->n_value,pStabCopy->n_desc);
+ break;
+ case N_RBRAC:
+ //printf("LOADER: END of lexical block %s @ reg. %x (%x)\n",pName,pStabCopy->n_value,pStabCopy->n_desc);
+ break;
+ case N_STSYM:
+ //printf("LOADER: static variable %s @ %x (%x)\n",pName,pStabCopy->n_value,pStabCopy->n_desc);
+ break;
+ case N_LCSYM:
+ //printf("LOADER: BSS variable %s @ %x (%x)\n",pName,pStabCopy->n_value,pStabCopy->n_desc);
+ break;
+ case N_LSYM:
+ if(pStabCopy->n_value)
+ {
+ //printf("LOADER: stack variable %s @ [EBP%+d] (%x)\n",pName,pStabCopy->n_value,pStabCopy->n_desc);
+ }
+ else
+ {
+ //printf("LOADER: global variable %s \n",pName);
+ }
+ break;
+*/
+ }
+
+ pStabCopy++;
+ }
+
+ //printf("LOADER: SymbolFileHeader.ulSizeOfHeader= %x (%x)\n",nSHdrSize,(LPSTR)pSHdr-(LPSTR)p);
+ //printf("LOADER: SymbolFileHeader.ulSizeOfGlobals = %x (%x)\n",nGlobalLen,(LPSTR)pGlobals-(LPSTR)p);
+ //printf("LOADER: SymbolFileHeader.ulSizeOfGlobalsStrings = %x (%x)\n",nGlobalStrLen,(LPSTR)pGlobalsStr-(LPSTR)p);
+ //printf("LOADER: SymbolFileHeader.ulSizeOfStabs = %x (%x)\n",nStabLen,(LPSTR)pStab-(LPSTR)p);
+ //printf("LOADER: SymbolFileHeader.ulSizeOfStabsStrings = %x (%x)\n",nStrLen,(LPSTR)pStr-(LPSTR)p);
+
+ SymbolFileHeader.ulOffsetToHeaders = sizeof(PICE_SYMBOLFILE_HEADER);
+ SymbolFileHeader.ulSizeOfHeader = sectionHeadersSize;
+ SymbolFileHeader.ulOffsetToGlobals = sizeof(PICE_SYMBOLFILE_HEADER)+sectionHeadersSize;
+ SymbolFileHeader.ulSizeOfGlobals = nGlobalLen;
+ SymbolFileHeader.ulOffsetToGlobalsStrings = sizeof(PICE_SYMBOLFILE_HEADER)+sectionHeadersSize+nGlobalLen;
+ SymbolFileHeader.ulSizeOfGlobalsStrings = nGlobalStrLen;
+ SymbolFileHeader.ulOffsetToStabs = sizeof(PICE_SYMBOLFILE_HEADER)+sectionHeadersSize+nGlobalLen+nGlobalStrLen;
+ SymbolFileHeader.ulSizeOfStabs = nStabLen;
+ SymbolFileHeader.ulOffsetToStabsStrings = sizeof(PICE_SYMBOLFILE_HEADER)+sectionHeadersSize+nGlobalLen+nGlobalStrLen+nStabLen;
+ SymbolFileHeader.ulSizeOfStabsStrings = nStrLen;
+ SymbolFileHeader.ulOffsetToSrcFiles = sizeof(PICE_SYMBOLFILE_HEADER)+sectionHeadersSize+nGlobalLen+nGlobalStrLen+nStabLen+nStrLen;
+ SymbolFileHeader.ulNumberOfSrcFiles = ulCurrentSrcFile;
+
+ printf("sectionHeaderSize: %ld, nGlobalLen: %ld, nGlobalStrLen: %ld, nStabLen: %ld, "
+ "nStrLen: %ld, ulCurrentSrcFile: %ld, ulOffsetToStabs: %ld\n",
+ sectionHeadersSize, nGlobalLen, nGlobalStrLen,
+ nStabLen, nStrLen, ulCurrentSrcFile, SymbolFileHeader.ulOffsetToStabs);
+
+ WriteFile(fileout,&SymbolFileHeader,sizeof(PICE_SYMBOLFILE_HEADER),&wrote, NULL);
+ WriteFile(fileout,section,sectionHeadersSize,&wrote, NULL);
+ WriteFile(fileout,pGlobals,nGlobalLen,&wrote, NULL);
+ WriteFile(fileout,pGlobalsStr,nGlobalStrLen,&wrote, NULL);
+ WriteFile(fileout,pStab,nStabLen,&wrote, NULL);
+ WriteFile(fileout,pStr,nStrLen,&wrote, NULL);
+
+ for(i=0;i<ulCurrentSrcFile;i++)
+ {
+ HANDLE file;
+ int len;
+ PVOID pFile;
+ PICE_SYMBOLFILE_SOURCE pss;
+
+ file = CreateFile(SrcFileNames[i],GENERIC_READ , 0, NULL, OPEN_EXISTING, 0, 0);
+ //printf("Trying To Open: %s, result: %x\n", SrcFileNames[i], file );
+
+
+ if( file == INVALID_HANDLE_VALUE ){
+ //let's try win format drive:/file
+ char srctmp[2048];
+ strcpy(srctmp, SrcFileNames[i] );
+ if(strncmp(srctmp,"//",2)==0){
+ *(srctmp) = *(srctmp+2);
+ *(srctmp+1) = ':';
+ *(srctmp+2) = '/';
+ file = CreateFile(srctmp,GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
+ //printf("Trying To Open: %s, handle: %x\n", srctmp, file );
+ if( file == INVALID_HANDLE_VALUE )
+ printf("Can't open file: %s\n", srctmp );
+ }
+ }
+ if(file != INVALID_HANDLE_VALUE)
+ {
+ //printf("LOADER: [%u] opened %s as FD %x\n",i,SrcFileNames[i],file);
+
+ len = SetFilePointer(file,0,NULL,FILE_END);
+ //printf("LOADER: length = %d\n",(int)len);
+
+ SetFilePointer(file,0,NULL,FILE_BEGIN);
+
+ strcpy(pss.filename,SrcFileNames[i]);
+ pss.ulOffsetToNext = len+sizeof(PICE_SYMBOLFILE_SOURCE);
+
+ pFile = malloc(len+1);
+ //printf("LOADER: memory for file @ %x\n",pFile);
+ if(pFile)
+ {
+ //printf("LOADER: reading file...\n");
+ ReadFile(file,pFile,len+1,&wrote,NULL);
+ //printf("read: %d, error: %d\n", wrote, GetLastError());
+ WriteFile(fileout,&pss,sizeof(PICE_SYMBOLFILE_SOURCE),&wrote, NULL);
+ WriteFile(fileout,pFile,len,&wrote, NULL);
+ //printf("LOADER: writing file...%d\n%s\n",wrote,pFile );
+ free(pFile);
+ }
+
+ CloseHandle(file);
+ }
+
+ }
+
+ //printf("LOADER: leave process_stabs()\n");
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// find_stab_sections()
+//
+///////////////////////////////////////////////////////////////////////////////////
+void find_stab_sections(void* p,PIMAGE_SECTION_HEADER section, unsigned cSections,
+ PSTAB_ENTRY* ppStab,int* pLen,char** ppStr,int* pnStabStrLen)
+{
+ unsigned i;
+ //printf("LOADER: enter find_stab_sections()\n");
+ *ppStab = 0;
+ *ppStr = 0;
+
+ for ( i=1; i <= cSections; i++, section++ )
+ {
+
+ if(strcmp(section->Name,".stab") == 0)
+ {
+ *ppStab = (PSTAB_ENTRY)((int)p + section->PointerToRawData);
+ *pLen = section->SizeOfRawData;
+ printf("LOADER: .stab @ %x (offset %x) len = %x\n",*ppStab,section->PointerToRawData,section->SizeOfRawData);
+ }
+ else if(strncmp(section->Name,".stabstr",strlen(".stabstr")) == 0)
+ {
+ *ppStr = (char*)((int)p + section->PointerToRawData);
+ *pnStabStrLen = section->SizeOfRawData;
+ printf("LOADER: .stabstr @ %x (offset %x) len = %x\n",*ppStab,section->PointerToRawData,section->SizeOfRawData);
+ }
+ }
+
+ //printf("LOADER: leave find_stab_sections()\n");
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// process_pe()
+//
+///////////////////////////////////////////////////////////////////////////////////
+int process_pe(char* filename,int file,void* p,int len)
+{
+
+ PIMAGE_DOS_HEADER pDosHeader;
+ PIMAGE_NT_HEADERS pNTHeaders;
+
+ char* pStr;
+ PSTAB_ENTRY pStab;
+ DWORD nStabLen,nSym;
+ char* pStrTab;
+ char* pSymTab;
+
+ char szSymName[2048];
+ HANDLE fileout;
+ int nSymStrLen,nStabStrLen;
+ int iRetVal = 0;
+
+ pDosHeader = (PIMAGE_DOS_HEADER)p;
+ pNTHeaders = (PIMAGE_NT_HEADERS)((DWORD)p + pDosHeader->e_lfanew);
+
+ if ((pDosHeader->e_magic == IMAGE_DOS_SIGNATURE)
+ && (pDosHeader->e_lfanew != 0L)
+ && (pNTHeaders->Signature == IMAGE_NT_SIGNATURE))
+ {
+ if( pNTHeaders->FileHeader.PointerToSymbolTable ){
+
+ pSymTab = (char*)((DWORD)p + pNTHeaders->FileHeader.PointerToSymbolTable);
+ nSym = pNTHeaders->FileHeader.NumberOfSymbols;
+ //string table follows immediately after symbol table. first 4 bytes give the length of the table
+ //references to string table include the first 4 bytes.
+ pStrTab = (char*)((PIMAGE_SYMBOL)pSymTab + nSym);
+ nSymStrLen = *((DWORD*)pStrTab);
+ find_stab_sections(p,IMAGE_FIRST_SECTION(pNTHeaders),pNTHeaders->FileHeader.NumberOfSections,
+ &pStab,&nStabLen,&pStr,&nStabStrLen);
+
+ if(pStab && nStabLen && pStr && nStabStrLen)
+ {
+ LPSTR pDot;
+
+ strcpy(szSymName,filename);
+ //printf("LOADER: file name = %s\n",szSymName);
+ if((pDot = strchr(szSymName,'.')))
+ {
+ *pDot = 0;
+ strcat(pDot,".dbg");
+ }
+ else
+ {
+ strcat(szSymName,".dbg");
+ }
+ //printf("LOADER: symbol file name = %s\n",szSymName);
+ printf("LOADER: creating symbol file %s for %s\n",szSymName,filename);
+
+ fileout = CreateFile(szSymName,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ 0,
+ 0);
+
+ if(fileout != INVALID_HANDLE_VALUE)
+ {
+ printf("NumberOfSections: %d, size: %d\n", pNTHeaders->FileHeader.NumberOfSections,sizeof(IMAGE_SECTION_HEADER));
+ process_stabs(szSymName,
+ fileout,
+ IMAGE_FIRST_SECTION(pNTHeaders),
+ pNTHeaders->FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER),
+ p,
+ pStab,
+ nStabLen,
+ pStr,
+ nStabStrLen,
+ (char*)pSymTab,
+ nSym*sizeof(IMAGE_SYMBOL),
+ pStrTab,
+ nSymStrLen);
+
+ CloseHandle(fileout);
+ }
+ else
+ {
+ printf("LOADER: creation of symbol file %s failed\n",szSymName);
+ iRetVal = 2;
+ }
+
+ }
+ else
+ {
+ printf("LOADER: file %s has no data inside symbol tables\n",filename);
+ if( ulGlobalVerbose )
+ {
+ if( !pStab || !nStabLen )
+ printf("LOADER: - symbol table is empty or not present\n");
+ if( !pStr || !nStabStrLen )
+ printf("LOADER: - string table is empty or not present\n");
+ }
+ iRetVal = 2;
+ }
+ }
+ else{
+ printf("LOADER: file %s does not have a symbol table\n",filename);
+ iRetVal = 2;
+ }
+ }
+ else
+ {
+ printf("LOADER: file %s is not an ELF binary\n",filename);
+ iRetVal = 1;
+ }
+
+ //printf("LOADER: leave process_pe()\n");
+ return iRetVal;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// process_file()
+//
+///////////////////////////////////////////////////////////////////////////////////
+int process_file(char* filename)
+{
+ int file;
+ void* p;
+ off_t len;
+ int iRetVal=0;
+
+ //printf("LOADER: enter process_file()\n");
+ file = _open(filename,O_RDONLY|_O_BINARY);
+ if(file>0)
+ {
+ //printf("LOADER: opened %s as FD %x\n",filename,file);
+
+ len = _lseek(file,0,SEEK_END);
+ printf("LOADER: file %s is %u bytes\n",filename,(int)len);
+
+ _lseek(file,0,SEEK_SET);
+
+ p = malloc(len+16);
+ if(p)
+ {
+ long count;
+ //printf("LOADER: malloc'd @ %x\n",p);
+ memset(p,0,len+16);
+ if(len == (count = _read(file,p,len)))
+ {
+ //printf("LOADER: trying ELF format\n");
+ iRetVal = process_pe(filename,file,p,len);
+ }
+ }
+ _close(file);
+ }
+ else
+ {
+ printf("LOADER: file %s could not be opened\n",filename);
+ iRetVal = 1;
+ }
+
+ //printf("LOADER: leave process_file()\n");
+ return iRetVal;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// open_debugger()
+//
+///////////////////////////////////////////////////////////////////////////////////
+HANDLE open_debugger(void)
+{
+ debugger_file = CreateFile("\\Device\\Pice",GENERIC_READ,0,NULL,OPEN_EXISTING,NULL,NULL);
+ if(debugger_file == INVALID_HANDLE_VALUE)
+ {
+ printf("LOADER: debugger is not loaded. Last Error: %ld\n", GetLastError());
+ }
+
+ return debugger_file;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// close_debugger()
+//
+///////////////////////////////////////////////////////////////////////////////////
+void close_debugger(void)
+{
+ if( !CloseHandle(debugger_file) ){
+ printf("Error closing debugger handle: %ld\n", GetLastError());
+ }
+}
+
+int ioctl( HANDLE device, DWORD ioctrlcode, PDEBUGGER_STATUS_BLOCK psb)
+{
+ DEBUGGER_STATUS_BLOCK tsb;
+ DWORD bytesreturned;
+ if( !DeviceIoControl( device, ioctrlcode, psb, sizeof(DEBUGGER_STATUS_BLOCK),
+ &tsb, sizeof(DEBUGGER_STATUS_BLOCK),&bytesreturned, NULL) ){
+ printf("Error in DeviceIoControl: %ld\n", GetLastError());
+ return -EINVAL;
+ }
+ else{
+ memcpy( psb, &tsb, sizeof(DEBUGGER_STATUS_BLOCK) );
+ }
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// banner()
+//
+///////////////////////////////////////////////////////////////////////////////////
+void banner(void)
+{
+ printf("#########################################################\n");
+ printf("#### Symbols LOADER/TRANSLATOR for PICE ####\n");
+ printf("#########################################################\n");
+}
+
+#define ACTION_NONE 0
+#define ACTION_LOAD 1
+#define ACTION_UNLOAD 2
+#define ACTION_TRANS 3
+#define ACTION_RELOAD 4
+#define ACTION_INSTALL 5
+#define ACTION_UNINSTALL 6
+#define ACTION_STATUS 7
+#define ACTION_BREAK 8
+#define ACTION_TERMINAL 9
+
+///////////////////////////////////////////////////////////////////////////////////
+// change_symbols()
+//
+///////////////////////////////////////////////////////////////////////////////////
+void change_symbols(int action,char* pfilename)
+{
+ int iRetVal = 0;
+ DEBUGGER_STATUS_BLOCK sb;
+
+ strcpy(sb.filename, pfilename);
+
+ switch(action)
+ {
+ case ACTION_LOAD:
+ printf("LOADER: loading symbols from %s\n",pfilename);
+ if(open_debugger() != INVALID_HANDLE_VALUE)
+ {
+ iRetVal = ioctl(debugger_file,PICE_IOCTL_LOAD,&sb);
+ close_debugger();
+ }
+ break;
+ case ACTION_UNLOAD:
+ printf("LOADER: unloading symbols from %s\n",pfilename);
+ if(open_debugger() != INVALID_HANDLE_VALUE)
+ {
+ iRetVal = ioctl(debugger_file,PICE_IOCTL_UNLOAD,&sb);
+ close_debugger();
+ }
+ break;
+ case ACTION_RELOAD:
+ printf("LOADER: reloading all symbols\n");
+ if(open_debugger() != INVALID_HANDLE_VALUE)
+ {
+ ioctl(debugger_file,PICE_IOCTL_RELOAD,NULL);
+ close_debugger();
+ printf("LOADER: reloading DONE!\n");
+ }
+ break;
+ default :
+ printf("LOADER: an internal error has occurred at change_symbols\n");
+ }
+
+ switch( iRetVal )
+ {
+ case -EINVAL :
+ printf("LOADER: debugger return value = -EINVAL, operation has failed\n");
+ break;
+ case 0 :
+ // success - silently proceed
+ break;
+ default :
+ printf("LOADER: debugger return value = %i, operation possibly failed\n",iRetVal);
+ }
+}
+
+// Dynamic install to be added later
+#if 0
+///////////////////////////////////////////////////////////////////////////////////
+// tryinstall()
+//
+///////////////////////////////////////////////////////////////////////////////////
+int tryinstall(void)
+{
+ char *argv[]={"/sbin/insmod","pice.o",NULL};
+ int err = 0;
+ int pid,status;
+
+ banner();
+ printf("LOADER: trying to install debugger...\n");
+
+ if( open_debugger() != INVALID_HANDLE_VALUE )
+ {
+ printf("LOADER: debugger already installed...\n");
+ close_debugger();
+ return 0;
+ }
+
+ // create a separate thread
+ pid = fork();
+ switch(pid)
+ {
+ case -1:
+ // error when forking, i.e. out E_NOMEM
+ err = errno;
+ printf("LOADER: fork failed for execution of '%s' (errno = %u).\n",argv[0],err);
+ break;
+ case 0:
+ // child process handler
+ execve(argv[0],argv,NULL);
+ // returns only on error, with return value -1, errno is set
+ printf("LOADER: couldn't execute '%s' (errno = %u)\n",argv[0],errno);
+ exit(255);
+ break;
+ default:
+ // parent process handler
+ printf("LOADER: waiting for debugger to load...\n");
+ pid = waitpid(pid, &status, 0); // suspend until child is done
+ if( (pid>0) && WIFEXITED(status) && (WEXITSTATUS(status) == 0) )
+ printf("LOADER: debugger loaded!\n");
+ else if( pid<=0 )
+ {
+ printf("LOADER: Error on loading debugger! (waitpid() = %i)\n",pid);
+ err = -1;
+ }
+ else if( !WIFEXITED(status) )
+ {
+ printf("LOADER: Error on loading debugger! (ifexited = %i)\n",WIFEXITED(status));
+ err = -1;
+ }
+ else
+ {
+ printf("LOADER: Error on loading debugger! (exitstatus = %u)\n",WEXITSTATUS(status));
+ err = WEXITSTATUS(status);
+ }
+ break;
+ }
+
+ return err;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// tryuninstall()
+//
+///////////////////////////////////////////////////////////////////////////////////
+int tryuninstall(void)
+{
+ char *argv[]={"/sbin/rmmod","pice",NULL};
+ int err = 0;
+ int pid,status;
+
+ banner();
+ printf("LOADER: trying to remove debugger...\n");
+
+ // check for loaded debugger
+ if(open_debugger() == INVALID_HANDLE_VALUE)
+ {
+ return -1;
+ }
+ // don't to close, else we'll have a reference count != 0
+ close_debugger();
+
+ // create a separate thread
+ pid = fork();
+ switch(pid)
+ {
+ case -1:
+ // error when forking, i.e. out E_NOMEM
+ err = errno;
+ printf("LOADER: fork failed for execution of '%s' (errno=%u).\n",argv[0],err);
+ break;
+ case 0:
+ // child process handler
+ execve(argv[0],argv,NULL);
+ // returns only on error, with return value -1, errno is set
+ printf("LOADER: couldn't execute '%s' (errno = %u)\n",argv[0],errno);
+ exit(255);
+ break;
+ default:
+ // parent process handler
+ printf("LOADER: waiting for debugger to unload...\n");
+ pid = waitpid(pid, &status, 0); // suspend until child is done
+
+ if( (pid>0) && WIFEXITED(status) && (WEXITSTATUS(status) == 0) )
+ printf("LOADER: debugger removed!\n");
+ else if( pid<=0 )
+ {
+ printf("LOADER: Error on removing debugger! (waitpid() = %i)\n",pid);
+ err = -1;
+ }
+ else if( !WIFEXITED(status) )
+ {
+ printf("LOADER: Error on removing debugger! (ifexited = %i)\n",WIFEXITED(status));
+ err = -1;
+ }
+ else
+ {
+ printf("LOADER: Error on removing debugger! (exitstatus = %u)\n",WEXITSTATUS(status));
+ err = WEXITSTATUS(status);
+ }
+ break;
+ }
+ return err;
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////
+// showstatus()
+//
+///////////////////////////////////////////////////////////////////////////////////
+void showstatus(void)
+{
+ DEBUGGER_STATUS_BLOCK sb;
+ int iRetVal;
+
+ if(open_debugger() != INVALID_HANDLE_VALUE)
+ {
+ iRetVal = ioctl(debugger_file,PICE_IOCTL_STATUS,&sb);
+
+ //printf("LOADER: Test = %X\n",sb.Test);
+ close_debugger();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// dobreak()
+//
+///////////////////////////////////////////////////////////////////////////////////
+void dobreak(void)
+{
+ int iRetVal;
+
+ if(open_debugger() != INVALID_HANDLE_VALUE)
+ {
+ iRetVal = ioctl(debugger_file,PICE_IOCTL_BREAK,NULL);
+ close_debugger();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// doterminal()
+//
+///////////////////////////////////////////////////////////////////////////////////
+#if 0
+void doterminal(void)
+{
+ if(SetupSerial(2,B115200))
+ {
+ DebuggerShell();
+ CloseSerial();
+ }
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////
+// process_switches()
+//
+// returns !=0 in case of a commandline error
+//
+///////////////////////////////////////////////////////////////////////////////////
+int process_switches(int argc,char* argv[])
+{
+ int i;
+ char* parg,*pfilename = NULL;
+ int action = ACTION_NONE;
+ int error = 0;
+
+ // parse commandline arguments
+ for(i=1;i<argc;i++)
+ {
+ parg = argv[i];
+ if(*parg == '-')
+ {
+ int new_action=ACTION_NONE;
+
+ parg++;
+ if(strcmp(parg,"load")==0 || strcmp(parg,"l")==0)
+ {
+ new_action = ACTION_LOAD;
+ }
+ else if(strcmp(parg,"unload")==0 || strcmp(parg,"u")==0)
+ {
+ new_action = ACTION_UNLOAD;
+ }
+ else if(strcmp(parg,"trans")==0 || strcmp(parg,"t")==0)
+ {
+ new_action = ACTION_TRANS;
+ }
+ else if(strcmp(parg,"reload")==0 || strcmp(parg,"r")==0)
+ {
+ new_action = ACTION_RELOAD;
+ }
+ else if(strcmp(parg,"verbose")==0 || strcmp(parg,"v")==0)
+ {
+ if( ulGlobalVerbose+1 > ulGlobalVerbose )
+ ulGlobalVerbose++;
+ }
+ else if(strcmp(parg,"install")==0 || strcmp(parg,"i")==0)
+ {
+ new_action = ACTION_INSTALL;
+ }
+ else if(strcmp(parg,"uninstall")==0 || strcmp(parg,"x")==0)
+ {
+ new_action = ACTION_UNINSTALL;
+ }
+ else if(strcmp(parg,"status")==0 || strcmp(parg,"s")==0)
+ {
+ new_action = ACTION_STATUS;
+ }
+ else if(strcmp(parg,"break")==0 || strcmp(parg,"b")==0)
+ {
+ new_action = ACTION_BREAK;
+ }
+ else if(strcmp(parg,"serial")==0 || strcmp(parg,"ser")==0)
+ {
+ new_action = ACTION_TERMINAL;
+ }
+ else
+ {
+ printf("LOADER: error: unknown switch %s", argv[i]);
+ error = 1;
+ }
+
+ if( new_action != ACTION_NONE )
+ {
+ if( action == ACTION_NONE )
+ action = new_action;
+ else
+ if( action == new_action )
+ {
+ // identical, just ignore
+ }
+ else
+ {
+ printf("LOADER: error: conflicting switch %s", argv[i]);
+ error = 1;
+ }
+ }
+ }
+ else
+ {
+ if( pfilename )
+ {
+ printf("LOADER: error: additional filename %s", parg);
+ error = 1;
+ }
+ pfilename = parg;
+ }
+ }
+
+ // check number of required parameters
+ switch( action )
+ {
+ case ACTION_TRANS :
+ case ACTION_LOAD :
+ case ACTION_UNLOAD :
+ if( !pfilename )
+ {
+ printf("LOADER: error: missing filename\n");
+ error = 1;
+ }
+ break;
+ case ACTION_RELOAD :
+ /* filename parameter is optional */
+ break;
+#if 0
+ case ACTION_UNINSTALL:
+ close_debugger();
+ tryuninstall();
+ break;
+ case ACTION_INSTALL:
+ tryinstall();
+ break;
+#endif
+ case ACTION_STATUS:
+ showstatus();
+ break;
+ case ACTION_BREAK:
+ dobreak();
+ break;
+#if 0
+ case ACTION_TERMINAL:
+ doterminal();
+ break;
+#endif
+ case ACTION_NONE :
+ printf("LOADER: no action specified specifed on commandline\n");
+ error = 1;
+
+ break;
+ default :
+ printf("LOADER: an internal error has occurred at commandline parsing\n");
+ error = 1;
+ }
+
+ if( !error ) // commandline was fine, now start processing
+ {
+ switch( action )
+ {
+ case ACTION_TRANS :
+ printf("LOADER: trying to translate file %s...\n",pfilename);
+ if( process_file(pfilename)==0 )
+ printf("LOADER: file %s has been translated\n",pfilename);
+ else
+ printf("LOADER: error while translating file %s\n",pfilename);
+ break;
+ case ACTION_LOAD :
+ case ACTION_UNLOAD :
+ case ACTION_RELOAD :
+ change_symbols(action,pfilename);
+ break;
+ }
+ }
+
+ return error;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// showhelp()
+//
+///////////////////////////////////////////////////////////////////////////////////
+void showhelp(void)
+{
+ banner();
+ printf("LOADER: Syntax:\n");
+ printf("LOADER: loader [switches] [executable/object file path]\n");
+ printf("LOADER: Switches:\n");
+ printf("LOADER: -trans (-t): translate from exe to sym\n");
+ printf("LOADER: -load (-l): load symbols\n");
+ printf("LOADER: -unload (-u): unload symbols\n");
+ printf("LOADER: -reload (-r): reload some/all symbols\n");
+ printf("LOADER: -verbose (-v): be a bit more verbose\n");
+ printf("LOADER: -install (-i): install pICE debugger\n");
+ printf("LOADER: -uninstall (-x): uninstall pICE debugger\n");
+ printf("LOADER: -break (-b): break into debugger\n");
+ printf("LOADER: -serial (-ser): start serial line terminal\n");
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// showpermission()
+//
+///////////////////////////////////////////////////////////////////////////////////
+void showpermission(void)
+{
+ banner();
+ printf("LOADER: You must be superuser!\n");
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// main()
+//
+///////////////////////////////////////////////////////////////////////////////////
+int main(int argc,char* argv[])
+{
+ if(argc==1 || argc>3)
+ {
+ showhelp();
+
+ return 1;
+ }
+
+ return process_switches(argc,argv);
+}
--- /dev/null
+typedef unsigned int ULONG,*PULONG;
+typedef unsigned short USHORT,*PUSHORT;
+typedef unsigned char UCHAR,*PUCHAR;
+
+typedef signed int LONG,*PLONG;
+typedef signed short SHORT,*PSHORT;
+typedef signed char CHAR,*PCHAR,*LPSTR,*PSTR;
+
+typedef void VOID,*PVOID;
+
+typedef char BOOLEAN,*PBOOLEAN;
+
+#define FALSE (0==1)
+#define TRUE (1==1)
+
--- /dev/null
+/* Table of DBX symbol codes for the GNU system.
+ Copyright (C) 1988, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+\f
+/* New stab from Solaris 2. This uses an n_type of 0, which in a.out files
+ overlaps the N_UNDF used for ordinary symbols. In ELF files, the
+ debug information is in a different file section, so there is no conflict.
+ This symbol's n_value gives the size of the string section associated
+ with this file. The symbol's n_strx (relative to the just-updated
+ string section start address) gives the name of the source file,
+ e.g. "foo.c", without any path information. The symbol's n_desc gives
+ the count of upcoming symbols associated with this file (not including
+ this one). */
+__define_stab (N_UNDF, 0x00, "UNDF")
+
+/* Global variable. Only the name is significant.
+ To find the address, look in the corresponding external symbol. */
+__define_stab (N_GSYM, 0x20, "GSYM")
+
+/* Function name for BSD Fortran. Only the name is significant.
+ To find the address, look in the corresponding external symbol. */
+__define_stab (N_FNAME, 0x22, "FNAME")
+
+/* Function name or text-segment variable for C. Value is its address.
+ Desc is supposedly starting line number, but GCC doesn't set it
+ and DBX seems not to miss it. */
+__define_stab (N_FUN, 0x24, "FUN")
+
+/* Data-segment variable with internal linkage. Value is its address.
+ "Static Sym". */
+__define_stab (N_STSYM, 0x26, "STSYM")
+
+/* BSS-segment variable with internal linkage. Value is its address. */
+__define_stab (N_LCSYM, 0x28, "LCSYM")
+
+/* Name of main routine. Only the name is significant. */
+__define_stab (N_MAIN, 0x2a, "MAIN")
+
+/* Solaris2: Read-only data symbols. */
+__define_stab (N_ROSYM, 0x2c, "ROSYM")
+
+/* Global symbol in Pascal.
+ Supposedly the value is its line number; I'm skeptical. */
+__define_stab (N_PC, 0x30, "PC")
+
+/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */
+__define_stab (N_NSYMS, 0x32, "NSYMS")
+
+/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */
+__define_stab (N_NOMAP, 0x34, "NOMAP")
+
+/* New stab from Solaris 2. Like N_SO, but for the object file. Two in
+ a row provide the build directory and the relative path of the .o from it.
+ Solaris2 uses this to avoid putting the stabs info into the linked
+ executable; this stab goes into the ".stab.index" section, and the debugger
+ reads the real stabs directly from the .o files instead. */
+__define_stab (N_OBJ, 0x38, "OBJ")
+
+/* New stab from Solaris 2. Options for the debugger, related to the
+ source language for this module. E.g. whether to use ANSI
+ integral promotions or traditional integral promotions. */
+__define_stab (N_OPT, 0x3c, "OPT")
+
+/* Register variable. Value is number of register. */
+__define_stab (N_RSYM, 0x40, "RSYM")
+
+/* Modula-2 compilation unit. Can someone say what info it contains? */
+__define_stab (N_M2C, 0x42, "M2C")
+
+/* Line number in text segment. Desc is the line number;
+ value is corresponding address. On Solaris2, the line number is
+ relative to the start of the current function. */
+__define_stab (N_SLINE, 0x44, "SLINE")
+
+/* Similar, for data segment. */
+__define_stab (N_DSLINE, 0x46, "DSLINE")
+
+/* Similar, for bss segment. */
+__define_stab (N_BSLINE, 0x48, "BSLINE")
+
+/* Sun's source-code browser stabs. ?? Don't know what the fields are.
+ Supposedly the field is "path to associated .cb file". THIS VALUE
+ OVERLAPS WITH N_BSLINE! */
+__define_stab_duplicate (N_BROWS, 0x48, "BROWS")
+
+/* GNU Modula-2 definition module dependency. Value is the modification time
+ of the definition file. Other is non-zero if it is imported with the
+ GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there
+ are enough empty fields? */
+__define_stab(N_DEFD, 0x4a, "DEFD")
+
+/* New in Solaris2. Function start/body/end line numbers. */
+__define_stab(N_FLINE, 0x4C, "FLINE")
+
+/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2
+ and one is for C++. Still,... */
+/* GNU C++ exception variable. Name is variable name. */
+__define_stab (N_EHDECL, 0x50, "EHDECL")
+/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */
+__define_stab_duplicate (N_MOD2, 0x50, "MOD2")
+
+/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if
+ this entry is immediately followed by a CAUGHT stab saying what exception
+ was caught. Multiple CAUGHT stabs means that multiple exceptions
+ can be caught here. If Desc is 0, it means all exceptions are caught
+ here. */
+__define_stab (N_CATCH, 0x54, "CATCH")
+
+/* Structure or union element. Value is offset in the structure. */
+__define_stab (N_SSYM, 0x60, "SSYM")
+
+/* Solaris2: Last stab emitted for module. */
+__define_stab (N_ENDM, 0x62, "ENDM")
+
+/* Name of main source file.
+ Value is starting text address of the compilation.
+ If multiple N_SO's appear, the first to contain a trailing / is the
+ compilation directory. The first to not contain a trailing / is the
+ source file name, relative to the compilation directory. Others (perhaps
+ resulting from cfront) are ignored.
+ On Solaris2, value is undefined, but desc is a source-language code. */
+
+__define_stab (N_SO, 0x64, "SO")
+
+/* Automatic variable in the stack. Value is offset from frame pointer.
+ Also used for type descriptions. */
+__define_stab (N_LSYM, 0x80, "LSYM")
+
+/* Beginning of an include file. Only Sun uses this.
+ In an object file, only the name is significant.
+ The Sun linker puts data into some of the other fields. */
+__define_stab (N_BINCL, 0x82, "BINCL")
+
+/* Name of sub-source file (#include file).
+ Value is starting text address of the compilation. */
+__define_stab (N_SOL, 0x84, "SOL")
+
+/* Parameter variable. Value is offset from argument pointer.
+ (On most machines the argument pointer is the same as the frame pointer. */
+__define_stab (N_PSYM, 0xa0, "PSYM")
+
+/* End of an include file. No name.
+ This and N_BINCL act as brackets around the file's output.
+ In an object file, there is no significant data in this entry.
+ The Sun linker puts data into some of the fields. */
+__define_stab (N_EINCL, 0xa2, "EINCL")
+
+/* Alternate entry point. Value is its address. */
+__define_stab (N_ENTRY, 0xa4, "ENTRY")
+
+/* Beginning of lexical block.
+ The desc is the nesting level in lexical blocks.
+ The value is the address of the start of the text for the block.
+ The variables declared inside the block *precede* the N_LBRAC symbol.
+ On Solaris2, the value is relative to the start of the current function. */
+__define_stab (N_LBRAC, 0xc0, "LBRAC")
+
+/* Place holder for deleted include file. Replaces a N_BINCL and everything
+ up to the corresponding N_EINCL. The Sun linker generates these when
+ it finds multiple identical copies of the symbols from an include file.
+ This appears only in output from the Sun linker. */
+__define_stab (N_EXCL, 0xc2, "EXCL")
+
+/* Modula-2 scope information. Can someone say what info it contains? */
+__define_stab (N_SCOPE, 0xc4, "SCOPE")
+
+/* End of a lexical block. Desc matches the N_LBRAC's desc.
+ The value is the address of the end of the text for the block.
+ On Solaris2, the value is relative to the start of the current function. */
+__define_stab (N_RBRAC, 0xe0, "RBRAC")
+
+/* Begin named common block. Only the name is significant. */
+__define_stab (N_BCOMM, 0xe2, "BCOMM")
+
+/* End named common block. Only the name is significant
+ (and it should match the N_BCOMM). */
+__define_stab (N_ECOMM, 0xe4, "ECOMM")
+
+/* Member of a common block; value is offset within the common block.
+ This should occur within a BCOMM/ECOMM pair. */
+__define_stab (N_ECOML, 0xe8, "ECOML")
+
+/* Solaris2: Pascal "with" statement: type,,0,0,offset */
+__define_stab (N_WITH, 0xea, "WITH")
+
+/* These STAB's are used on Gould systems for Non-Base register symbols
+ or something like that. FIXME. I have assigned the values at random
+ since I don't have a Gould here. Fixups from Gould folk welcome... */
+__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
+__define_stab (N_NBDATA, 0xF2, "NBDATA")
+__define_stab (N_NBBSS, 0xF4, "NBBSS")
+__define_stab (N_NBSTS, 0xF6, "NBSTS")
+__define_stab (N_NBLCS, 0xF8, "NBLCS")
+
+/* Second symbol entry containing a length-value for the preceding entry.
+ The value is the length. */
+__define_stab (N_LENG, 0xfe, "LENG")
+\f
+/* The above information, in matrix format.
+
+ STAB MATRIX
+ _________________________________________________
+ | 00 - 1F are not dbx stab symbols |
+ | In most cases, the low bit is the EXTernal bit|
+
+ | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA |
+ | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT |
+
+ | 08 BSS | 0A INDR | 0C FN_SEQ | 0E WEAKA |
+ | 09 |EXT | 0B | 0D WEAKU | 0F WEAKT |
+
+ | 10 WEAKD | 12 COMM | 14 SETA | 16 SETT |
+ | 11 WEAKB | 13 | 15 | 17 |
+
+ | 18 SETD | 1A SETB | 1C SETV | 1E WARNING|
+ | 19 | 1B | 1D | 1F FN |
+
+ |_______________________________________________|
+ | Debug entries with bit 01 set are unused. |
+ | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM |
+ | 28 LCSYM | 2A MAIN | 2C ROSYM | 2E |
+ | 30 PC | 32 NSYMS | 34 NOMAP | 36 |
+ | 38 OBJ | 3A | 3C OPT | 3E |
+ | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE |
+ | 48 BSLINE*| 4A DEFD | 4C FLINE | 4E |
+ | 50 EHDECL*| 52 | 54 CATCH | 56 |
+ | 58 | 5A | 5C | 5E |
+ | 60 SSYM | 62 ENDM | 64 SO | 66 |
+ | 68 | 6A | 6C | 6E |
+ | 70 | 72 | 74 | 76 |
+ | 78 | 7A | 7C | 7E |
+ | 80 LSYM | 82 BINCL | 84 SOL | 86 |
+ | 88 | 8A | 8C | 8E |
+ | 90 | 92 | 94 | 96 |
+ | 98 | 9A | 9C | 9E |
+ | A0 PSYM | A2 EINCL | A4 ENTRY | A6 |
+ | A8 | AA | AC | AE |
+ | B0 | B2 | B4 | B6 |
+ | B8 | BA | BC | BE |
+ | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 |
+ | C8 | CA | CC | CE |
+ | D0 | D2 | D4 | D6 |
+ | D8 | DA | DC | DE |
+ | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 |
+ | E8 ECOML | EA WITH | EC | EE |
+ | F0 | F2 | F4 | F6 |
+ | F8 | FA | FC | FE LENG |
+ +-----------------------------------------------+
+ * 50 EHDECL is also MOD2.
+ * 48 BSLINE is also BROWS.
+ */
--- /dev/null
+#ifndef __GNU_STAB__
+
+/* Indicate the GNU stab.h is in use. */
+
+#define __GNU_STAB__
+
+#define __define_stab(NAME, CODE, STRING) NAME=CODE,
+#define __define_stab_duplicate(NAME, CODE, STRING) NAME=CODE,
+
+enum __stab_debug_code
+{
+#include "stab.def"
+LAST_UNUSED_STAB_CODE
+};
+
+#undef __define_stab
+
+/* Definitions of "desc" field for N_SO stabs in Solaris2. */
+
+#define N_SO_AS 1
+#define N_SO_C 2
+#define N_SO_ANSI_C 3
+#define N_SO_CC 4 /* C++ */
+#define N_SO_FORTRAN 5
+#define N_SO_PASCAL 6
+
+/* Solaris2: Floating point type values in basic types. */
+
+#define NF_NONE 0
+#define NF_SINGLE 1 /* IEEE 32-bit */
+#define NF_DOUBLE 2 /* IEEE 64-bit */
+#define NF_COMPLEX 3 /* Fortran complex */
+#define NF_COMPLEX16 4 /* Fortran double complex */
+#define NF_COMPLEX32 5 /* Fortran complex*16 */
+#define NF_LDOUBLE 6 /* Long double (whatever that is) */
+
+#endif /* __GNU_STAB_ */
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <io.h>
+
+//#include <winnt.h>
+#include <windows.h>
+#include <kefuncs.h>
+
+//#include <winnt.h>
+#include <sys/types.h>
+//#include <sys/wait.h>
+//#include <sys/ioctl.h>
+//#include <sys/signal.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+//#include <unistd.h>
+//#include <linux/unistd.h>
+
+#include "../../../../include/pe.h"
+#include "stab_gnu.h"
+//#include "retypes.h"
+//#include "terminal.h"
+//#include <termios.h>
+#include "../shared/shared.h"
+
+
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ termínal.c
+
+Abstract:
+
+ serial terminal for pICE headless mode
+
+Environment:
+
+ User mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 23-Jan-2001: created
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+#if 0 //ei not ready
+#include "stdinc.h"
+#include <curses.h>
+
+
+#define CONSOLE_WIDTH (80)
+#define CONSOLE_HEIGHT (25)
+
+USHORT major_version=0xFFFF,minor_version=0xFFFF,build_number=0xFFFF;
+
+USHORT g_attr = 0;
+
+USHORT usCurX,usCurY,xSize,ySize;
+
+USHORT foreground_color_map[]=
+{
+};
+
+USHORT background_color_map[]=
+{
+};
+
+
+int fd_comm;
+struct termios oldtio;
+
+//************************************************************************
+// CheckSum()
+//
+//************************************************************************
+UCHAR CheckSum(LPSTR p,ULONG Len)
+{
+ UCHAR ucCheckSum = 0;
+ ULONG i;
+ for(i=0;i<Len;i++)
+ {
+ ucCheckSum ^= *p++;
+ ucCheckSum += 1;
+ }
+
+ return ucCheckSum;
+}
+
+///************************************************************************
+// ReadByte()
+//
+///************************************************************************
+BOOLEAN ReadByte(PUCHAR pc)
+{
+ return (read(fd_comm,pc,1) > 0);
+}
+
+///************************************************************************
+// SendByte()
+//
+///************************************************************************
+BOOLEAN SendByte(UCHAR c)
+{
+ return (write(fd_comm,&c,1) > 0);
+}
+
+
+///************************************************************************
+// ReadPacket()
+//
+///************************************************************************
+PSERIAL_PACKET ReadPacket(void)
+{
+ ULONG i;
+ PSERIAL_PACKET p;
+ SERIAL_PACKET_HEADER header;
+ PUCHAR pHeaderRaw,pData;
+ char temp[256];
+ ULONG ulCheckSum;
+
+ // read a packet header
+ pHeaderRaw = (PUCHAR)&header;
+ for(i=0;i<sizeof(SERIAL_PACKET_HEADER);i++)
+ {
+// //printf("reading()\n");
+ if(! ReadByte(pHeaderRaw))
+ {
+ // //printf("no header byte read!\n");
+ return NULL;
+ }
+
+ pHeaderRaw++;
+ }
+
+ //printf("received header!\n");
+
+ ulCheckSum = header.packet_header_chksum;
+ header.packet_header_chksum = 0;
+
+ if(ulCheckSum != CheckSum((PUCHAR)&header,sizeof(SERIAL_PACKET_HEADER)) )
+ {
+ //printf("header checksum mismatch!\n");
+ tcflush(fd_comm, TCIFLUSH);
+ return NULL;
+ }
+
+ p = malloc(sizeof(SERIAL_PACKET_HEADER) + header.packet_size);
+ if(!p)
+ {
+ //printf("out of memory!\n");
+ return NULL;
+ }
+ PICE_memcpy(p,&header,sizeof(SERIAL_PACKET_HEADER));
+
+ sprintf(temp,"size %X chksum %x\n",header.packet_size,header.packet_chksum);
+ //printf(temp);
+
+ // read the attached data
+ pData = (PUCHAR)p + sizeof(header);
+ for(i=0;i<header.packet_size;i++)
+ {
+ if(! ReadByte(pData))
+ {
+ //printf("no data byte read!\n");
+ return NULL;
+ }
+
+ pData++;
+ }
+
+ //printf("received data!\n");
+
+ pData = (PUCHAR)p + sizeof(header);
+ if(header.packet_chksum != CheckSum(pData,header.packet_size))
+ {
+ free(p);
+ p = NULL;
+ //printf("data checksum mismatch!\n");
+ return NULL;
+ }
+
+ while(!SendByte(ACK));
+
+ return p;
+}
+
+///************************************************************************
+// SendPacket()
+//
+///************************************************************************
+BOOLEAN SendPacket(PSERIAL_PACKET p)
+{
+ return TRUE;
+}
+
+void DeletePacket(PSERIAL_PACKET p)
+{
+ free(p);
+}
+
+//************************************************************************
+// SetupSerial()
+//
+//************************************************************************
+BOOLEAN SetupSerial(ULONG port,ULONG baudrate)
+{
+ struct termios newtio;
+ char* ports[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2","/dev/ttyS3"};
+
+ /*
+ Open modem device for reading and writing and not as controlling tty
+ because we don't want to get killed if linenoise sends CTRL-C.
+ */
+ //printf("opening comm %s\n",ports[port-1]);
+ fd_comm = open(ports[port-1], O_RDWR | O_NOCTTY);
+ if (fd_comm <0)
+ {
+ perror(ports[port-1]);
+ exit(-1);
+ }
+
+ //printf("tcgetattr()\n");
+ tcgetattr(fd_comm,&oldtio); /* save current modem settings */
+
+ /*
+ Set bps rate and hardware flow control and 8n1 (8bit,no parity,1 stopbit).
+ Also don't hangup automatically and ignore modem status.
+ Finally enable receiving characters.
+ */
+ newtio.c_cflag = baudrate | CS8 | CLOCAL | CREAD;
+
+ /*
+ Ignore bytes with parity errors and make terminal raw and dumb.
+ */
+ newtio.c_iflag = IGNPAR;
+
+ /*
+ Raw output.
+ */
+ newtio.c_oflag = 0;
+
+ /*
+ Don't echo characters because if you connect to a host it or your
+ modem will echo characters for you. Don't generate signals.
+ */
+ newtio.c_lflag = 0;
+
+ /* blocking read until 1 char arrives */
+ newtio.c_cc[VMIN]=0;
+ newtio.c_cc[VTIME]=0;
+
+ /* now clean the modem line and activate the settings for modem */
+ //printf("tcflush()\n");
+ tcflush(fd_comm, TCIFLUSH);
+ //printf("tcsetattr()\n");
+ tcsetattr(fd_comm,TCSANOW,&newtio);
+
+ // NCURSES
+ initscr();
+ refresh();
+
+ return TRUE;
+}
+
+//************************************************************************
+// CloseSerial()
+//
+//************************************************************************
+void CloseSerial(void)
+{
+ // NCURSES
+ endwin();
+
+ tcsetattr(fd_comm,TCSANOW,&oldtio); /* save current modem settings */
+ close(fd_comm);
+}
+
+//************************************************************************
+// ClrLine()
+//
+//************************************************************************
+void ClrLine(UCHAR line)
+{
+ move(line,0);
+}
+
+//************************************************************************
+// InvertLine()
+//
+//************************************************************************
+void InvertLine(UCHAR line)
+{
+ move(line,0);
+}
+
+//************************************************************************
+// SetCursorPosition()
+//
+//************************************************************************
+void SetCursorPosition(USHORT x, USHORT y)
+{
+ move(y,x);
+}
+
+//************************************************************************
+// GetCursorPosition()
+//
+//************************************************************************
+void GetCursorPosition(PUSHORT px,PUSHORT py)
+{
+}
+
+//************************************************************************
+// SetCursorState()
+//
+//************************************************************************
+void SetCursorState(UCHAR c)
+{
+}
+
+
+//************************************************************************
+// Print()
+//
+//************************************************************************
+void Print(LPSTR p,USHORT x,USHORT y)
+{
+ // save the cursor pos
+ GetCursorPosition(&usCurX,&usCurY);
+
+ if(y<25)
+ {
+ SetCursorPosition(x,y);
+ refresh();
+
+ addstr(p);
+ refresh();
+ SetCursorPosition(usCurX,usCurY);
+ }
+}
+
+//************************************************************************
+// ProcessPacket()
+//
+//************************************************************************
+void ProcessPacket(PSERIAL_PACKET p)
+{
+ ULONG ulSize;
+ PSERIAL_DATA_PACKET pData;
+
+ pData = (PSERIAL_DATA_PACKET)((PUCHAR)p + sizeof(SERIAL_PACKET_HEADER));
+ ulSize = p->header.packet_size;
+
+ switch(pData->type)
+ {
+ case PACKET_TYPE_CONNECT:
+ {
+ PSERIAL_DATA_PACKET_CONNECT pDataConnect = (PSERIAL_DATA_PACKET_CONNECT)pData;
+ UCHAR i;
+
+ for(i=0;i<ySize;i++)
+ ClrLine(i);
+
+ SetCursorState(0);
+ SetCursorPosition(0,0);
+// ResizeConsole(hConsole,pDataConnect->xsize,pDataConnect->ysize);
+ xSize = pDataConnect->xsize;
+ ySize = pDataConnect->ysize;
+ }
+ break;
+ case PACKET_TYPE_CLRLINE:
+ {
+ PSERIAL_DATA_PACKET_CLRLINE pDataClrLine = (PSERIAL_DATA_PACKET_CLRLINE)pData;
+
+ ClrLine(pDataClrLine->line);
+ }
+ break;
+ case PACKET_TYPE_INVERTLINE:
+ {
+ PSERIAL_DATA_PACKET_INVERTLINE pDataInvertLine = (PSERIAL_DATA_PACKET_INVERTLINE)pData;
+
+ InvertLine(pDataInvertLine->line);
+ }
+ break;
+ case PACKET_TYPE_PRINT:
+ {
+ PSERIAL_DATA_PACKET_PRINT pDataPrint = (PSERIAL_DATA_PACKET_PRINT)pData;
+
+ Print(pDataPrint->string,pDataPrint->x,pDataPrint->y);
+ }
+ break;
+ case PACKET_TYPE_CURSOR:
+ {
+ PSERIAL_DATA_PACKET_CURSOR pDataCursor = (PSERIAL_DATA_PACKET_CURSOR)pData;
+
+ SetCursorPosition(pDataCursor->x,pDataCursor->y);
+ SetCursorState(pDataCursor->state);
+ }
+ break;
+ case PACKET_TYPE_POLL:
+ {
+ PSERIAL_DATA_PACKET_POLL pDataPoll= (PSERIAL_DATA_PACKET_POLL)pData;
+
+ if( (major_version != pDataPoll->major_version) ||
+ (minor_version != pDataPoll->minor_version) ||
+ (build_number != pDataPoll->build_number) )
+ {
+ major_version = pDataPoll->major_version;
+ minor_version = pDataPoll->minor_version;
+ build_number = pDataPoll->build_number;
+
+// SetAppTitle();
+ }
+
+ }
+ break;
+ default:
+ //printf("UNHANDLED\n");
+ break;
+ }
+}
+
+//************************************************************************
+// DebuggerShell()
+//
+//************************************************************************
+void DebuggerShell(void)
+{
+ PSERIAL_PACKET p;
+
+ //printf("DebuggerShell()\n");
+ for(;;)
+ {
+ p = ReadPacket();
+ if(p)
+ {
+ ProcessPacket(p);
+ DeletePacket(p);
+ }
+ else
+ {
+ usleep(100*1000);
+ }
+ }
+}
+#endif
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ termínal.h
+
+Abstract:
+
+ HEADER for terminal.c
+
+Environment:
+
+ User mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 23-Jan-2001: created
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+BOOLEAN SetupSerial(ULONG port,ULONG baudrate);
+void CloseSerial(void);
+
+
+void DebuggerShell(void);
--- /dev/null
+// this file is dynamically generated: DON'T TOUCH
+
+UCHAR cAnimation[192*11]={
+0x00, // 1
+0x00, // 2
+0x00, // 3
+0x00, // 4
+0x00, // 5
+0x00, // 6
+0x00, // 7
+0x00, // 8
+0x00, // 9
+0x00, // 10
+0x00, // 11
+0x00, // 12
+0x00, // 13
+0x00, // 14
+0x00, // 15
+0x00, // 16
+0x00, // 17
+0x00, // 18
+0x00, // 19
+0x00, // 20
+0x00, // 21
+0x00, // 22
+0x00, // 23
+0x00, // 24
+0x00, // 25
+0x00, // 26
+0x00, // 27
+0x00, // 28
+0x00, // 29
+0x00, // 30
+0x00, // 31
+0x00, // 32
+0x00, // 33
+0x00, // 34
+0x00, // 35
+0x00, // 36
+0x00, // 37
+0x00, // 38
+0x00, // 39
+0x00, // 40
+0x00, // 41
+0x00, // 42
+0x00, // 43
+0x00, // 44
+0x00, // 45
+0x00, // 46
+0x00, // 47
+0x00, // 48
+0x00, // 49
+0x00, // 50
+0x00, // 51
+0x00, // 52
+0x00, // 53
+0x00, // 54
+0x00, // 55
+0x00, // 56
+0x00, // 57
+0x00, // 58
+0x00, // 59
+0x00, // 60
+0x00, // 61
+0x00, // 62
+0x00, // 63
+0x00, // 64
+0x00, // 65
+0x00, // 66
+0x00, // 67
+0x80, // 68
+0x00, // 69
+0x00, // 70
+0x00, // 71
+0x00, // 72
+0x00, // 73
+0x00, // 74
+0x00, // 75
+0xc0, // 76
+0x00, // 77
+0x00, // 78
+0x00, // 79
+0x00, // 80
+0x00, // 81
+0x00, // 82
+0x03, // 83
+0x60, // 84
+0x00, // 85
+0x00, // 86
+0x00, // 87
+0x00, // 88
+0x00, // 89
+0x00, // 90
+0x01, // 91
+0xb8, // 92
+0x00, // 93
+0x00, // 94
+0x00, // 95
+0x00, // 96
+0x00, // 97
+0x00, // 98
+0x00, // 99
+0xfe, // 100
+0x00, // 101
+0x00, // 102
+0x00, // 103
+0x00, // 104
+0x00, // 105
+0x00, // 106
+0x00, // 107
+0x42, // 108
+0x00, // 109
+0x00, // 110
+0x00, // 111
+0x00, // 112
+0x00, // 113
+0x00, // 114
+0x00, // 115
+0x43, // 116
+0x80, // 117
+0x00, // 118
+0x00, // 119
+0x00, // 120
+0x00, // 121
+0x00, // 122
+0x00, // 123
+0x76, // 124
+0xc0, // 125
+0x00, // 126
+0x00, // 127
+0x00, // 128
+0x00, // 129
+0x00, // 130
+0x02, // 131
+0x3c, // 132
+0x60, // 133
+0x00, // 134
+0x00, // 135
+0x00, // 136
+0x00, // 137
+0x00, // 138
+0x03, // 139
+0xf0, // 140
+0x20, // 141
+0x00, // 142
+0x00, // 143
+0x00, // 144
+0x00, // 145
+0x00, // 146
+0x00, // 147
+0x10, // 148
+0x20, // 149
+0x00, // 150
+0x00, // 151
+0x00, // 152
+0x00, // 153
+0x00, // 154
+0x00, // 155
+0xf8, // 156
+0x20, // 157
+0x00, // 158
+0x00, // 159
+0x00, // 160
+0x00, // 161
+0x00, // 162
+0x00, // 163
+0x1c, // 164
+0x20, // 165
+0x00, // 166
+0x00, // 167
+0x00, // 168
+0x00, // 169
+0x00, // 170
+0x00, // 171
+0x07, // 172
+0xe0, // 173
+0x00, // 174
+0x00, // 175
+0x00, // 176
+0x00, // 177
+0x00, // 178
+0x00, // 179
+0x01, // 180
+0x80, // 181
+0x00, // 182
+0x00, // 183
+0x00, // 184
+0x00, // 185
+0x00, // 186
+0x00, // 187
+0x07, // 188
+0x80, // 189
+0x00, // 190
+0x00, // 191
+0x00, // 192
+0x00, // 2
+0x00, // 4
+0x00, // 6
+0x00, // 8
+0x00, // 10
+0x00, // 12
+0x00, // 14
+0x00, // 16
+0x00, // 18
+0x00, // 20
+0x00, // 22
+0x00, // 24
+0x00, // 26
+0x00, // 28
+0x00, // 30
+0x00, // 32
+0x00, // 34
+0x00, // 36
+0x00, // 38
+0x00, // 40
+0x00, // 42
+0x00, // 44
+0x00, // 46
+0x00, // 48
+0x00, // 50
+0x00, // 52
+0x00, // 54
+0x00, // 56
+0x00, // 58
+0x00, // 60
+0x00, // 62
+0x00, // 64
+0x00, // 66
+0x00, // 68
+0x00, // 70
+0x00, // 72
+0x00, // 74
+0x00, // 76
+0x00, // 78
+0x00, // 80
+0x00, // 82
+0x00, // 84
+0x00, // 86
+0x00, // 88
+0x00, // 90
+0x00, // 92
+0x00, // 94
+0x00, // 96
+0x00, // 98
+0x00, // 100
+0x00, // 102
+0x00, // 104
+0x00, // 106
+0x00, // 108
+0x00, // 110
+0x00, // 112
+0x00, // 114
+0x00, // 116
+0x00, // 118
+0x00, // 120
+0x00, // 122
+0x00, // 124
+0x00, // 126
+0x00, // 128
+0x00, // 130
+0x00, // 132
+0x01, // 134
+0x10, // 136
+0x00, // 138
+0x00, // 140
+0x00, // 142
+0x00, // 144
+0x00, // 146
+0x00, // 148
+0x01, // 150
+0x90, // 152
+0x00, // 154
+0x00, // 156
+0x00, // 158
+0x00, // 160
+0x00, // 162
+0x00, // 164
+0x00, // 166
+0x90, // 168
+0x00, // 170
+0x00, // 172
+0x00, // 174
+0x00, // 176
+0x00, // 178
+0x00, // 180
+0x00, // 182
+0x90, // 184
+0x00, // 186
+0x00, // 188
+0x00, // 190
+0x00, // 192
+0x00, // 194
+0x00, // 196
+0x00, // 198
+0xfe, // 200
+0x00, // 202
+0x00, // 204
+0x00, // 206
+0x00, // 208
+0x00, // 210
+0x00, // 212
+0x00, // 214
+0x42, // 216
+0x40, // 218
+0x00, // 220
+0x00, // 222
+0x00, // 224
+0x00, // 226
+0x00, // 228
+0x00, // 230
+0x43, // 232
+0xc0, // 234
+0x00, // 236
+0x00, // 238
+0x00, // 240
+0x00, // 242
+0x00, // 244
+0x00, // 246
+0x76, // 248
+0xc8, // 250
+0x00, // 252
+0x00, // 254
+0x00, // 256
+0x00, // 258
+0x00, // 260
+0x00, // 262
+0x3c, // 264
+0x78, // 266
+0x00, // 268
+0x00, // 270
+0x00, // 272
+0x00, // 274
+0x00, // 276
+0x01, // 278
+0xf0, // 280
+0x20, // 282
+0x00, // 284
+0x00, // 286
+0x00, // 288
+0x00, // 290
+0x00, // 292
+0x00, // 294
+0x10, // 296
+0x20, // 298
+0x00, // 300
+0x00, // 302
+0x00, // 304
+0x00, // 306
+0x00, // 308
+0x01, // 310
+0xf8, // 312
+0x20, // 314
+0x00, // 316
+0x00, // 318
+0x00, // 320
+0x00, // 322
+0x00, // 324
+0x03, // 326
+0x1c, // 328
+0x20, // 330
+0x00, // 332
+0x00, // 334
+0x00, // 336
+0x00, // 338
+0x00, // 340
+0x00, // 342
+0x07, // 344
+0xe0, // 346
+0x00, // 348
+0x00, // 350
+0x00, // 352
+0x00, // 354
+0x00, // 356
+0x00, // 358
+0x01, // 360
+0x80, // 362
+0x00, // 364
+0x00, // 366
+0x00, // 368
+0x00, // 370
+0x00, // 372
+0x00, // 374
+0x07, // 376
+0x80, // 378
+0x00, // 380
+0x00, // 382
+0x00, // 384
+0x00, // 3
+0x00, // 6
+0x00, // 9
+0x00, // 12
+0x00, // 15
+0x00, // 18
+0x00, // 21
+0x00, // 24
+0x00, // 27
+0x00, // 30
+0x00, // 33
+0x00, // 36
+0x00, // 39
+0x00, // 42
+0x00, // 45
+0x00, // 48
+0x00, // 51
+0x00, // 54
+0x00, // 57
+0x00, // 60
+0x00, // 63
+0x00, // 66
+0x00, // 69
+0x00, // 72
+0x00, // 75
+0x00, // 78
+0x00, // 81
+0x00, // 84
+0x00, // 87
+0x00, // 90
+0x00, // 93
+0x00, // 96
+0x00, // 99
+0x00, // 102
+0x00, // 105
+0x00, // 108
+0x00, // 111
+0x00, // 114
+0x00, // 117
+0x00, // 120
+0x00, // 123
+0x00, // 126
+0x00, // 129
+0x00, // 132
+0x00, // 135
+0x00, // 138
+0x00, // 141
+0x00, // 144
+0x00, // 147
+0x00, // 150
+0x00, // 153
+0x00, // 156
+0x00, // 159
+0x00, // 162
+0x00, // 165
+0x00, // 168
+0x00, // 171
+0x00, // 174
+0x00, // 177
+0x08, // 180
+0x00, // 183
+0x00, // 186
+0x00, // 189
+0x00, // 192
+0x00, // 195
+0x00, // 198
+0x00, // 201
+0x08, // 204
+0x00, // 207
+0x00, // 210
+0x00, // 213
+0x00, // 216
+0x00, // 219
+0x00, // 222
+0x00, // 225
+0x88, // 228
+0x00, // 231
+0x00, // 234
+0x00, // 237
+0x00, // 240
+0x00, // 243
+0x00, // 246
+0x00, // 249
+0x88, // 252
+0x00, // 255
+0x00, // 258
+0x00, // 261
+0x00, // 264
+0x00, // 267
+0x00, // 270
+0x00, // 273
+0x8e, // 276
+0x00, // 279
+0x00, // 282
+0x00, // 285
+0x00, // 288
+0x00, // 291
+0x00, // 294
+0x00, // 297
+0xdb, // 300
+0x00, // 303
+0x00, // 306
+0x00, // 309
+0x00, // 312
+0x00, // 315
+0x00, // 318
+0x00, // 321
+0x71, // 324
+0x10, // 327
+0x00, // 330
+0x00, // 333
+0x00, // 336
+0x00, // 339
+0x00, // 342
+0x00, // 345
+0x23, // 348
+0xb0, // 351
+0x00, // 354
+0x00, // 357
+0x00, // 360
+0x00, // 363
+0x00, // 366
+0x00, // 369
+0x36, // 372
+0xc0, // 375
+0x00, // 378
+0x00, // 381
+0x00, // 384
+0x00, // 387
+0x00, // 390
+0x00, // 393
+0x3c, // 396
+0x6c, // 399
+0x00, // 402
+0x00, // 405
+0x00, // 408
+0x00, // 411
+0x00, // 414
+0x01, // 417
+0xf0, // 420
+0x38, // 423
+0x00, // 426
+0x00, // 429
+0x00, // 432
+0x00, // 435
+0x00, // 438
+0x03, // 441
+0x10, // 444
+0x30, // 447
+0x00, // 450
+0x00, // 453
+0x00, // 456
+0x00, // 459
+0x00, // 462
+0x06, // 465
+0x38, // 468
+0x10, // 471
+0x00, // 474
+0x00, // 477
+0x00, // 480
+0x00, // 483
+0x00, // 486
+0x04, // 489
+0x7c, // 492
+0x30, // 495
+0x00, // 498
+0x00, // 501
+0x00, // 504
+0x00, // 507
+0x00, // 510
+0x00, // 513
+0x46, // 516
+0x20, // 519
+0x00, // 522
+0x00, // 525
+0x00, // 528
+0x00, // 531
+0x00, // 534
+0x00, // 537
+0x01, // 540
+0xe0, // 543
+0x00, // 546
+0x00, // 549
+0x00, // 552
+0x00, // 555
+0x00, // 558
+0x00, // 561
+0x07, // 564
+0x80, // 567
+0x00, // 570
+0x00, // 573
+0x00, // 576
+0x00, // 4
+0x00, // 8
+0x00, // 12
+0x00, // 16
+0x00, // 20
+0x00, // 24
+0x00, // 28
+0x00, // 32
+0x00, // 36
+0x00, // 40
+0x00, // 44
+0x00, // 48
+0x00, // 52
+0x00, // 56
+0x00, // 60
+0x00, // 64
+0x00, // 68
+0x00, // 72
+0x00, // 76
+0x00, // 80
+0x00, // 84
+0x00, // 88
+0x00, // 92
+0x00, // 96
+0x00, // 100
+0x00, // 104
+0x00, // 108
+0x00, // 112
+0x00, // 116
+0x00, // 120
+0x00, // 124
+0x00, // 128
+0x00, // 132
+0x00, // 136
+0x00, // 140
+0x00, // 144
+0x00, // 148
+0x00, // 152
+0x00, // 156
+0x00, // 160
+0x00, // 164
+0x00, // 168
+0x00, // 172
+0x00, // 176
+0x00, // 180
+0x00, // 184
+0x00, // 188
+0x00, // 192
+0x00, // 196
+0x00, // 200
+0x00, // 204
+0x00, // 208
+0x00, // 212
+0x00, // 216
+0x00, // 220
+0x00, // 224
+0x00, // 228
+0x00, // 232
+0x00, // 236
+0x00, // 240
+0x00, // 244
+0x00, // 248
+0x00, // 252
+0x00, // 256
+0x00, // 260
+0x00, // 264
+0x01, // 268
+0x10, // 272
+0x00, // 276
+0x00, // 280
+0x00, // 284
+0x00, // 288
+0x00, // 292
+0x00, // 296
+0x01, // 300
+0x90, // 304
+0x00, // 308
+0x00, // 312
+0x00, // 316
+0x00, // 320
+0x00, // 324
+0x00, // 328
+0x00, // 332
+0x90, // 336
+0x00, // 340
+0x00, // 344
+0x00, // 348
+0x00, // 352
+0x00, // 356
+0x00, // 360
+0x00, // 364
+0x90, // 368
+0x00, // 372
+0x00, // 376
+0x00, // 380
+0x00, // 384
+0x00, // 388
+0x00, // 392
+0x00, // 396
+0xfe, // 400
+0x00, // 404
+0x00, // 408
+0x00, // 412
+0x00, // 416
+0x00, // 420
+0x00, // 424
+0x00, // 428
+0x42, // 432
+0x40, // 436
+0x00, // 440
+0x00, // 444
+0x00, // 448
+0x00, // 452
+0x00, // 456
+0x00, // 460
+0x43, // 464
+0xc0, // 468
+0x00, // 472
+0x00, // 476
+0x00, // 480
+0x00, // 484
+0x00, // 488
+0x00, // 492
+0x76, // 496
+0xc8, // 500
+0x00, // 504
+0x00, // 508
+0x00, // 512
+0x00, // 516
+0x00, // 520
+0x00, // 524
+0x3c, // 528
+0x78, // 532
+0x00, // 536
+0x00, // 540
+0x00, // 544
+0x00, // 548
+0x00, // 552
+0x01, // 556
+0xf0, // 560
+0x20, // 564
+0x00, // 568
+0x00, // 572
+0x00, // 576
+0x00, // 580
+0x00, // 584
+0x00, // 588
+0x10, // 592
+0x20, // 596
+0x00, // 600
+0x00, // 604
+0x00, // 608
+0x00, // 612
+0x00, // 616
+0x01, // 620
+0xf8, // 624
+0x20, // 628
+0x00, // 632
+0x00, // 636
+0x00, // 640
+0x00, // 644
+0x00, // 648
+0x03, // 652
+0x1c, // 656
+0x20, // 660
+0x00, // 664
+0x00, // 668
+0x00, // 672
+0x00, // 676
+0x00, // 680
+0x00, // 684
+0x07, // 688
+0xe0, // 692
+0x00, // 696
+0x00, // 700
+0x00, // 704
+0x00, // 708
+0x00, // 712
+0x00, // 716
+0x01, // 720
+0x80, // 724
+0x00, // 728
+0x00, // 732
+0x00, // 736
+0x00, // 740
+0x00, // 744
+0x00, // 748
+0x07, // 752
+0x80, // 756
+0x00, // 760
+0x00, // 764
+0x00, // 768
+0x00, // 5
+0x00, // 10
+0x00, // 15
+0x00, // 20
+0x00, // 25
+0x00, // 30
+0x00, // 35
+0x00, // 40
+0x00, // 45
+0x00, // 50
+0x00, // 55
+0x00, // 60
+0x00, // 65
+0x00, // 70
+0x00, // 75
+0x00, // 80
+0x00, // 85
+0x00, // 90
+0x00, // 95
+0x00, // 100
+0x00, // 105
+0x00, // 110
+0x00, // 115
+0x00, // 120
+0x00, // 125
+0x00, // 130
+0x00, // 135
+0x00, // 140
+0x00, // 145
+0x00, // 150
+0x00, // 155
+0x00, // 160
+0x00, // 165
+0x00, // 170
+0x00, // 175
+0x00, // 180
+0x00, // 185
+0x00, // 190
+0x00, // 195
+0x00, // 200
+0x00, // 205
+0x00, // 210
+0x00, // 215
+0x00, // 220
+0x00, // 225
+0x00, // 230
+0x00, // 235
+0x00, // 240
+0x00, // 245
+0x00, // 250
+0x00, // 255
+0x00, // 260
+0x00, // 265
+0x00, // 270
+0x00, // 275
+0x00, // 280
+0x00, // 285
+0x00, // 290
+0x00, // 295
+0x00, // 300
+0x00, // 305
+0x00, // 310
+0x00, // 315
+0x00, // 320
+0x00, // 325
+0x00, // 330
+0x00, // 335
+0x80, // 340
+0x00, // 345
+0x00, // 350
+0x00, // 355
+0x00, // 360
+0x00, // 365
+0x00, // 370
+0x00, // 375
+0xc0, // 380
+0x00, // 385
+0x00, // 390
+0x00, // 395
+0x00, // 400
+0x00, // 405
+0x00, // 410
+0x03, // 415
+0x60, // 420
+0x00, // 425
+0x00, // 430
+0x00, // 435
+0x00, // 440
+0x00, // 445
+0x00, // 450
+0x01, // 455
+0xb8, // 460
+0x00, // 465
+0x00, // 470
+0x00, // 475
+0x00, // 480
+0x00, // 485
+0x00, // 490
+0x00, // 495
+0xfe, // 500
+0x00, // 505
+0x00, // 510
+0x00, // 515
+0x00, // 520
+0x00, // 525
+0x00, // 530
+0x00, // 535
+0x42, // 540
+0x00, // 545
+0x00, // 550
+0x00, // 555
+0x00, // 560
+0x00, // 565
+0x00, // 570
+0x00, // 575
+0x43, // 580
+0x80, // 585
+0x00, // 590
+0x00, // 595
+0x00, // 600
+0x00, // 605
+0x00, // 610
+0x00, // 615
+0x76, // 620
+0xc0, // 625
+0x00, // 630
+0x00, // 635
+0x00, // 640
+0x00, // 645
+0x00, // 650
+0x02, // 655
+0x3c, // 660
+0x60, // 665
+0x00, // 670
+0x00, // 675
+0x00, // 680
+0x00, // 685
+0x00, // 690
+0x03, // 695
+0xf0, // 700
+0x20, // 705
+0x00, // 710
+0x00, // 715
+0x00, // 720
+0x00, // 725
+0x00, // 730
+0x00, // 735
+0x10, // 740
+0x20, // 745
+0x00, // 750
+0x00, // 755
+0x00, // 760
+0x00, // 765
+0x00, // 770
+0x00, // 775
+0xf8, // 780
+0x20, // 785
+0x00, // 790
+0x00, // 795
+0x00, // 800
+0x00, // 805
+0x00, // 810
+0x00, // 815
+0x1c, // 820
+0x20, // 825
+0x00, // 830
+0x00, // 835
+0x00, // 840
+0x00, // 845
+0x00, // 850
+0x00, // 855
+0x07, // 860
+0xe0, // 865
+0x00, // 870
+0x00, // 875
+0x00, // 880
+0x00, // 885
+0x00, // 890
+0x00, // 895
+0x01, // 900
+0x80, // 905
+0x00, // 910
+0x00, // 915
+0x00, // 920
+0x00, // 925
+0x00, // 930
+0x00, // 935
+0x07, // 940
+0x80, // 945
+0x00, // 950
+0x00, // 955
+0x00, // 960
+0x00, // 6
+0x00, // 12
+0x00, // 18
+0x00, // 24
+0x00, // 30
+0x00, // 36
+0x00, // 42
+0x00, // 48
+0x00, // 54
+0x00, // 60
+0x00, // 66
+0x00, // 72
+0x00, // 78
+0x00, // 84
+0x00, // 90
+0x00, // 96
+0x00, // 102
+0x00, // 108
+0x00, // 114
+0x00, // 120
+0x00, // 126
+0x00, // 132
+0x00, // 138
+0x00, // 144
+0x00, // 150
+0x00, // 156
+0x00, // 162
+0x00, // 168
+0x00, // 174
+0x00, // 180
+0x00, // 186
+0x00, // 192
+0x00, // 198
+0x00, // 204
+0x00, // 210
+0x00, // 216
+0x00, // 222
+0x00, // 228
+0x00, // 234
+0x00, // 240
+0x00, // 246
+0x00, // 252
+0x00, // 258
+0x00, // 264
+0x00, // 270
+0x00, // 276
+0x00, // 282
+0x00, // 288
+0x00, // 294
+0x00, // 300
+0x00, // 306
+0x00, // 312
+0x00, // 318
+0x00, // 324
+0x00, // 330
+0x00, // 336
+0x00, // 342
+0x00, // 348
+0x00, // 354
+0x08, // 360
+0x00, // 366
+0x00, // 372
+0x00, // 378
+0x00, // 384
+0x00, // 390
+0x00, // 396
+0x00, // 402
+0x08, // 408
+0x00, // 414
+0x00, // 420
+0x00, // 426
+0x00, // 432
+0x00, // 438
+0x00, // 444
+0x00, // 450
+0x88, // 456
+0x00, // 462
+0x00, // 468
+0x00, // 474
+0x00, // 480
+0x00, // 486
+0x00, // 492
+0x00, // 498
+0x88, // 504
+0x00, // 510
+0x00, // 516
+0x00, // 522
+0x00, // 528
+0x00, // 534
+0x00, // 540
+0x00, // 546
+0x8e, // 552
+0x00, // 558
+0x00, // 564
+0x00, // 570
+0x00, // 576
+0x00, // 582
+0x00, // 588
+0x00, // 594
+0xdb, // 600
+0x00, // 606
+0x00, // 612
+0x00, // 618
+0x00, // 624
+0x00, // 630
+0x00, // 636
+0x00, // 642
+0x71, // 648
+0x10, // 654
+0x00, // 660
+0x00, // 666
+0x00, // 672
+0x00, // 678
+0x00, // 684
+0x00, // 690
+0x23, // 696
+0xb0, // 702
+0x00, // 708
+0x00, // 714
+0x00, // 720
+0x00, // 726
+0x00, // 732
+0x00, // 738
+0x36, // 744
+0xc0, // 750
+0x00, // 756
+0x00, // 762
+0x00, // 768
+0x00, // 774
+0x00, // 780
+0x00, // 786
+0x3c, // 792
+0x6c, // 798
+0x00, // 804
+0x00, // 810
+0x00, // 816
+0x00, // 822
+0x00, // 828
+0x01, // 834
+0xf0, // 840
+0x38, // 846
+0x00, // 852
+0x00, // 858
+0x00, // 864
+0x00, // 870
+0x00, // 876
+0x03, // 882
+0x10, // 888
+0x30, // 894
+0x00, // 900
+0x00, // 906
+0x00, // 912
+0x00, // 918
+0x00, // 924
+0x06, // 930
+0x38, // 936
+0x10, // 942
+0x00, // 948
+0x00, // 954
+0x00, // 960
+0x00, // 966
+0x00, // 972
+0x04, // 978
+0x7c, // 984
+0x30, // 990
+0x00, // 996
+0x00, // 1002
+0x00, // 1008
+0x00, // 1014
+0x00, // 1020
+0x00, // 1026
+0x46, // 1032
+0x20, // 1038
+0x00, // 1044
+0x00, // 1050
+0x00, // 1056
+0x00, // 1062
+0x00, // 1068
+0x00, // 1074
+0x01, // 1080
+0xe0, // 1086
+0x00, // 1092
+0x00, // 1098
+0x00, // 1104
+0x00, // 1110
+0x00, // 1116
+0x00, // 1122
+0x07, // 1128
+0x80, // 1134
+0x00, // 1140
+0x00, // 1146
+0x00, // 1152
+0x00, // 7
+0x00, // 14
+0x00, // 21
+0x00, // 28
+0x00, // 35
+0x00, // 42
+0x00, // 49
+0x00, // 56
+0x00, // 63
+0x00, // 70
+0x00, // 77
+0x00, // 84
+0x00, // 91
+0x00, // 98
+0x00, // 105
+0x00, // 112
+0x00, // 119
+0x00, // 126
+0x00, // 133
+0x00, // 140
+0x00, // 147
+0x00, // 154
+0x00, // 161
+0x00, // 168
+0x00, // 175
+0x00, // 182
+0x00, // 189
+0x00, // 196
+0x00, // 203
+0x00, // 210
+0x00, // 217
+0x00, // 224
+0x00, // 231
+0x00, // 238
+0x00, // 245
+0x00, // 252
+0x00, // 259
+0x00, // 266
+0x00, // 273
+0x00, // 280
+0x00, // 287
+0x00, // 294
+0x00, // 301
+0x01, // 308
+0x00, // 315
+0x00, // 322
+0x00, // 329
+0x00, // 336
+0x00, // 343
+0x00, // 350
+0x00, // 357
+0x21, // 364
+0x00, // 371
+0x00, // 378
+0x00, // 385
+0x00, // 392
+0x00, // 399
+0x00, // 406
+0x00, // 413
+0x23, // 420
+0x00, // 427
+0x00, // 434
+0x00, // 441
+0x00, // 448
+0x00, // 455
+0x00, // 462
+0x00, // 469
+0x22, // 476
+0x00, // 483
+0x00, // 490
+0x00, // 497
+0x00, // 504
+0x00, // 511
+0x00, // 518
+0x00, // 525
+0x22, // 532
+0x00, // 539
+0x00, // 546
+0x00, // 553
+0x00, // 560
+0x00, // 567
+0x00, // 574
+0x00, // 581
+0x33, // 588
+0x00, // 595
+0x00, // 602
+0x00, // 609
+0x00, // 616
+0x00, // 623
+0x00, // 630
+0x00, // 637
+0x1f, // 644
+0x80, // 651
+0x00, // 658
+0x00, // 665
+0x00, // 672
+0x00, // 679
+0x00, // 686
+0x00, // 693
+0x08, // 700
+0x80, // 707
+0x00, // 714
+0x00, // 721
+0x00, // 728
+0x00, // 735
+0x00, // 742
+0x00, // 749
+0x08, // 756
+0x88, // 763
+0x00, // 770
+0x00, // 777
+0x00, // 784
+0x00, // 791
+0x00, // 798
+0x00, // 805
+0x09, // 812
+0x98, // 819
+0x00, // 826
+0x00, // 833
+0x00, // 840
+0x00, // 847
+0x00, // 854
+0x00, // 861
+0x0f, // 868
+0xf0, // 875
+0x00, // 882
+0x00, // 889
+0x00, // 896
+0x00, // 903
+0x00, // 910
+0x00, // 917
+0x0c, // 924
+0x20, // 931
+0x00, // 938
+0x00, // 945
+0x00, // 952
+0x00, // 959
+0x00, // 966
+0x0f, // 973
+0xf8, // 980
+0x30, // 987
+0x00, // 994
+0x00, // 1001
+0x00, // 1008
+0x00, // 1015
+0x00, // 1022
+0x00, // 1029
+0x08, // 1036
+0x1f, // 1043
+0x80, // 1050
+0x00, // 1057
+0x00, // 1064
+0x00, // 1071
+0x00, // 1078
+0x00, // 1085
+0x1c, // 1092
+0x10, // 1099
+0x00, // 1106
+0x00, // 1113
+0x00, // 1120
+0x00, // 1127
+0x00, // 1134
+0x00, // 1141
+0xf6, // 1148
+0x30, // 1155
+0x00, // 1162
+0x00, // 1169
+0x00, // 1176
+0x00, // 1183
+0x00, // 1190
+0x00, // 1197
+0x83, // 1204
+0x60, // 1211
+0x00, // 1218
+0x00, // 1225
+0x00, // 1232
+0x00, // 1239
+0x00, // 1246
+0x00, // 1253
+0x01, // 1260
+0xc0, // 1267
+0x00, // 1274
+0x00, // 1281
+0x00, // 1288
+0x00, // 1295
+0x00, // 1302
+0x00, // 1309
+0x03, // 1316
+0xe0, // 1323
+0x00, // 1330
+0x00, // 1337
+0x00, // 1344
+0x00, // 8
+0x00, // 16
+0x00, // 24
+0x00, // 32
+0x00, // 40
+0x00, // 48
+0x00, // 56
+0x00, // 64
+0x00, // 72
+0x00, // 80
+0x00, // 88
+0x00, // 96
+0x00, // 104
+0x00, // 112
+0x00, // 120
+0x00, // 128
+0x00, // 136
+0x00, // 144
+0x00, // 152
+0x00, // 160
+0x00, // 168
+0x00, // 176
+0x00, // 184
+0x00, // 192
+0x00, // 200
+0x00, // 208
+0x00, // 216
+0x00, // 224
+0x00, // 232
+0x00, // 240
+0x00, // 248
+0x00, // 256
+0x00, // 264
+0x00, // 272
+0x00, // 280
+0x00, // 288
+0x00, // 296
+0x00, // 304
+0x00, // 312
+0x00, // 320
+0x00, // 328
+0x00, // 336
+0x00, // 344
+0x00, // 352
+0x00, // 360
+0x00, // 368
+0x00, // 376
+0x00, // 384
+0x00, // 392
+0x00, // 400
+0x00, // 408
+0x00, // 416
+0x00, // 424
+0x00, // 432
+0x00, // 440
+0x00, // 448
+0x00, // 456
+0x00, // 464
+0x00, // 472
+0x00, // 480
+0x00, // 488
+0x00, // 496
+0x00, // 504
+0x00, // 512
+0x00, // 520
+0x00, // 528
+0x00, // 536
+0x00, // 544
+0x0c, // 552
+0x00, // 560
+0x00, // 568
+0x00, // 576
+0x00, // 584
+0x00, // 592
+0x00, // 600
+0x06, // 608
+0x18, // 616
+0x00, // 624
+0x00, // 632
+0x00, // 640
+0x00, // 648
+0x00, // 656
+0x00, // 664
+0x03, // 672
+0x30, // 680
+0x00, // 688
+0x00, // 696
+0x00, // 704
+0x00, // 712
+0x00, // 720
+0x00, // 728
+0x01, // 736
+0xe0, // 744
+0x00, // 752
+0x00, // 760
+0x00, // 768
+0x00, // 776
+0x00, // 784
+0x00, // 792
+0x01, // 800
+0x20, // 808
+0x00, // 816
+0x00, // 824
+0x00, // 832
+0x00, // 840
+0x00, // 848
+0x00, // 856
+0x01, // 864
+0x20, // 872
+0x00, // 880
+0x00, // 888
+0x00, // 896
+0x00, // 904
+0x00, // 912
+0x00, // 920
+0x01, // 928
+0xe0, // 936
+0x00, // 944
+0x00, // 952
+0x00, // 960
+0x00, // 968
+0x00, // 976
+0x00, // 984
+0x3d, // 992
+0xb9, // 1000
+0x80, // 1008
+0x00, // 1016
+0x00, // 1024
+0x00, // 1032
+0x00, // 1040
+0x00, // 1048
+0x07, // 1056
+0x0f, // 1064
+0x00, // 1072
+0x00, // 1080
+0x00, // 1088
+0x00, // 1096
+0x00, // 1104
+0x00, // 1112
+0x02, // 1120
+0x08, // 1128
+0x00, // 1136
+0x00, // 1144
+0x00, // 1152
+0x00, // 1160
+0x00, // 1168
+0x00, // 1176
+0x02, // 1184
+0x0b, // 1192
+0x80, // 1200
+0x00, // 1208
+0x00, // 1216
+0x00, // 1224
+0x00, // 1232
+0x00, // 1240
+0x3f, // 1248
+0x1e, // 1256
+0x00, // 1264
+0x00, // 1272
+0x00, // 1280
+0x00, // 1288
+0x00, // 1296
+0x00, // 1304
+0x01, // 1312
+0x10, // 1320
+0x00, // 1328
+0x00, // 1336
+0x00, // 1344
+0x00, // 1352
+0x00, // 1360
+0x00, // 1368
+0x01, // 1376
+0xe0, // 1384
+0x00, // 1392
+0x00, // 1400
+0x00, // 1408
+0x00, // 1416
+0x00, // 1424
+0x00, // 1432
+0x00, // 1440
+0xf0, // 1448
+0x00, // 1456
+0x00, // 1464
+0x00, // 1472
+0x00, // 1480
+0x00, // 1488
+0x00, // 1496
+0x01, // 1504
+0x98, // 1512
+0x00, // 1520
+0x00, // 1528
+0x00, // 1536
+0x00, // 9
+0x00, // 18
+0x00, // 27
+0x01, // 36
+0xff, // 45
+0xc0, // 54
+0x00, // 63
+0x00, // 72
+0x00, // 81
+0x00, // 90
+0x00, // 99
+0x00, // 108
+0xff, // 117
+0x80, // 126
+0x00, // 135
+0x00, // 144
+0x00, // 153
+0x00, // 162
+0x00, // 171
+0x00, // 180
+0x3f, // 189
+0x80, // 198
+0x00, // 207
+0x00, // 216
+0x00, // 225
+0x00, // 234
+0x00, // 243
+0x00, // 252
+0x01, // 261
+0x80, // 270
+0x00, // 279
+0x00, // 288
+0x00, // 297
+0x00, // 306
+0x00, // 315
+0x00, // 324
+0x00, // 333
+0x00, // 342
+0x00, // 351
+0x00, // 360
+0x00, // 369
+0x00, // 378
+0x00, // 387
+0x00, // 396
+0x00, // 405
+0x00, // 414
+0x00, // 423
+0x00, // 432
+0x00, // 441
+0x00, // 450
+0x00, // 459
+0x00, // 468
+0x00, // 477
+0x00, // 486
+0x00, // 495
+0x00, // 504
+0x00, // 513
+0x00, // 522
+0x00, // 531
+0x00, // 540
+0x00, // 549
+0x00, // 558
+0x00, // 567
+0x00, // 576
+0x00, // 585
+0x00, // 594
+0x00, // 603
+0x00, // 612
+0x0c, // 621
+0x00, // 630
+0x00, // 639
+0x00, // 648
+0x00, // 657
+0x00, // 666
+0x00, // 675
+0x06, // 684
+0x18, // 693
+0x00, // 702
+0x00, // 711
+0x00, // 720
+0x00, // 729
+0x00, // 738
+0x00, // 747
+0x03, // 756
+0x30, // 765
+0x00, // 774
+0x00, // 783
+0x00, // 792
+0x00, // 801
+0x00, // 810
+0x00, // 819
+0x01, // 828
+0xe0, // 837
+0x00, // 846
+0x00, // 855
+0x00, // 864
+0x00, // 873
+0x00, // 882
+0x00, // 891
+0x01, // 900
+0x20, // 909
+0x00, // 918
+0x00, // 927
+0x00, // 936
+0x00, // 945
+0x00, // 954
+0x00, // 963
+0x01, // 972
+0x20, // 981
+0x00, // 990
+0x00, // 999
+0x00, // 1008
+0x00, // 1017
+0x00, // 1026
+0x00, // 1035
+0x01, // 1044
+0xe0, // 1053
+0x00, // 1062
+0x00, // 1071
+0x00, // 1080
+0x00, // 1089
+0x00, // 1098
+0x00, // 1107
+0x3d, // 1116
+0xb9, // 1125
+0x80, // 1134
+0x00, // 1143
+0x00, // 1152
+0x00, // 1161
+0x00, // 1170
+0x00, // 1179
+0x07, // 1188
+0x0f, // 1197
+0x00, // 1206
+0x00, // 1215
+0x00, // 1224
+0x00, // 1233
+0x00, // 1242
+0x00, // 1251
+0x02, // 1260
+0x08, // 1269
+0x00, // 1278
+0x00, // 1287
+0x00, // 1296
+0x00, // 1305
+0x00, // 1314
+0x00, // 1323
+0x02, // 1332
+0x0b, // 1341
+0x80, // 1350
+0x00, // 1359
+0x00, // 1368
+0x00, // 1377
+0x00, // 1386
+0x00, // 1395
+0x3f, // 1404
+0x1e, // 1413
+0x00, // 1422
+0x00, // 1431
+0x00, // 1440
+0x00, // 1449
+0x00, // 1458
+0x00, // 1467
+0x01, // 1476
+0x10, // 1485
+0x00, // 1494
+0x00, // 1503
+0x00, // 1512
+0x00, // 1521
+0x00, // 1530
+0x00, // 1539
+0x01, // 1548
+0xe0, // 1557
+0x00, // 1566
+0x00, // 1575
+0x00, // 1584
+0x00, // 1593
+0x00, // 1602
+0x00, // 1611
+0x00, // 1620
+0xf0, // 1629
+0x00, // 1638
+0x00, // 1647
+0x00, // 1656
+0x00, // 1665
+0x00, // 1674
+0x00, // 1683
+0x01, // 1692
+0x98, // 1701
+0x00, // 1710
+0x00, // 1719
+0x00, // 1728
+0x00, // 10
+0x00, // 20
+0x00, // 30
+0x0f, // 40
+0xfe, // 50
+0x00, // 60
+0x00, // 70
+0x00, // 80
+0x00, // 90
+0x00, // 100
+0x00, // 110
+0x0f, // 120
+0xff, // 130
+0xc0, // 140
+0x00, // 150
+0x00, // 160
+0x00, // 170
+0x00, // 180
+0x00, // 190
+0x1f, // 200
+0xff, // 210
+0xc0, // 220
+0x00, // 230
+0x00, // 240
+0x00, // 250
+0x00, // 260
+0x00, // 270
+0x1f, // 280
+0xff, // 290
+0x80, // 300
+0x00, // 310
+0x00, // 320
+0x00, // 330
+0x00, // 340
+0x00, // 350
+0x1f, // 360
+0xff, // 370
+0x80, // 380
+0x00, // 390
+0x00, // 400
+0x00, // 410
+0x00, // 420
+0x00, // 430
+0x1f, // 440
+0xff, // 450
+0x80, // 460
+0x00, // 470
+0x00, // 480
+0x00, // 490
+0x00, // 500
+0x00, // 510
+0x3f, // 520
+0xff, // 530
+0x80, // 540
+0x00, // 550
+0x00, // 560
+0x00, // 570
+0x00, // 580
+0x00, // 590
+0x3f, // 600
+0xff, // 610
+0xff, // 620
+0xff, // 630
+0xf8, // 640
+0x00, // 650
+0x00, // 660
+0x00, // 670
+0x3f, // 680
+0xff, // 690
+0x80, // 700
+0x00, // 710
+0x08, // 720
+0x00, // 730
+0x00, // 740
+0x00, // 750
+0x3f, // 760
+0xff, // 770
+0x80, // 780
+0x00, // 790
+0x08, // 800
+0x00, // 810
+0x00, // 820
+0x00, // 830
+0x3f, // 840
+0xff, // 850
+0x80, // 860
+0x7f, // 870
+0xf8, // 880
+0x00, // 890
+0x00, // 900
+0x00, // 910
+0x3f, // 920
+0xff, // 930
+0xff, // 940
+0xc0, // 950
+0x00, // 960
+0x00, // 970
+0x00, // 980
+0x00, // 990
+0x3f, // 1000
+0xff, // 1010
+0x80, // 1020
+0x00, // 1030
+0x00, // 1040
+0x00, // 1050
+0x00, // 1060
+0x00, // 1070
+0x3f, // 1080
+0xff, // 1090
+0x80, // 1100
+0x00, // 1110
+0x00, // 1120
+0x00, // 1130
+0x00, // 1140
+0x00, // 1150
+0x3f, // 1160
+0xff, // 1170
+0x80, // 1180
+0x00, // 1190
+0x00, // 1200
+0x00, // 1210
+0x00, // 1220
+0x00, // 1230
+0x3f, // 1240
+0xff, // 1250
+0x80, // 1260
+0x00, // 1270
+0x00, // 1280
+0x00, // 1290
+0x00, // 1300
+0x00, // 1310
+0x3f, // 1320
+0xff, // 1330
+0x80, // 1340
+0x00, // 1350
+0x00, // 1360
+0x00, // 1370
+0x00, // 1380
+0x00, // 1390
+0x3f, // 1400
+0xff, // 1410
+0x80, // 1420
+0x00, // 1430
+0x00, // 1440
+0x00, // 1450
+0x00, // 1460
+0x00, // 1470
+0x03, // 1480
+0xfb, // 1490
+0x80, // 1500
+0x00, // 1510
+0x00, // 1520
+0x00, // 1530
+0x00, // 1540
+0x00, // 1550
+0x3f, // 1560
+0x1e, // 1570
+0x00, // 1580
+0x00, // 1590
+0x00, // 1600
+0x00, // 1610
+0x00, // 1620
+0x1c, // 1630
+0x01, // 1640
+0x10, // 1650
+0x7c, // 1660
+0x00, // 1670
+0x00, // 1680
+0x00, // 1690
+0x00, // 1700
+0x10, // 1710
+0x01, // 1720
+0xe0, // 1730
+0x0c, // 1740
+0x00, // 1750
+0x00, // 1760
+0x00, // 1770
+0x00, // 1780
+0x00, // 1790
+0x00, // 1800
+0xf0, // 1810
+0x00, // 1820
+0x80, // 1830
+0x00, // 1840
+0x00, // 1850
+0x00, // 1860
+0x00, // 1870
+0x01, // 1880
+0x98, // 1890
+0x00, // 1900
+0x00, // 1910
+0x00, // 1920
+0x00, // 11
+0x00, // 22
+0x00, // 33
+0x07, // 44
+0xfe, // 55
+0x00, // 66
+0x00, // 77
+0x00, // 88
+0x00, // 99
+0x00, // 110
+0x00, // 121
+0x3f, // 132
+0xff, // 143
+0x80, // 154
+0x00, // 165
+0x00, // 176
+0x00, // 187
+0x00, // 198
+0x00, // 209
+0x3f, // 220
+0xff, // 231
+0xc0, // 242
+0x00, // 253
+0x00, // 264
+0x00, // 275
+0x00, // 286
+0x00, // 297
+0x3f, // 308
+0xff, // 319
+0xc0, // 330
+0x00, // 341
+0x00, // 352
+0x00, // 363
+0x00, // 374
+0x00, // 385
+0x3f, // 396
+0xff, // 407
+0xc0, // 418
+0x00, // 429
+0x00, // 440
+0x00, // 451
+0x00, // 462
+0x00, // 473
+0x3f, // 484
+0xff, // 495
+0xc0, // 506
+0x00, // 517
+0x00, // 528
+0x00, // 539
+0x00, // 550
+0x00, // 561
+0x7f, // 572
+0xff, // 583
+0xc0, // 594
+0x00, // 605
+0x00, // 616
+0x00, // 627
+0x00, // 638
+0x00, // 649
+0x7f, // 660
+0xff, // 671
+0xc0, // 682
+0x01, // 693
+0xf8, // 704
+0x00, // 715
+0x00, // 726
+0x00, // 737
+0x7f, // 748
+0xff, // 759
+0xc0, // 770
+0x1f, // 781
+0x0c, // 792
+0x00, // 803
+0x00, // 814
+0x00, // 825
+0x7f, // 836
+0xff, // 847
+0xc0, // 858
+0xf0, // 869
+0x0c, // 880
+0x00, // 891
+0x00, // 902
+0x00, // 913
+0x7f, // 924
+0xff, // 935
+0xff, // 946
+0x00, // 957
+0x38, // 968
+0x00, // 979
+0x00, // 990
+0x00, // 1001
+0x7f, // 1012
+0xff, // 1023
+0xe0, // 1034
+0x01, // 1045
+0xc0, // 1056
+0x00, // 1067
+0x00, // 1078
+0x00, // 1089
+0x3f, // 1100
+0xff, // 1111
+0xc0, // 1122
+0xff, // 1133
+0x00, // 1144
+0x00, // 1155
+0x00, // 1166
+0x00, // 1177
+0x3f, // 1188
+0xff, // 1199
+0xc7, // 1210
+0x80, // 1221
+0x00, // 1232
+0x00, // 1243
+0x00, // 1254
+0x00, // 1265
+0x3f, // 1276
+0xff, // 1287
+0xfc, // 1298
+0x00, // 1309
+0x00, // 1320
+0x00, // 1331
+0x00, // 1342
+0x00, // 1353
+0x3f, // 1364
+0xff, // 1375
+0xe0, // 1386
+0x00, // 1397
+0x00, // 1408
+0x00, // 1419
+0x00, // 1430
+0x00, // 1441
+0x3f, // 1452
+0xff, // 1463
+0xc0, // 1474
+0x00, // 1485
+0x00, // 1496
+0x00, // 1507
+0x00, // 1518
+0x00, // 1529
+0x3f, // 1540
+0xff, // 1551
+0x80, // 1562
+0x00, // 1573
+0x00, // 1584
+0x00, // 1595
+0x00, // 1606
+0x00, // 1617
+0x3f, // 1628
+0xff, // 1639
+0x80, // 1650
+0x00, // 1661
+0x00, // 1672
+0x00, // 1683
+0x00, // 1694
+0x00, // 1705
+0x3f, // 1716
+0xff, // 1727
+0x80, // 1738
+0x00, // 1749
+0x00, // 1760
+0x00, // 1771
+0x00, // 1782
+0x00, // 1793
+0x1f, // 1804
+0xff, // 1815
+0x80, // 1826
+0x00, // 1837
+0x00, // 1848
+0x00, // 1859
+0x00, // 1870
+0x00, // 1881
+0x1f, // 1892
+0xff, // 1903
+0x80, // 1914
+0x00, // 1925
+0x00, // 1936
+0x00, // 1947
+0x00, // 1958
+0x00, // 1969
+0x1f, // 1980
+0xff, // 1991
+0x80, // 2002
+0x00, // 2013
+0x00, // 2024
+0x00, // 2035
+0x00, // 2046
+0x5f, // 2057
+0x9f, // 2068
+0xff, // 2079
+0x9f, // 2090
+0x10, // 2101
+0x00, // 2112
+};
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ bp.c
+
+Abstract:
+
+ setting, listing and removing breakpoints
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 13-Nov-1999: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+
+////////////////////////////////////////////////////
+// GLOBALS
+////
+char tempBp[1024];
+
+ULONG OldInt3Handler=0;
+
+SW_BP aSwBreakpoints[64]={{0,0,0,0},};
+
+//*************************************************************************
+// FindSwBp()
+//
+//*************************************************************************
+PSW_BP FindSwBp(ULONG ulAddress)
+{
+ ULONG i;
+
+ for(i=0;i<DIM(aSwBreakpoints);i++)
+ {
+ if(aSwBreakpoints[i].ulAddress == ulAddress && aSwBreakpoints[i].bUsed==TRUE && aSwBreakpoints[i].bVirtual==FALSE)
+ return &aSwBreakpoints[i];
+ }
+
+ return NULL;
+}
+
+//*************************************************************************
+// FindEmptySwBpSlot()
+//
+//*************************************************************************
+PSW_BP FindEmptySwBpSlot(void)
+{
+ ULONG i;
+
+ for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
+ {
+ if(aSwBreakpoints[i].bUsed == FALSE)
+ {
+ return &aSwBreakpoints[i];
+ }
+ }
+
+ return NULL;
+}
+
+//*************************************************************************
+// FindVirtualSwBp()
+//
+//*************************************************************************
+PSW_BP FindVirtualSwBp(LPSTR ModName,LPSTR szFunctionName)
+{
+ ULONG i;
+ PSW_BP p;
+
+ for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
+ {
+ p = &aSwBreakpoints[i];
+
+ if(p->bUsed == TRUE &&
+ p->bVirtual == TRUE &&
+ PICE_strcmpi(p->szModName,ModName)==0 &&
+ PICE_strcmpi(p->szFunctionName,szFunctionName)==0)
+ {
+ return p;
+ }
+ }
+
+ return NULL;
+}
+
+//*************************************************************************
+// IsSwBpAtAddressInstalled()
+//
+//*************************************************************************
+BOOLEAN IsSwBpAtAddressInstalled(ULONG ulAddress)
+{
+ ULONG i;
+
+ for(i=0;i<DIM(aSwBreakpoints);i++)
+ {
+ if(aSwBreakpoints[i].ulAddress == ulAddress &&
+ aSwBreakpoints[i].bUsed == TRUE &&
+ aSwBreakpoints[i].bInstalled &&
+ aSwBreakpoints[i].bVirtual == FALSE)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//*************************************************************************
+// IsSwBpAtAddress()
+//
+//*************************************************************************
+BOOLEAN IsSwBpAtAddress(ULONG ulAddress)
+{
+ ULONG i;
+
+ for(i=0;i<DIM(aSwBreakpoints);i++)
+ {
+ if(aSwBreakpoints[i].ulAddress == ulAddress && aSwBreakpoints[i].bUsed==TRUE && aSwBreakpoints[i].bVirtual==FALSE)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//*************************************************************************
+// NeedToReInstallSWBreakpoints()
+//
+//*************************************************************************
+BOOLEAN NeedToReInstallSWBreakpoints(ULONG ulAddress,BOOLEAN bUseAddress)
+{
+ PSW_BP p;
+ BOOLEAN bResult = FALSE;
+ ULONG i;
+
+ ENTER_FUNC();
+ DPRINT((0,"NeedToReInstallSWBreakpoint() for %x (bUseAddress = %s)\n",ulAddress,bUseAddress?"TRUE":"FALSE"));
+
+ for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
+ {
+ p = &aSwBreakpoints[i];
+ if(bUseAddress)
+ {
+ if(p->bUsed == TRUE && p->bInstalled == FALSE && p->ulAddress==ulAddress && p->bVirtual==FALSE)
+ {
+ if(IsAddressValid(p->ulAddress))
+ {
+ DPRINT((0,"NeedToReInstallSWBreakpoint(): [1] found BP\n"));
+ bResult = TRUE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if(p->bUsed == TRUE && p->bInstalled == FALSE && p->bVirtual == FALSE)
+ {
+ if(IsAddressValid(p->ulAddress))
+ {
+ DPRINT((0,"NeedToReInstallSWBreakpoint(): [2] found BP\n"));
+ bResult = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+//*************************************************************************
+// ReInstallSWBreakpoint()
+//
+//*************************************************************************
+BOOLEAN ReInstallSWBreakpoint(ULONG ulAddress)
+{
+ PSW_BP p;
+ BOOLEAN bResult = FALSE;
+ ULONG i;
+
+ ENTER_FUNC();
+ DPRINT((0,"ReInstallSWBreakpoint()\n"));
+
+ for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
+ {
+ p = &aSwBreakpoints[i];
+ if(p->bUsed == TRUE && p->bInstalled == FALSE && p->ulAddress == ulAddress && p->bVirtual == FALSE)
+ {
+ if(IsAddressValid(p->ulAddress))
+ {
+ BOOLEAN isWriteable;
+
+ if( !( isWriteable = IsAddressWriteable(p->ulAddress) ) )
+ SetAddressWriteable(p->ulAddress,TRUE);
+ *(PUCHAR)(p->ulAddress) = 0xCC;
+ if( !isWriteable )
+ SetAddressWriteable(p->ulAddress,FALSE);
+ p->bInstalled = TRUE;
+ bResult = TRUE;
+ }
+ }
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+
+//*************************************************************************
+// InstallSWBreakpoint()
+//
+//*************************************************************************
+BOOLEAN InstallSWBreakpoint(ULONG ulAddress,BOOLEAN bPermanent,void (*SWBreakpointCallback)(void))
+{
+ PSW_BP p;
+ BOOLEAN bResult = FALSE;
+
+ ENTER_FUNC();
+ DPRINT((0,"InstallSWBreakpoint()\n"));
+
+ // check if page is present
+ // TODO: must also check if it's a writable page
+ if(IsAddressValid(ulAddress) )
+ {
+ DPRINT((0,"InstallSWBreakpoint(): %.8X is valid, writable? %d\n",ulAddress,IsAddressWriteable(ulAddress)));
+ DPRINT((0,"pde: %x, pte: %x\n", *(ADDR_TO_PDE(ulAddress)), *(ADDR_TO_PTE(ulAddress))));
+ if((p = FindSwBp(ulAddress))==NULL)
+ {
+ DPRINT((0,"InstallSWBreakpoint(): %.8X is free\n",ulAddress));
+ if( (p=FindEmptySwBpSlot()) )
+ {
+ BOOLEAN isWriteable;
+ DPRINT((0,"InstallSWBreakpoint(): found empty slot\n"));
+ DPRINT((0,"InstallSWBreakpoint(): %x value: %x", ulAddress, *(PUCHAR)ulAddress));
+ p->ucOriginalOpcode = *(PUCHAR)ulAddress;
+ //allow writing to page
+ if( !( isWriteable = IsAddressWriteable(ulAddress) ) )
+ SetAddressWriteable(ulAddress,TRUE);
+ DPRINT((0,"writing breakpoint\n"));
+ *(PUCHAR)ulAddress = 0xCC;
+ DPRINT((0,"restoring page access\n"));
+ if( !isWriteable )
+ SetAddressWriteable(ulAddress,FALSE);
+ p->bUsed = TRUE;
+ p->bInstalled = TRUE;
+ // find next address
+ p->ulAddress = ulAddress;
+ Disasm(&ulAddress,(PUCHAR)&tempBp);
+ p->ulNextInstr = ulAddress;
+ p->bPermanent = bPermanent;
+ if(bPermanent)
+ p->Callback = SWBreakpointCallback;
+ else
+ p->Callback = NULL;
+ bResult = TRUE;
+ }
+ }
+ else
+ {
+ DPRINT((0,"InstallSWBreakpoint(): %.8X is already used\n",ulAddress));
+ if(p->bPermanent)
+ {
+ DPRINT((0,"InstallSWBreakpoint(): %.8X is a permanent breakpoint\n",ulAddress));
+ }
+ }
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+//*************************************************************************
+// InstallVirtualSWBreakpoint()
+//
+//*************************************************************************
+BOOLEAN InstallVirtualSWBreakpoint(LPSTR ModName,LPSTR FunctionName)
+{
+ PSW_BP p;
+ BOOLEAN bResult = FALSE;
+
+ ENTER_FUNC();
+ DPRINT((0,"InstallVirtualSWBreakpoint(%s!%s)\n",ModName,FunctionName));
+
+ if( (p=FindEmptySwBpSlot()) )
+ {
+ DPRINT((0,"InstallVirtualSWBreakpoint(): found empty slot\n"));
+
+ p->bUsed = TRUE;
+ p->bInstalled = TRUE;
+ p->bVirtual = TRUE;
+ p->Callback = NULL;
+ PICE_strcpy(p->szModName,ModName);
+ PICE_strcpy(p->szFunctionName,FunctionName);
+
+ bResult = TRUE;
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+//*************************************************************************
+// TryToInstallVirtualSWBreakpoints()
+//
+//*************************************************************************
+void TryToInstallVirtualSWBreakpoints(void)
+{
+ ULONG i,ulAddress;
+ PDEBUG_MODULE pMod;
+ PSW_BP p;
+
+ DPRINT((0,"TryToInstallVirtualSWBreakpoints()\n"));
+
+ for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
+ {
+ p = &aSwBreakpoints[i];
+ if(p->bUsed == TRUE && p->bVirtual)
+ {
+ if((pMod = IsModuleLoaded(p->szModName)))
+ {
+ if((ulAddress = FindFunctionInModuleByName(p->szFunctionName,pMod)))
+ {
+ if((p = FindVirtualSwBp(p->szModName,p->szFunctionName)))
+ {
+ ULONG ulAddressWithOffset = ulAddress+p->ulAddress;
+ DPRINT((0,"TryToInstallVirtualSWBreakpoints(): ulAddressWithOffset = %x (offset = %x)\n",ulAddressWithOffset,p->ulAddress));
+
+ if(IsAddressValid(ulAddressWithOffset))
+ {
+ BOOLEAN isWriteable;
+ DPRINT((0,"TryToInstallVirtualSWBreakpoints(): installing...\n"));
+ p->ucOriginalOpcode = *(PUCHAR)ulAddressWithOffset;
+ //allow writing to page
+ if( !( isWriteable = IsAddressWriteable(ulAddressWithOffset) ) )
+ SetAddressWriteable(ulAddressWithOffset,TRUE);
+ *(PUCHAR)ulAddressWithOffset = 0xCC;
+ if( !isWriteable )
+ SetAddressWriteable(ulAddressWithOffset,FALSE);
+ p->bUsed = TRUE;
+ p->bInstalled = TRUE;
+ p->bVirtual = FALSE;
+ // find next address
+ p->ulAddress = ulAddressWithOffset;
+ Disasm(&ulAddressWithOffset,(PUCHAR)&tempBp);
+ p->ulNextInstr = ulAddressWithOffset;
+ p->bPermanent = FALSE;
+ p->Callback = NULL;
+ }
+ else
+ {
+ DPRINT((0,"TryToInstallVirtualSWBreakpoints(): not valid address\n"));
+ PICE_memset(p,0,sizeof(*p));
+ }
+ }
+
+ }
+ }
+ }
+ }
+}
+
+//*************************************************************************
+// RemoveSWBreakpoint()
+//
+// removes breakpoint from breakpoint list
+//*************************************************************************
+BOOLEAN RemoveSWBreakpoint(ULONG ulAddress)
+{
+ PSW_BP p;
+ BOOLEAN bResult = FALSE;
+
+ ENTER_FUNC();
+ DPRINT((0,"RemoveSWBreakpoint()\n"));
+
+ if( (p = FindSwBp(ulAddress)) )
+ {
+ if(IsAddressValid(ulAddress) && p->bInstalled == TRUE && p->bVirtual==FALSE)
+ {
+ BOOLEAN isWriteable;
+ if( !( isWriteable = IsAddressWriteable(ulAddress) ) )
+ SetAddressWriteable(ulAddress,TRUE);
+ // restore original opcode
+ *(PUCHAR)(p->ulAddress) = p->ucOriginalOpcode;
+ if( !isWriteable )
+ SetAddressWriteable(ulAddress,FALSE);
+ }
+
+ PICE_memset(p,0,sizeof(*p));
+
+ bResult = TRUE;
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+
+//*************************************************************************
+// DeInstallSWBreakpoint()
+//
+//*************************************************************************
+BOOLEAN DeInstallSWBreakpoint(ULONG ulAddress)
+{
+ PSW_BP p;
+ BOOLEAN bResult = FALSE;
+
+ ENTER_FUNC();
+ DPRINT((0,"DeInstallSWBreakpoint()\n"));
+
+ if( (p = FindSwBp(ulAddress)) )
+ {
+ if(IsAddressValid(ulAddress) && p->bInstalled == TRUE && p->bVirtual==FALSE)
+ {
+ BOOLEAN isWriteable;
+ if( !( isWriteable = IsAddressWriteable(ulAddress) ) )
+ SetAddressWriteable(ulAddress,TRUE);
+ // restore original opcode
+ *(PUCHAR)(p->ulAddress) = p->ucOriginalOpcode;
+ if( !isWriteable )
+ SetAddressWriteable(ulAddress,FALSE);
+ }
+
+ p->bInstalled = FALSE;
+
+ bResult = TRUE;
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+//*************************************************************************
+// RemoveAllSWBreakpoints()
+//
+//*************************************************************************
+BOOLEAN RemoveAllSWBreakpoints(BOOLEAN bEvenPermanents)
+{
+ PSW_BP p;
+ BOOLEAN bResult = FALSE;
+ ULONG i;
+
+ ENTER_FUNC();
+ DPRINT((0,"RemoveAllSWBreakpoint()\n"));
+
+ for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
+ {
+ p = &aSwBreakpoints[i];
+ if(p->bUsed == TRUE)
+ {
+ if(bEvenPermanents)
+ {
+ if(IsAddressValid(p->ulAddress) && p->bVirtual==FALSE)
+ {
+ BOOLEAN isWriteable;
+ if( !( isWriteable = IsAddressWriteable(p->ulAddress) ) )
+ SetAddressWriteable(p->ulAddress,TRUE);
+ *(PUCHAR)(p->ulAddress) = p->ucOriginalOpcode;
+ if( !isWriteable )
+ SetAddressWriteable(p->ulAddress,FALSE);
+ bResult = TRUE;
+ }
+ PICE_memset(p,0,sizeof(*p));
+ }
+ else
+ {
+ if(!p->bPermanent)
+ {
+ if(IsAddressValid(p->ulAddress) && p->bVirtual==FALSE)
+ {
+ BOOLEAN isWriteable;
+ if( !( isWriteable = IsAddressWriteable(p->ulAddress) ) )
+ SetAddressWriteable(p->ulAddress,TRUE);
+ *(PUCHAR)(p->ulAddress) = p->ucOriginalOpcode;
+ if( !isWriteable )
+ SetAddressWriteable(p->ulAddress,FALSE);
+ bResult = TRUE;
+ }
+ PICE_memset(p,0,sizeof(*p));
+ }
+ }
+ }
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+//*************************************************************************
+// IsPermanentSWBreakpoint()
+//
+//*************************************************************************
+PSW_BP IsPermanentSWBreakpoint(ULONG ulAddress)
+{
+ PSW_BP p;
+ ULONG i;
+
+ ENTER_FUNC();
+ DPRINT((0,"IsPermanentSWBreakpoint(%.8X)\n",ulAddress));
+
+ for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(aSwBreakpoints[0]));i++)
+ {
+ p = &aSwBreakpoints[i];
+ if(p->ulAddress == ulAddress &&
+ p->bUsed == TRUE &&
+ p->bPermanent == TRUE)
+ {
+ LEAVE_FUNC();
+ return p;
+ }
+ }
+
+ LEAVE_FUNC();
+
+ return NULL;
+}
+
+//*************************************************************************
+// ListSWBreakpoints()
+//
+//*************************************************************************
+void ListSWBreakpoints(void)
+{
+ PSW_BP p;
+ ULONG i;
+ LPSTR pSymbolName;
+ PDEBUG_MODULE pMod;
+
+ ENTER_FUNC();
+ DPRINT((0,"ListSWBreakpoints()\n"));
+
+ for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
+ {
+ p = &aSwBreakpoints[i];
+ if(p->bUsed == TRUE && p->bVirtual == FALSE)
+ {
+ if((pSymbolName = FindFunctionByAddress(p->ulAddress,NULL,NULL)) )
+ {
+ pMod = FindModuleFromAddress(p->ulAddress);
+ PICE_sprintf(tempBp,"[%u] %.8X (%S!%s) %s\n",i,p->ulAddress,pMod->name,pSymbolName,p->bPermanent?"PERMANENT":"");
+ }
+ else
+ {
+ if(ScanExportsByAddress(&pSymbolName,p->ulAddress))
+ PICE_sprintf(tempBp,"[%u] %.8X (%s) %s\n",i,p->ulAddress,pSymbolName,p->bPermanent?"PERMANENT":"");
+ else
+ PICE_sprintf(tempBp,"[%u] %.8X (no symbol) %s\n",i,p->ulAddress,p->bPermanent?"PERMANENT":"");
+ }
+ Print(OUTPUT_WINDOW,tempBp);
+ }
+ else if(p->bUsed == TRUE)
+ {
+ PICE_sprintf(tempBp,"[%u] xxxxxxxx (%s!%s) VIRTUAL\n",i,p->szModName,p->szFunctionName);
+ Print(OUTPUT_WINDOW,tempBp);
+ }
+ }
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// RevirtualizeBreakpointsForModule()
+//
+//*************************************************************************
+void RevirtualizeBreakpointsForModule(PDEBUG_MODULE pMod)
+{
+ ULONG i,start,end;
+ PSW_BP p;
+ char temp[DEBUG_MODULE_NAME_LEN];
+
+ DPRINT((0,"RevirtualizeBreakpointsForModule(%x)\n",(ULONG)pMod));
+
+ if(IsRangeValid((ULONG)pMod,sizeof(DEBUG_MODULE)) )
+ {
+ start = (ULONG)pMod->BaseAddress;
+ end = (ULONG)pMod->BaseAddress+pMod->size;
+
+ DPRINT((0,"RevirtualizeBreakpointsForModule(): module %x (%x-%x)\n",(ULONG)pMod,start,end));
+ // go through all breakpoints
+ for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
+ {
+ p = &aSwBreakpoints[i];
+ // if it's used and installed and not virtual
+ if(p->bUsed && p->bInstalled && p->bVirtual == FALSE)
+ {
+ // make sure we're in module's bound
+ if(p->ulAddress>=start && p->ulAddress<end)
+ {
+ LPSTR pFind;
+ ULONG ulFunctionAddress;
+
+ DPRINT((0,"RevirtualizeBreakpointsForModule(): module breakpoint %u\n",i));
+ // find the function in which this breakpoint resides
+ if(ScanExportsByAddress(&pFind,p->ulAddress))
+ {
+ // from now on it's virtual again
+ p->bVirtual = TRUE;
+ if(IsAddressValid(p->ulAddress) )
+ {
+ BOOLEAN isWriteable;
+ if( !( isWriteable = IsAddressWriteable(p->ulAddress) ) )
+ SetAddressWriteable(p->ulAddress,TRUE);
+ DPRINT((0,"RevirtualizeBreakpointsForModule(): restoring original opcode @ %x\n",p->ulAddress));
+ *(PUCHAR)(p->ulAddress) = p->ucOriginalOpcode;
+ if( !isWriteable )
+ SetAddressWriteable(p->ulAddress,FALSE);
+ }
+ else
+ {
+ DPRINT((0,"RevirtualizeBreakpointsForModule(): could not restore original opcode @ %x\n",p->ulAddress));
+ }
+ // skip past the module separator
+ while(*pFind!='!')pFind++;
+ pFind++;
+ // remember the function and the module for reinstallation
+ CopyWideToAnsi(temp,pMod->name);
+ PICE_strcpy(p->szModName,temp);
+ PICE_strcpy(p->szFunctionName,pFind);
+ DPRINT((0,"RevirtualizeBreakpointsForModule(): %s!%s\n",p->szModName,p->szFunctionName));
+ // if function name contains a '+' it's an offset
+ pFind = p->szFunctionName;
+ while(*pFind!=0)
+ {
+ DPRINT((0,"RevirtualizeBreakpointsForModule(): [1] %s\n",pFind));
+ // found any offset to function
+ if(*pFind=='+')
+ {
+ *pFind=0;
+ break;
+ }
+ pFind++;
+ }
+
+ DPRINT((0,"RevirtualizeBreakpointsForModule(): [2] %s\n",p->szFunctionName));
+ if(ScanExports(p->szFunctionName,&ulFunctionAddress))
+ {
+ p->ulAddress -= ulFunctionAddress;
+ DPRINT((0,"RevirtualizeBreakpointsForModule(): [1] function @ %x offset = %x\n",ulFunctionAddress,p->ulAddress));
+ }
+ else
+ {
+ if((ulFunctionAddress = FindFunctionInModuleByName(p->szFunctionName,pMod)) )
+ {
+ p->ulAddress -= ulFunctionAddress;
+ DPRINT((0,"RevirtualizeBreakpointsForModule(): [2] function @ %x offset = %x\n",ulFunctionAddress,p->ulAddress));
+ }
+ else
+ {
+ DPRINT((0,"RevirtualizeBreakpointsForModule(): Breakpoint %u could not be virtualized properly!\n",i));
+ PICE_sprintf(tempBp,"Breakpoint %u could not be virtualized properly!\n",i);
+ Print(OUTPUT_WINDOW,tempBp);
+ }
+ }
+ }
+ else
+ {
+ DPRINT((0,"RevirtualizeBreakpointsForModule(): function for %x not found!\n",p->ulAddress));
+ PICE_memset(p,0,sizeof(*p));
+ }
+ }
+ }
+ }
+ }
+}
+
+//*************************************************************************
+// NewInt3Handler()
+//
+//*************************************************************************
+__asm__ ("\n\t \
+NewInt3Handler:\n\t \
+ pushl $" STR(REASON_INT3) "\n\t \
+ // call debugger loop\n\t \
+ jmp NewInt31Handler\n\t \
+");
+
+
+//*************************************************************************
+// InstallInt3Hook()
+//
+//*************************************************************************
+void InstallInt3Hook(void)
+{
+ ULONG LocalInt3Handler;
+
+ ENTER_FUNC();
+ DPRINT((0,"enter InstallInt3Hook()...\n"));
+
+ MaskIrqs();
+ if(!OldInt3Handler)
+ {
+ PICE_memset(aSwBreakpoints,0,sizeof(aSwBreakpoints));
+ __asm__("mov $NewInt3Handler,%0"
+ :"=r" (LocalInt3Handler)
+ :
+ :"eax");
+ OldInt3Handler=SetGlobalInt(0x03,(ULONG)LocalInt3Handler);
+ }
+ UnmaskIrqs();
+
+ DPRINT((0,"leave InstallInt3Hook()...\n"));
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// DeInstallInt3Hook()
+//
+//*************************************************************************
+void DeInstallInt3Hook(void)
+{
+ ENTER_FUNC();
+ DPRINT((0,"enter DeInstallInt3Hook()...\n"));
+
+ MaskIrqs();
+ if(OldInt3Handler)
+ {
+ RemoveAllSWBreakpoints(TRUE);
+ SetGlobalInt(0x03,(ULONG)OldInt3Handler);
+ OldInt3Handler=0;
+ }
+ UnmaskIrqs();
+
+ DPRINT((0,"leave DeInstallInt3Hook()...\n"));
+ LEAVE_FUNC();
+}
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ bp.h
+
+Abstract:
+
+ HEADER for bp.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+typedef struct _SW_BP
+{
+ ULONG ulAddress;
+ ULONG ulNextInstr;
+ UCHAR ucOriginalOpcode;
+ BOOLEAN bUsed;
+ BOOLEAN bInstalled;
+ BOOLEAN bPermanent;
+ BOOLEAN bVirtual;
+ char szModName[128];
+ char szFunctionName[128];
+ void (*Callback)(void);
+}SW_BP,*PSW_BP;
+
+BOOLEAN InstallSWBreakpoint(ULONG ulAddress,BOOLEAN bPermanent,void (*SWBreakpointCallback)(void));
+BOOLEAN InstallVirtualSWBreakpoint(LPSTR ModName,LPSTR Function);
+void TryToInstallVirtualSWBreakpoints(void);
+BOOLEAN DeInstallSWBreakpoint(ULONG ulAddress);
+BOOLEAN RemoveSWBreakpoint(ULONG ulAddress);
+BOOLEAN NeedToReInstallSWBreakpoints(ULONG ulAddress,BOOLEAN bUseAddress);
+BOOLEAN ReInstallSWBreakpoint(ULONG ulAddress);
+BOOLEAN RemoveAllSWBreakpoints(BOOLEAN bEvenPermanents);
+PSW_BP IsPermanentSWBreakpoint(ULONG ulAddress);
+void ListSWBreakpoints(void);
+PSW_BP FindSwBp(ULONG ulAddress);
+BOOLEAN IsSwBpAtAddress(ULONG ulAddress);
+BOOLEAN IsSwBpAtAddressInstalled(ULONG ulAddress);
+void RevirtualizeBreakpointsForModule(PDEBUG_MODULE pMod);
+
+void InstallInt3Hook(void);
+void DeInstallInt3Hook(void);
+
--- /dev/null
+// this file is dynamically generated: DON'T TOUCH
+
+UCHAR cGraphTable[8*256]=
+{
+ /* 0 0x00 '^@' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 1 0x01 '^A' */
+ 0x7e, /* 01111110 */
+ 0x81, /* 10000001 */
+ 0xa5, /* 10100101 */
+ 0x81, /* 10000001 */
+ 0xbd, /* 10111101 */
+ 0x99, /* 10011001 */
+ 0x81, /* 10000001 */
+ 0x7e, /* 01111110 */
+
+ /* 2 0x02 '^B' */
+ 0x7e, /* 01111110 */
+ 0xff, /* 11111111 */
+ 0xdb, /* 11011011 */
+ 0xff, /* 11111111 */
+ 0xc3, /* 11000011 */
+ 0xe7, /* 11100111 */
+ 0xff, /* 11111111 */
+ 0x7e, /* 01111110 */
+
+ /* 3 0x03 '^C' */
+ 0x6c, /* 01101100 */
+ 0xfe, /* 11111110 */
+ 0xfe, /* 11111110 */
+ 0xfe, /* 11111110 */
+ 0x7c, /* 01111100 */
+ 0x38, /* 00111000 */
+ 0x10, /* 00010000 */
+ 0x00, /* 00000000 */
+
+ /* 4 0x04 '^D' */
+ 0x10, /* 00010000 */
+ 0x38, /* 00111000 */
+ 0x7c, /* 01111100 */
+ 0xfe, /* 11111110 */
+ 0x7c, /* 01111100 */
+ 0x38, /* 00111000 */
+ 0x10, /* 00010000 */
+ 0x00, /* 00000000 */
+
+ /* 5 0x05 '^E' */
+ 0x38, /* 00111000 */
+ 0x7c, /* 01111100 */
+ 0x38, /* 00111000 */
+ 0xfe, /* 11111110 */
+ 0xfe, /* 11111110 */
+ 0xd6, /* 11010110 */
+ 0x10, /* 00010000 */
+ 0x38, /* 00111000 */
+
+ /* 6 0x06 '^F' */
+ 0x10, /* 00010000 */
+ 0x38, /* 00111000 */
+ 0x7c, /* 01111100 */
+ 0xfe, /* 11111110 */
+ 0xfe, /* 11111110 */
+ 0x7c, /* 01111100 */
+ 0x10, /* 00010000 */
+ 0x38, /* 00111000 */
+
+ /* 7 0x07 '^G' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x3c, /* 00111100 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 8 0x08 '^H' */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0xe7, /* 11100111 */
+ 0xc3, /* 11000011 */
+ 0xc3, /* 11000011 */
+ 0xe7, /* 11100111 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+
+ /* 9 0x09 '^I' */
+ 0x00, /* 00000000 */
+ 0x3c, /* 00111100 */
+ 0x66, /* 01100110 */
+ 0x42, /* 01000010 */
+ 0x42, /* 01000010 */
+ 0x66, /* 01100110 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 10 0x0a '^J' */
+ 0xff, /* 11111111 */
+ 0xc3, /* 11000011 */
+ 0x99, /* 10011001 */
+ 0xbd, /* 10111101 */
+ 0xbd, /* 10111101 */
+ 0x99, /* 10011001 */
+ 0xc3, /* 11000011 */
+ 0xff, /* 11111111 */
+
+ /* 11 0x0b '^K' */
+ 0x0f, /* 00001111 */
+ 0x07, /* 00000111 */
+ 0x0f, /* 00001111 */
+ 0x7d, /* 01111101 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0x78, /* 01111000 */
+
+ /* 12 0x0c '^L' */
+ 0x3c, /* 00111100 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x3c, /* 00111100 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+
+ /* 13 0x0d '^M' */
+ 0x3f, /* 00111111 */
+ 0x33, /* 00110011 */
+ 0x3f, /* 00111111 */
+ 0x30, /* 00110000 */
+ 0x30, /* 00110000 */
+ 0x70, /* 01110000 */
+ 0xf0, /* 11110000 */
+ 0xe0, /* 11100000 */
+
+ /* 14 0x0e '^N' */
+ 0x7f, /* 01111111 */
+ 0x63, /* 01100011 */
+ 0x7f, /* 01111111 */
+ 0x63, /* 01100011 */
+ 0x63, /* 01100011 */
+ 0x67, /* 01100111 */
+ 0xe6, /* 11100110 */
+ 0xc0, /* 11000000 */
+
+ /* 15 0x0f '^O' */
+ 0x18, /* 00011000 */
+ 0xdb, /* 11011011 */
+ 0x3c, /* 00111100 */
+ 0xe7, /* 11100111 */
+ 0xe7, /* 11100111 */
+ 0x3c, /* 00111100 */
+ 0xdb, /* 11011011 */
+ 0x18, /* 00011000 */
+
+ /* 16 0x10 '^P' */
+ 0x80, /* 10000000 */
+ 0xe0, /* 11100000 */
+ 0xf8, /* 11111000 */
+ 0xfe, /* 11111110 */
+ 0xf8, /* 11111000 */
+ 0xe0, /* 11100000 */
+ 0x80, /* 10000000 */
+ 0x00, /* 00000000 */
+
+ /* 17 0x11 '^Q' */
+ 0x02, /* 00000010 */
+ 0x0e, /* 00001110 */
+ 0x3e, /* 00111110 */
+ 0xfe, /* 11111110 */
+ 0x3e, /* 00111110 */
+ 0x0e, /* 00001110 */
+ 0x02, /* 00000010 */
+ 0x00, /* 00000000 */
+
+ /* 18 0x12 '^R' */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+ 0x3c, /* 00111100 */
+ 0x18, /* 00011000 */
+
+ /* 19 0x13 '^S' */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x00, /* 00000000 */
+ 0x66, /* 01100110 */
+ 0x00, /* 00000000 */
+
+ /* 20 0x14 '^T' */
+ 0x7f, /* 01111111 */
+ 0xdb, /* 11011011 */
+ 0xdb, /* 11011011 */
+ 0x7b, /* 01111011 */
+ 0x1b, /* 00011011 */
+ 0x1b, /* 00011011 */
+ 0x1b, /* 00011011 */
+ 0x00, /* 00000000 */
+
+ /* 21 0x15 '^U' */
+ 0x3e, /* 00111110 */
+ 0x61, /* 01100001 */
+ 0x3c, /* 00111100 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x3c, /* 00111100 */
+ 0x86, /* 10000110 */
+ 0x7c, /* 01111100 */
+
+ /* 22 0x16 '^V' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0x7e, /* 01111110 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+
+ /* 23 0x17 '^W' */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+ 0x3c, /* 00111100 */
+ 0x18, /* 00011000 */
+ 0xff, /* 11111111 */
+
+ /* 24 0x18 '^X' */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+
+ /* 25 0x19 '^Y' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+ 0x3c, /* 00111100 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+
+ /* 26 0x1a '^Z' */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x0c, /* 00001100 */
+ 0xfe, /* 11111110 */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 27 0x1b '^[' */
+ 0x00, /* 00000000 */
+ 0x30, /* 00110000 */
+ 0x60, /* 01100000 */
+ 0xfe, /* 11111110 */
+ 0x60, /* 01100000 */
+ 0x30, /* 00110000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 28 0x1c '^\' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 29 0x1d '^]' */
+ 0x00, /* 00000000 */
+ 0x24, /* 00100100 */
+ 0x66, /* 01100110 */
+ 0xff, /* 11111111 */
+ 0x66, /* 01100110 */
+ 0x24, /* 00100100 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 30 0x1e '^^' */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x7e, /* 01111110 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 31 0x1f '^_' */
+ 0x00, /* 00000000 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0x7e, /* 01111110 */
+ 0x3c, /* 00111100 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 32 0x20 ' ' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 33 0x21 '!' */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x3c, /* 00111100 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+
+ /* 34 0x22 '"' */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x24, /* 00100100 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 35 0x23 '#' */
+ 0x6c, /* 01101100 */
+ 0x6c, /* 01101100 */
+ 0xfe, /* 11111110 */
+ 0x6c, /* 01101100 */
+ 0xfe, /* 11111110 */
+ 0x6c, /* 01101100 */
+ 0x6c, /* 01101100 */
+ 0x00, /* 00000000 */
+
+ /* 36 0x24 '$' */
+ 0x18, /* 00011000 */
+ 0x3e, /* 00111110 */
+ 0x60, /* 01100000 */
+ 0x3c, /* 00111100 */
+ 0x06, /* 00000110 */
+ 0x7c, /* 01111100 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+
+ /* 37 0x25 '%' */
+ 0x00, /* 00000000 */
+ 0xc6, /* 11000110 */
+ 0xcc, /* 11001100 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0x66, /* 01100110 */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+
+ /* 38 0x26 '&' */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0x38, /* 00111000 */
+ 0x76, /* 01110110 */
+ 0xdc, /* 11011100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 39 0x27 ''' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 40 0x28 '(' */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0x30, /* 00110000 */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x0c, /* 00001100 */
+ 0x00, /* 00000000 */
+
+ /* 41 0x29 ')' */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x0c, /* 00001100 */
+ 0x0c, /* 00001100 */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0x00, /* 00000000 */
+
+ /* 42 0x2a '*' */
+ 0x00, /* 00000000 */
+ 0x66, /* 01100110 */
+ 0x3c, /* 00111100 */
+ 0xff, /* 11111111 */
+ 0x3c, /* 00111100 */
+ 0x66, /* 01100110 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 43 0x2b '+' */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 44 0x2c ',' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+
+ /* 45 0x2d '-' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 46 0x2e '.' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+
+ /* 47 0x2f '/' */
+ 0x06, /* 00000110 */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0x60, /* 01100000 */
+ 0xc0, /* 11000000 */
+ 0x80, /* 10000000 */
+ 0x00, /* 00000000 */
+
+ /* 48 0x30 '0' */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0xc6, /* 11000110 */
+ 0xd6, /* 11010110 */
+ 0xc6, /* 11000110 */
+ 0x6c, /* 01101100 */
+ 0x38, /* 00111000 */
+ 0x00, /* 00000000 */
+
+ /* 49 0x31 '1' */
+ 0x18, /* 00011000 */
+ 0x38, /* 00111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+
+ /* 50 0x32 '2' */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0x06, /* 00000110 */
+ 0x1c, /* 00011100 */
+ 0x30, /* 00110000 */
+ 0x66, /* 01100110 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+
+ /* 51 0x33 '3' */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0x06, /* 00000110 */
+ 0x3c, /* 00111100 */
+ 0x06, /* 00000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 52 0x34 '4' */
+ 0x1c, /* 00011100 */
+ 0x3c, /* 00111100 */
+ 0x6c, /* 01101100 */
+ 0xcc, /* 11001100 */
+ 0xfe, /* 11111110 */
+ 0x0c, /* 00001100 */
+ 0x1e, /* 00011110 */
+ 0x00, /* 00000000 */
+
+ /* 53 0x35 '5' */
+ 0xfe, /* 11111110 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0xfc, /* 11111100 */
+ 0x06, /* 00000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 54 0x36 '6' */
+ 0x38, /* 00111000 */
+ 0x60, /* 01100000 */
+ 0xc0, /* 11000000 */
+ 0xfc, /* 11111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 55 0x37 '7' */
+ 0xfe, /* 11111110 */
+ 0xc6, /* 11000110 */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0x30, /* 00110000 */
+ 0x30, /* 00110000 */
+ 0x00, /* 00000000 */
+
+ /* 56 0x38 '8' */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 57 0x39 '9' */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7e, /* 01111110 */
+ 0x06, /* 00000110 */
+ 0x0c, /* 00001100 */
+ 0x78, /* 01111000 */
+ 0x00, /* 00000000 */
+
+ /* 58 0x3a ':' */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+
+ /* 59 0x3b ';' */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+
+ /* 60 0x3c '<' */
+ 0x06, /* 00000110 */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x0c, /* 00001100 */
+ 0x06, /* 00000110 */
+ 0x00, /* 00000000 */
+
+ /* 61 0x3d '=' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 62 0x3e '>' */
+ 0x60, /* 01100000 */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0x60, /* 01100000 */
+ 0x00, /* 00000000 */
+
+ /* 63 0x3f '?' */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+
+ /* 64 0x40 '@' */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xde, /* 11011110 */
+ 0xde, /* 11011110 */
+ 0xde, /* 11011110 */
+ 0xc0, /* 11000000 */
+ 0x78, /* 01111000 */
+ 0x00, /* 00000000 */
+
+ /* 65 0x41 'A' */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+
+ /* 66 0x42 'B' */
+ 0xfc, /* 11111100 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x7c, /* 01111100 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0xfc, /* 11111100 */
+ 0x00, /* 00000000 */
+
+ /* 67 0x43 'C' */
+ 0x3c, /* 00111100 */
+ 0x66, /* 01100110 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0x66, /* 01100110 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 68 0x44 'D' */
+ 0xf8, /* 11111000 */
+ 0x6c, /* 01101100 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x6c, /* 01101100 */
+ 0xf8, /* 11111000 */
+ 0x00, /* 00000000 */
+
+ /* 69 0x45 'E' */
+ 0xfe, /* 11111110 */
+ 0x62, /* 01100010 */
+ 0x68, /* 01101000 */
+ 0x78, /* 01111000 */
+ 0x68, /* 01101000 */
+ 0x62, /* 01100010 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+
+ /* 70 0x46 'F' */
+ 0xfe, /* 11111110 */
+ 0x62, /* 01100010 */
+ 0x68, /* 01101000 */
+ 0x78, /* 01111000 */
+ 0x68, /* 01101000 */
+ 0x60, /* 01100000 */
+ 0xf0, /* 11110000 */
+ 0x00, /* 00000000 */
+
+ /* 71 0x47 'G' */
+ 0x3c, /* 00111100 */
+ 0x66, /* 01100110 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0xce, /* 11001110 */
+ 0x66, /* 01100110 */
+ 0x3a, /* 00111010 */
+ 0x00, /* 00000000 */
+
+ /* 72 0x48 'H' */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+
+ /* 73 0x49 'I' */
+ 0x3c, /* 00111100 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 74 0x4a 'J' */
+ 0x1e, /* 00011110 */
+ 0x0c, /* 00001100 */
+ 0x0c, /* 00001100 */
+ 0x0c, /* 00001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0x78, /* 01111000 */
+ 0x00, /* 00000000 */
+
+ /* 75 0x4b 'K' */
+ 0xe6, /* 11100110 */
+ 0x66, /* 01100110 */
+ 0x6c, /* 01101100 */
+ 0x78, /* 01111000 */
+ 0x6c, /* 01101100 */
+ 0x66, /* 01100110 */
+ 0xe6, /* 11100110 */
+ 0x00, /* 00000000 */
+
+ /* 76 0x4c 'L' */
+ 0xf0, /* 11110000 */
+ 0x60, /* 01100000 */
+ 0x60, /* 01100000 */
+ 0x60, /* 01100000 */
+ 0x62, /* 01100010 */
+ 0x66, /* 01100110 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+
+ /* 77 0x4d 'M' */
+ 0xc6, /* 11000110 */
+ 0xee, /* 11101110 */
+ 0xfe, /* 11111110 */
+ 0xfe, /* 11111110 */
+ 0xd6, /* 11010110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+
+ /* 78 0x4e 'N' */
+ 0xc6, /* 11000110 */
+ 0xe6, /* 11100110 */
+ 0xf6, /* 11110110 */
+ 0xde, /* 11011110 */
+ 0xce, /* 11001110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+
+ /* 79 0x4f 'O' */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 80 0x50 'P' */
+ 0xfc, /* 11111100 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x7c, /* 01111100 */
+ 0x60, /* 01100000 */
+ 0x60, /* 01100000 */
+ 0xf0, /* 11110000 */
+ 0x00, /* 00000000 */
+
+ /* 81 0x51 'Q' */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xce, /* 11001110 */
+ 0x7c, /* 01111100 */
+ 0x0e, /* 00001110 */
+
+ /* 82 0x52 'R' */
+ 0xfc, /* 11111100 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x7c, /* 01111100 */
+ 0x6c, /* 01101100 */
+ 0x66, /* 01100110 */
+ 0xe6, /* 11100110 */
+ 0x00, /* 00000000 */
+
+ /* 83 0x53 'S' */
+ 0x3c, /* 00111100 */
+ 0x66, /* 01100110 */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x0c, /* 00001100 */
+ 0x66, /* 01100110 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 84 0x54 'T' */
+ 0x7e, /* 01111110 */
+ 0x7e, /* 01111110 */
+ 0x5a, /* 01011010 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 85 0x55 'U' */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 86 0x56 'V' */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x6c, /* 01101100 */
+ 0x38, /* 00111000 */
+ 0x00, /* 00000000 */
+
+ /* 87 0x57 'W' */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xd6, /* 11010110 */
+ 0xd6, /* 11010110 */
+ 0xfe, /* 11111110 */
+ 0x6c, /* 01101100 */
+ 0x00, /* 00000000 */
+
+ /* 88 0x58 'X' */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x6c, /* 01101100 */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+
+ /* 89 0x59 'Y' */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x3c, /* 00111100 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 90 0x5a 'Z' */
+ 0xfe, /* 11111110 */
+ 0xc6, /* 11000110 */
+ 0x8c, /* 10001100 */
+ 0x18, /* 00011000 */
+ 0x32, /* 00110010 */
+ 0x66, /* 01100110 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+
+ /* 91 0x5b '[' */
+ 0x3c, /* 00111100 */
+ 0x30, /* 00110000 */
+ 0x30, /* 00110000 */
+ 0x30, /* 00110000 */
+ 0x30, /* 00110000 */
+ 0x30, /* 00110000 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 92 0x5c '\' */
+ 0xc0, /* 11000000 */
+ 0x60, /* 01100000 */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x0c, /* 00001100 */
+ 0x06, /* 00000110 */
+ 0x02, /* 00000010 */
+ 0x00, /* 00000000 */
+
+ /* 93 0x5d ']' */
+ 0x3c, /* 00111100 */
+ 0x0c, /* 00001100 */
+ 0x0c, /* 00001100 */
+ 0x0c, /* 00001100 */
+ 0x0c, /* 00001100 */
+ 0x0c, /* 00001100 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 94 0x5e '^' */
+ 0x10, /* 00010000 */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 95 0x5f '_' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xff, /* 11111111 */
+
+ /* 96 0x60 '`' */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x0c, /* 00001100 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 97 0x61 'a' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x78, /* 01111000 */
+ 0x0c, /* 00001100 */
+ 0x7c, /* 01111100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 98 0x62 'b' */
+ 0xe0, /* 11100000 */
+ 0x60, /* 01100000 */
+ 0x7c, /* 01111100 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0xdc, /* 11011100 */
+ 0x00, /* 00000000 */
+
+ /* 99 0x63 'c' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc0, /* 11000000 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 100 0x64 'd' */
+ 0x1c, /* 00011100 */
+ 0x0c, /* 00001100 */
+ 0x7c, /* 01111100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 101 0x65 'e' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc0, /* 11000000 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 102 0x66 'f' */
+ 0x3c, /* 00111100 */
+ 0x66, /* 01100110 */
+ 0x60, /* 01100000 */
+ 0xf8, /* 11111000 */
+ 0x60, /* 01100000 */
+ 0x60, /* 01100000 */
+ 0xf0, /* 11110000 */
+ 0x00, /* 00000000 */
+
+ /* 103 0x67 'g' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x76, /* 01110110 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0x7c, /* 01111100 */
+ 0x0c, /* 00001100 */
+ 0xf8, /* 11111000 */
+
+ /* 104 0x68 'h' */
+ 0xe0, /* 11100000 */
+ 0x60, /* 01100000 */
+ 0x6c, /* 01101100 */
+ 0x76, /* 01110110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0xe6, /* 11100110 */
+ 0x00, /* 00000000 */
+
+ /* 105 0x69 'i' */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x38, /* 00111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 106 0x6a 'j' */
+ 0x06, /* 00000110 */
+ 0x00, /* 00000000 */
+ 0x06, /* 00000110 */
+ 0x06, /* 00000110 */
+ 0x06, /* 00000110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x3c, /* 00111100 */
+
+ /* 107 0x6b 'k' */
+ 0xe0, /* 11100000 */
+ 0x60, /* 01100000 */
+ 0x66, /* 01100110 */
+ 0x6c, /* 01101100 */
+ 0x78, /* 01111000 */
+ 0x6c, /* 01101100 */
+ 0xe6, /* 11100110 */
+ 0x00, /* 00000000 */
+
+ /* 108 0x6c 'l' */
+ 0x38, /* 00111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 109 0x6d 'm' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xec, /* 11101100 */
+ 0xfe, /* 11111110 */
+ 0xd6, /* 11010110 */
+ 0xd6, /* 11010110 */
+ 0xd6, /* 11010110 */
+ 0x00, /* 00000000 */
+
+ /* 110 0x6e 'n' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xdc, /* 11011100 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x00, /* 00000000 */
+
+ /* 111 0x6f 'o' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 112 0x70 'p' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xdc, /* 11011100 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x7c, /* 01111100 */
+ 0x60, /* 01100000 */
+ 0xf0, /* 11110000 */
+
+ /* 113 0x71 'q' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x76, /* 01110110 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0x7c, /* 01111100 */
+ 0x0c, /* 00001100 */
+ 0x1e, /* 00011110 */
+
+ /* 114 0x72 'r' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xdc, /* 11011100 */
+ 0x76, /* 01110110 */
+ 0x60, /* 01100000 */
+ 0x60, /* 01100000 */
+ 0xf0, /* 11110000 */
+ 0x00, /* 00000000 */
+
+ /* 115 0x73 's' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0xc0, /* 11000000 */
+ 0x7c, /* 01111100 */
+ 0x06, /* 00000110 */
+ 0xfc, /* 11111100 */
+ 0x00, /* 00000000 */
+
+ /* 116 0x74 't' */
+ 0x30, /* 00110000 */
+ 0x30, /* 00110000 */
+ 0xfc, /* 11111100 */
+ 0x30, /* 00110000 */
+ 0x30, /* 00110000 */
+ 0x36, /* 00110110 */
+ 0x1c, /* 00011100 */
+ 0x00, /* 00000000 */
+
+ /* 117 0x75 'u' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 118 0x76 'v' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x6c, /* 01101100 */
+ 0x38, /* 00111000 */
+ 0x00, /* 00000000 */
+
+ /* 119 0x77 'w' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xc6, /* 11000110 */
+ 0xd6, /* 11010110 */
+ 0xd6, /* 11010110 */
+ 0xfe, /* 11111110 */
+ 0x6c, /* 01101100 */
+ 0x00, /* 00000000 */
+
+ /* 120 0x78 'x' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xc6, /* 11000110 */
+ 0x6c, /* 01101100 */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+
+ /* 121 0x79 'y' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7e, /* 01111110 */
+ 0x06, /* 00000110 */
+ 0xfc, /* 11111100 */
+
+ /* 122 0x7a 'z' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0x4c, /* 01001100 */
+ 0x18, /* 00011000 */
+ 0x32, /* 00110010 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+
+ /* 123 0x7b '{' */
+ 0x0e, /* 00001110 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x70, /* 01110000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x0e, /* 00001110 */
+ 0x00, /* 00000000 */
+
+ /* 124 0x7c '|' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+
+ /* 125 0x7d '}' */
+ 0x70, /* 01110000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x0e, /* 00001110 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x70, /* 01110000 */
+ 0x00, /* 00000000 */
+
+ /* 126 0x7e '~' */
+ 0x76, /* 01110110 */
+ 0xdc, /* 11011100 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 127 0x7f '\7f' */
+ 0x00, /* 00000000 */
+ 0x10, /* 00010000 */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+
+ /* 128 0x80 '\80' */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x0c, /* 00001100 */
+ 0x78, /* 01111000 */
+
+ /* 129 0x81 '\81' */
+ 0xcc, /* 11001100 */
+ 0x00, /* 00000000 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 130 0x82 '\82' */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc0, /* 11000000 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 131 0x83 '\83' */
+ 0x7c, /* 01111100 */
+ 0x82, /* 10000010 */
+ 0x78, /* 01111000 */
+ 0x0c, /* 00001100 */
+ 0x7c, /* 01111100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 132 0x84 '\84' */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+ 0x78, /* 01111000 */
+ 0x0c, /* 00001100 */
+ 0x7c, /* 01111100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 133 0x85 '\85' */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x78, /* 01111000 */
+ 0x0c, /* 00001100 */
+ 0x7c, /* 01111100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 134 0x86 '\86' */
+ 0x30, /* 00110000 */
+ 0x30, /* 00110000 */
+ 0x78, /* 01111000 */
+ 0x0c, /* 00001100 */
+ 0x7c, /* 01111100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 135 0x87 '\87' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0x7e, /* 01111110 */
+ 0x0c, /* 00001100 */
+ 0x38, /* 00111000 */
+
+ /* 136 0x88 '\88' */
+ 0x7c, /* 01111100 */
+ 0x82, /* 10000010 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc0, /* 11000000 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 137 0x89 '\89' */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc0, /* 11000000 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 138 0x8a '\8a' */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc0, /* 11000000 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 139 0x8b '\8b' */
+ 0x66, /* 01100110 */
+ 0x00, /* 00000000 */
+ 0x38, /* 00111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 140 0x8c '\8c' */
+ 0x7c, /* 01111100 */
+ 0x82, /* 10000010 */
+ 0x38, /* 00111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 141 0x8d '\8d' */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x38, /* 00111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 142 0x8e '\8e' */
+ 0xc6, /* 11000110 */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+
+ /* 143 0x8f '\8f' */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+
+ /* 144 0x90 '\90' */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0xfe, /* 11111110 */
+ 0xc0, /* 11000000 */
+ 0xf8, /* 11111000 */
+ 0xc0, /* 11000000 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+
+ /* 145 0x91 '\91' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+ 0xd8, /* 11011000 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+
+ /* 146 0x92 '\92' */
+ 0x3e, /* 00111110 */
+ 0x6c, /* 01101100 */
+ 0xcc, /* 11001100 */
+ 0xfe, /* 11111110 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xce, /* 11001110 */
+ 0x00, /* 00000000 */
+
+ /* 147 0x93 '\93' */
+ 0x7c, /* 01111100 */
+ 0x82, /* 10000010 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 148 0x94 '\94' */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 149 0x95 '\95' */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 150 0x96 '\96' */
+ 0x78, /* 01111000 */
+ 0x84, /* 10000100 */
+ 0x00, /* 00000000 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 151 0x97 '\97' */
+ 0x60, /* 01100000 */
+ 0x30, /* 00110000 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 152 0x98 '\98' */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7e, /* 01111110 */
+ 0x06, /* 00000110 */
+ 0xfc, /* 11111100 */
+
+ /* 153 0x99 '\99' */
+ 0xc6, /* 11000110 */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x6c, /* 01101100 */
+ 0x38, /* 00111000 */
+ 0x00, /* 00000000 */
+
+ /* 154 0x9a '\9a' */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 155 0x9b '\9b' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 156 0x9c '\9c' */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0x64, /* 01100100 */
+ 0xf0, /* 11110000 */
+ 0x60, /* 01100000 */
+ 0x66, /* 01100110 */
+ 0xfc, /* 11111100 */
+ 0x00, /* 00000000 */
+
+ /* 157 0x9d '\9d' */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x3c, /* 00111100 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 158 0x9e '\9e' */
+ 0xf8, /* 11111000 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xfa, /* 11111010 */
+ 0xc6, /* 11000110 */
+ 0xcf, /* 11001111 */
+ 0xc6, /* 11000110 */
+ 0xc7, /* 11000111 */
+
+ /* 159 0x9f '\9f' */
+ 0x0e, /* 00001110 */
+ 0x1b, /* 00011011 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x18, /* 00011000 */
+ 0xd8, /* 11011000 */
+ 0x70, /* 01110000 */
+ 0x00, /* 00000000 */
+
+ /* 160 0xa0 ' ' */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0x78, /* 01111000 */
+ 0x0c, /* 00001100 */
+ 0x7c, /* 01111100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 161 0xa1 '¡' */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x38, /* 00111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 162 0xa2 '¢' */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 163 0xa3 '£' */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 164 0xa4 '¤' */
+ 0x76, /* 01110110 */
+ 0xdc, /* 11011100 */
+ 0x00, /* 00000000 */
+ 0xdc, /* 11011100 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x00, /* 00000000 */
+
+ /* 165 0xa5 '¥' */
+ 0x76, /* 01110110 */
+ 0xdc, /* 11011100 */
+ 0x00, /* 00000000 */
+ 0xe6, /* 11100110 */
+ 0xf6, /* 11110110 */
+ 0xde, /* 11011110 */
+ 0xce, /* 11001110 */
+ 0x00, /* 00000000 */
+
+ /* 166 0xa6 '¦' */
+ 0x3c, /* 00111100 */
+ 0x6c, /* 01101100 */
+ 0x6c, /* 01101100 */
+ 0x3e, /* 00111110 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 167 0xa7 '§' */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0x6c, /* 01101100 */
+ 0x38, /* 00111000 */
+ 0x00, /* 00000000 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 168 0xa8 '¨' */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0x63, /* 01100011 */
+ 0x3e, /* 00111110 */
+ 0x00, /* 00000000 */
+
+ /* 169 0xa9 '©' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xfe, /* 11111110 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 170 0xaa 'ª' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xfe, /* 11111110 */
+ 0x06, /* 00000110 */
+ 0x06, /* 00000110 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 171 0xab '«' */
+ 0x63, /* 01100011 */
+ 0xe6, /* 11100110 */
+ 0x6c, /* 01101100 */
+ 0x7e, /* 01111110 */
+ 0x33, /* 00110011 */
+ 0x66, /* 01100110 */
+ 0xcc, /* 11001100 */
+ 0x0f, /* 00001111 */
+
+ /* 172 0xac '¬' */
+ 0x63, /* 01100011 */
+ 0xe6, /* 11100110 */
+ 0x6c, /* 01101100 */
+ 0x7a, /* 01111010 */
+ 0x36, /* 00110110 */
+ 0x6a, /* 01101010 */
+ 0xdf, /* 11011111 */
+ 0x06, /* 00000110 */
+
+ /* 173 0xad '' */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x3c, /* 00111100 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+
+ /* 174 0xae '®' */
+ 0x00, /* 00000000 */
+ 0x33, /* 00110011 */
+ 0x66, /* 01100110 */
+ 0xcc, /* 11001100 */
+ 0x66, /* 01100110 */
+ 0x33, /* 00110011 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 175 0xaf '¯' */
+ 0x00, /* 00000000 */
+ 0xcc, /* 11001100 */
+ 0x66, /* 01100110 */
+ 0x33, /* 00110011 */
+ 0x66, /* 01100110 */
+ 0xcc, /* 11001100 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 176 0xb0 '°' */
+ 0x22, /* 00100010 */
+ 0x88, /* 10001000 */
+ 0x22, /* 00100010 */
+ 0x88, /* 10001000 */
+ 0x22, /* 00100010 */
+ 0x88, /* 10001000 */
+ 0x22, /* 00100010 */
+ 0x88, /* 10001000 */
+
+ /* 177 0xb1 '±' */
+ 0x55, /* 01010101 */
+ 0xaa, /* 10101010 */
+ 0x55, /* 01010101 */
+ 0xaa, /* 10101010 */
+ 0x55, /* 01010101 */
+ 0xaa, /* 10101010 */
+ 0x55, /* 01010101 */
+ 0xaa, /* 10101010 */
+
+ /* 178 0xb2 '²' */
+ 0x77, /* 01110111 */
+ 0xdd, /* 11011101 */
+ 0x77, /* 01110111 */
+ 0xdd, /* 11011101 */
+ 0x77, /* 01110111 */
+ 0xdd, /* 11011101 */
+ 0x77, /* 01110111 */
+ 0xdd, /* 11011101 */
+
+ /* 179 0xb3 '³' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 180 0xb4 '´' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0xf8, /* 11111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 181 0xb5 'µ' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0xf8, /* 11111000 */
+ 0x18, /* 00011000 */
+ 0xf8, /* 11111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 182 0xb6 '¶' */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0xf6, /* 11110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+
+ /* 183 0xb7 '·' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xfe, /* 11111110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+
+ /* 184 0xb8 '¸' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xf8, /* 11111000 */
+ 0x18, /* 00011000 */
+ 0xf8, /* 11111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 185 0xb9 '¹' */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0xf6, /* 11110110 */
+ 0x06, /* 00000110 */
+ 0xf6, /* 11110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+
+ /* 186 0xba 'º' */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+
+ /* 187 0xbb '»' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xfe, /* 11111110 */
+ 0x06, /* 00000110 */
+ 0xf6, /* 11110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+
+ /* 188 0xbc '¼' */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0xf6, /* 11110110 */
+ 0x06, /* 00000110 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 189 0xbd '½' */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 190 0xbe '¾' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0xf8, /* 11111000 */
+ 0x18, /* 00011000 */
+ 0xf8, /* 11111000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 191 0xbf '¿' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xf8, /* 11111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 192 0xc0 'À' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x1f, /* 00011111 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 193 0xc1 'Á' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0xff, /* 11111111 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 194 0xc2 'Â' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xff, /* 11111111 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 195 0xc3 'Ã' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x1f, /* 00011111 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 196 0xc4 'Ä' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xff, /* 11111111 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 197 0xc5 'Å' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0xff, /* 11111111 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 198 0xc6 'Æ' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x1f, /* 00011111 */
+ 0x18, /* 00011000 */
+ 0x1f, /* 00011111 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 199 0xc7 'Ç' */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x37, /* 00110111 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+
+ /* 200 0xc8 'È' */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x37, /* 00110111 */
+ 0x30, /* 00110000 */
+ 0x3f, /* 00111111 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 201 0xc9 'É' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x3f, /* 00111111 */
+ 0x30, /* 00110000 */
+ 0x37, /* 00110111 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+
+ /* 202 0xca 'Ê' */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0xf7, /* 11110111 */
+ 0x00, /* 00000000 */
+ 0xff, /* 11111111 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 203 0xcb 'Ë' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xff, /* 11111111 */
+ 0x00, /* 00000000 */
+ 0xf7, /* 11110111 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+
+ /* 204 0xcc 'Ì' */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x37, /* 00110111 */
+ 0x30, /* 00110000 */
+ 0x37, /* 00110111 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+
+ /* 205 0xcd 'Í' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xff, /* 11111111 */
+ 0x00, /* 00000000 */
+ 0xff, /* 11111111 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 206 0xce 'Î' */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0xf7, /* 11110111 */
+ 0x00, /* 00000000 */
+ 0xf7, /* 11110111 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+
+ /* 207 0xcf 'Ï' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0xff, /* 11111111 */
+ 0x00, /* 00000000 */
+ 0xff, /* 11111111 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 208 0xd0 'Ð' */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0xff, /* 11111111 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 209 0xd1 'Ñ' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xff, /* 11111111 */
+ 0x00, /* 00000000 */
+ 0xff, /* 11111111 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 210 0xd2 'Ò' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xff, /* 11111111 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+
+ /* 211 0xd3 'Ó' */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x3f, /* 00111111 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 212 0xd4 'Ô' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x1f, /* 00011111 */
+ 0x18, /* 00011000 */
+ 0x1f, /* 00011111 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 213 0xd5 'Õ' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x1f, /* 00011111 */
+ 0x18, /* 00011000 */
+ 0x1f, /* 00011111 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 214 0xd6 'Ö' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x3f, /* 00111111 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+
+ /* 215 0xd7 '×' */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0xff, /* 11111111 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+
+ /* 216 0xd8 'Ø' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0xff, /* 11111111 */
+ 0x18, /* 00011000 */
+ 0xff, /* 11111111 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 217 0xd9 'Ù' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0xf8, /* 11111000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 218 0xda 'Ú' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x1f, /* 00011111 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 219 0xdb 'Û' */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+
+ /* 220 0xdc 'Ü' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+
+ /* 221 0xdd 'Ý' */
+ 0xf0, /* 11110000 */
+ 0xf0, /* 11110000 */
+ 0xf0, /* 11110000 */
+ 0xf0, /* 11110000 */
+ 0xf0, /* 11110000 */
+ 0xf0, /* 11110000 */
+ 0xf0, /* 11110000 */
+ 0xf0, /* 11110000 */
+
+ /* 222 0xde 'Þ' */
+ 0x0f, /* 00001111 */
+ 0x0f, /* 00001111 */
+ 0x0f, /* 00001111 */
+ 0x0f, /* 00001111 */
+ 0x0f, /* 00001111 */
+ 0x0f, /* 00001111 */
+ 0x0f, /* 00001111 */
+ 0x0f, /* 00001111 */
+
+ /* 223 0xdf 'ß' */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0xff, /* 11111111 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 224 0xe0 'à' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x76, /* 01110110 */
+ 0xdc, /* 11011100 */
+ 0xc8, /* 11001000 */
+ 0xdc, /* 11011100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 225 0xe1 'á' */
+ 0x78, /* 01111000 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xd8, /* 11011000 */
+ 0xcc, /* 11001100 */
+ 0xc6, /* 11000110 */
+ 0xcc, /* 11001100 */
+ 0x00, /* 00000000 */
+
+ /* 226 0xe2 'â' */
+ 0xfe, /* 11111110 */
+ 0xc6, /* 11000110 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0x00, /* 00000000 */
+
+ /* 227 0xe3 'ã' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0xfe, /* 11111110 */
+ 0x6c, /* 01101100 */
+ 0x6c, /* 01101100 */
+ 0x6c, /* 01101100 */
+ 0x6c, /* 01101100 */
+ 0x00, /* 00000000 */
+
+ /* 228 0xe4 'ä' */
+ 0xfe, /* 11111110 */
+ 0xc6, /* 11000110 */
+ 0x60, /* 01100000 */
+ 0x30, /* 00110000 */
+ 0x60, /* 01100000 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+
+ /* 229 0xe5 'å' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0xd8, /* 11011000 */
+ 0xd8, /* 11011000 */
+ 0xd8, /* 11011000 */
+ 0x70, /* 01110000 */
+ 0x00, /* 00000000 */
+
+ /* 230 0xe6 'æ' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x7c, /* 01111100 */
+ 0xc0, /* 11000000 */
+
+ /* 231 0xe7 'ç' */
+ 0x00, /* 00000000 */
+ 0x76, /* 01110110 */
+ 0xdc, /* 11011100 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+
+ /* 232 0xe8 'è' */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x3c, /* 00111100 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+
+ /* 233 0xe9 'é' */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc6, /* 11000110 */
+ 0x6c, /* 01101100 */
+ 0x38, /* 00111000 */
+ 0x00, /* 00000000 */
+
+ /* 234 0xea 'ê' */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x6c, /* 01101100 */
+ 0x6c, /* 01101100 */
+ 0xee, /* 11101110 */
+ 0x00, /* 00000000 */
+
+ /* 235 0xeb 'ë' */
+ 0x0e, /* 00001110 */
+ 0x18, /* 00011000 */
+ 0x0c, /* 00001100 */
+ 0x3e, /* 00111110 */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 236 0xec 'ì' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0xdb, /* 11011011 */
+ 0xdb, /* 11011011 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 237 0xed 'í' */
+ 0x06, /* 00000110 */
+ 0x0c, /* 00001100 */
+ 0x7e, /* 01111110 */
+ 0xdb, /* 11011011 */
+ 0xdb, /* 11011011 */
+ 0x7e, /* 01111110 */
+ 0x60, /* 01100000 */
+ 0xc0, /* 11000000 */
+
+ /* 238 0xee 'î' */
+ 0x1e, /* 00011110 */
+ 0x30, /* 00110000 */
+ 0x60, /* 01100000 */
+ 0x7e, /* 01111110 */
+ 0x60, /* 01100000 */
+ 0x30, /* 00110000 */
+ 0x1e, /* 00011110 */
+ 0x00, /* 00000000 */
+
+ /* 239 0xef 'ï' */
+ 0x00, /* 00000000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+
+ /* 240 0xf0 'ð' */
+ 0x00, /* 00000000 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 241 0xf1 'ñ' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+
+ /* 242 0xf2 'ò' */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+
+ /* 243 0xf3 'ó' */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x0c, /* 00001100 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+
+ /* 244 0xf4 'ô' */
+ 0x0e, /* 00001110 */
+ 0x1b, /* 00011011 */
+ 0x1b, /* 00011011 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 245 0xf5 'õ' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0xd8, /* 11011000 */
+ 0xd8, /* 11011000 */
+ 0x70, /* 01110000 */
+
+ /* 246 0xf6 'ö' */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 247 0xf7 '÷' */
+ 0x00, /* 00000000 */
+ 0x76, /* 01110110 */
+ 0xdc, /* 11011100 */
+ 0x00, /* 00000000 */
+ 0x76, /* 01110110 */
+ 0xdc, /* 11011100 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 248 0xf8 'ø' */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0x6c, /* 01101100 */
+ 0x38, /* 00111000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 249 0xf9 'ù' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 250 0xfa 'ú' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 251 0xfb 'û' */
+ 0x0f, /* 00001111 */
+ 0x0c, /* 00001100 */
+ 0x0c, /* 00001100 */
+ 0x0c, /* 00001100 */
+ 0xec, /* 11101100 */
+ 0x6c, /* 01101100 */
+ 0x3c, /* 00111100 */
+ 0x1c, /* 00011100 */
+
+ /* 252 0xfc 'ü' */
+ 0x6c, /* 01101100 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x36, /* 00110110 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 253 0xfd 'ý' */
+ 0x78, /* 01111000 */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 254 0xfe 'þ' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x3c, /* 00111100 */
+ 0x3c, /* 00111100 */
+ 0x3c, /* 00111100 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+
+ /* 255 0xff 'ÿ' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+};
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ dblflt.c
+
+Abstract:
+
+ handle double faults on x86
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 13-Nov-1999: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+
+////////////////////////////////////////////////////
+// GLOBALS
+////
+ULONG OldDblFltHandler = 0;
+
+////////////////////////////////////////////////////
+// FUNCTIONS
+////
+
+//*************************************************************************
+// HandleDoubleFault()
+//
+//*************************************************************************
+void HandleDoubleFault(FRAME* ptr)
+{
+ DPRINT((0,"HandleDoubleFault(): ptr = %x\n",ptr));
+}
+
+
+//*************************************************************************
+// NewDblFltHandler()
+//
+//*************************************************************************
+__asm__ (" \
+NewDblFltHandler:\n\t \
+ pushfl\n\t \
+ cli;\n\t \
+ cld;\n\t \
+ pushal;\n\t \
+ pushl %ds;\n\t \
+\n\t \
+ // setup default data selectors\n\t \
+ movw %ss,%ax\n\t \
+ movw %ax,%ds\n\t \
+\n\t \
+ // get frame ptr\n\t \
+ lea 40(%esp),%eax\n\t \
+ pushl %eax\n\t \
+ call _HandleDoubleFault\n\t \
+ addl $4,%esp\n\t \
+\n\t \
+ popl %ds\n\t \
+ popal\n\t \
+ popfl\n\t \
+ // remove error code from stack and replace with reason code\n\t \
+ movl $" STR(REASON_DOUBLE_FAULT) ",(%esp)\n\t \
+ // call debugger loop\n\t \
+ jmp NewInt31Handler\n\t");
+
+
+//*************************************************************************
+// InstallDblFltHook()
+//
+//*************************************************************************
+void InstallDblFltHook(void)
+{
+ ULONG LocalDblFltHandler;
+
+ ENTER_FUNC();
+
+ MaskIrqs();
+ if(!OldDblFltHandler)
+ {
+ __asm__("mov $NewDblFltHandler,%0"
+ :"=r" (LocalDblFltHandler)
+ :
+ :"eax");
+ OldDblFltHandler=SetGlobalInt(0x08,(ULONG)LocalDblFltHandler);
+ }
+ UnmaskIrqs();
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// DeInstallDblFltHook()
+//
+//*************************************************************************
+void DeInstallDblFltHook(void)
+{
+ ENTER_FUNC();
+
+ MaskIrqs();
+ if(OldDblFltHandler)
+ {
+ RemoveAllSWBreakpoints(TRUE);
+ SetGlobalInt(0x08,(ULONG)OldDblFltHandler);
+ OldDblFltHandler=0;
+ }
+ UnmaskIrqs();
+
+ LEAVE_FUNC();
+}
+
+// EOF
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ dblflt.h
+
+Abstract:
+
+ HEADER for dblflt.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+void InstallDblFltHook(void);
+void DeInstallDblFltHook(void);
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ debug.c
+
+Abstract:
+
+ debug output
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 04-Feb-1999: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#ifdef DEBUG
+#include "remods.h"
+
+#include "precomp.h"
+#include <stdarg.h>
+#include "serial.h"
+#include "serial_port.h"
+
+#define STANDARD_DEBUG_PREFIX "pICE: "
+
+////////////////////////////////////////////////////
+// GLOBALS
+////
+LONG lDebugLevel = 10;
+ULONG ulDebugFlags;
+char tempDebug[2048];
+USHORT usDebugPortBase;
+
+extern BOOLEAN bIsPrintkPatched;
+////////////////////////////////////////////////////
+// FUNCTIONS
+////
+void DebugSendString(LPSTR s);
+
+
+//*************************************************************************
+// Pice_dprintf()
+//
+// internal debug print
+//*************************************************************************
+VOID Pice_dprintf(ULONG DebugLevel, PCHAR DebugMessage, ...)
+{
+ va_list ap;
+
+ va_start(ap, DebugMessage);
+ if (/*DebugLevel <= lDebugLevel*/ DebugLevel == 2)
+ {
+ save_flags(ulDebugFlags);
+ cli();
+ PICE_vsprintf(tempDebug, DebugMessage, ap);
+ //ei DebugSendString(tempDebug);
+ Print(OUTPUT_WINDOW, tempDebug);
+ //DbgPrint("%s", tempDebug);
+ restore_flags(ulDebugFlags);
+ }
+ va_end(ap);
+}
+
+//************************************************************************
+// SendByte()
+//
+// Output a character to the serial port
+//************************************************************************
+BOOLEAN DebugSendByte(UCHAR x)
+{
+ ULONG timeout;
+
+ timeout = 0x00FFFFL;
+
+ // Wait for transmitter to clear
+ while ((inportb((USHORT)(usDebugPortBase + LSR)) & XMTRDY) == 0)
+ if (!(--timeout))
+ {
+ return FALSE;
+ }
+
+ outportb((USHORT)(usDebugPortBase + TXR), x);
+
+ return TRUE;
+}
+
+///************************************************************************
+// DebugSetSpeed()
+//
+///************************************************************************
+void DebugSendString(LPSTR s)
+{
+ ULONG len = PICE_strlen(s),i;
+
+ for(i=0;i<len;i++)
+ {
+ DebugSendByte(s[i]);
+ }
+ DebugSendByte('\r');
+}
+
+///************************************************************************
+// DebugSetSpeed()
+//
+///************************************************************************
+void DebugSetSpeed(ULONG baudrate)
+{
+ UCHAR c;
+ ULONG divisor;
+
+ divisor = (ULONG) (115200L/baudrate);
+
+ c = inportb((USHORT)(usDebugPortBase + LCR));
+ outportb((USHORT)(usDebugPortBase + LCR), (UCHAR)(c | 0x80)); // Set DLAB
+ outportb((USHORT)(usDebugPortBase + DLL), (UCHAR)(divisor & 0x00FF));
+ outportb((USHORT)(usDebugPortBase + DLH), (UCHAR)((divisor >> 8) & 0x00FF));
+ outportb((USHORT)(usDebugPortBase + LCR), c); // Reset DLAB
+
+}
+
+///************************************************************************
+// DebugSetOthers()
+//
+// Set other communications parameters
+//************************************************************************
+void DebugSetOthers(ULONG Parity, ULONG Bits, ULONG StopBit)
+{
+ ULONG setting;
+ UCHAR c;
+
+ if (usDebugPortBase == 0) return ;
+ if (Bits < 5 || Bits > 8) return ;
+ if (StopBit != 1 && StopBit != 2) return ;
+ if (Parity != NO_PARITY && Parity != ODD_PARITY && Parity != EVEN_PARITY)
+ return;
+
+ setting = Bits-5;
+ setting |= ((StopBit == 1) ? 0x00 : 0x04);
+ setting |= Parity;
+
+ c = inportb((USHORT)(usDebugPortBase + LCR));
+ outportb((USHORT)(usDebugPortBase + LCR), (UCHAR)(c & ~0x80)); // Reset DLAB
+
+ // no ints
+ outportb((USHORT)(usDebugPortBase + IER), (UCHAR)0);
+
+ outportb((USHORT)(usDebugPortBase + FCR), (UCHAR)0);
+
+ outportb((USHORT)(usDebugPortBase + LCR), (UCHAR)setting);
+
+ outportb((USHORT)(usDebugPortBase + MCR), DTR | RTS);
+
+
+ return ;
+}
+
+///************************************************************************
+// DebugSetupSerial()
+//
+///************************************************************************
+void DebugSetupSerial(ULONG port,ULONG baudrate)
+{
+ USHORT ports[]={COM1BASE,COM2BASE};
+#if 0 //ei temporary
+ usDebugPortBase = ports[port-1];
+ DebugSetOthers(NO_PARITY,8,1);
+ DebugSetSpeed(baudrate);
+#endif
+}
+#endif // DEBUG
+
+// EOF
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ debug.h
+
+Abstract:
+
+ HEADER for debug.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+#ifdef DEBUG
+
+#define ENTER_FUNC() DPRINT((0,"enter "__FUNCTION__"()\n"))
+
+#define LEAVE_FUNC() DPRINT((0,"leave "__FUNCTION__"()\n"))
+
+VOID Pice_dprintf(ULONG DebugLevel, PCHAR DebugMessage, ...);
+#define DPRINT(arg) Pice_dprintf arg
+
+#else // DEBUG
+
+#define ENTER_FUNC()
+#define LEAVE_FUNC()
+
+#define DPRINT(arg)
+
+#endif // DEBUG
--- /dev/null
+/*++
+
+Copyright (c) 2000-2001 Goran Devic
+Modified (c) 2001 Klaus P. Gerlicher
+
+Module Name:
+
+ disassembler.c
+
+Abstract:
+
+ line disassembler
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Goran Devic
+
+Revision History:
+
+ 17-Mar-2000: Original (Goran Devic)
+ 26-Apr-2000: Major rewrite, added coprocessor instructions (Goran Devic)
+ 04-Nov-2000: Modified for LinIce (Goran Devic)
+ 05-Jan-2001: Modified for pICE (Klaus P. Gerlicher)
+
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+/*******************************************************************************
+* Include Files *
+******************************************************************************/
+#include "remods.h"
+#include "precomp.h"
+
+#include "disassemblerdata.h" // Include its own data
+
+/******************************************************************************
+*
+* This structure is used to pass parameters and options to the
+* line disassembler.
+*
+******************************************************************************/
+typedef struct
+{
+ ULONG dwFlags; // Generic flags (described below)
+ USHORT wSel; // Selector to use to fetch code
+ UCHAR *bpTarget; // Target pointer to disassemble
+ UCHAR *szDisasm; // String where to put ascii result
+ UCHAR Codes[20]; // Buffer where to store code UCHARs
+
+ UCHAR bAsciiLen; // Length of the ascii result
+ UCHAR bInstrLen; // Instruction lenght in UCHARs
+
+ int nDisplacement; // Scanner: possible constant displacement
+ int nScanEnum; // Scanner: specific flags SCAN_*
+
+} TDisassembler;
+
+// dwFlags contains a set of boolean flags with the following functionality
+
+#define DIS_DATA32 0x0001 // Data size 16/32 bits (0/1)
+#define DIS_GETDATASIZE(flags) ((flags)&DIS_DATA32)
+#define DIS_ADDRESS32 0x0002 // Address size 16/32 bits (0/1)
+#define DIS_GETADDRSIZE(flags) (((flags)&DIS_ADDRESS32)?1:0)
+
+#define DIS_SEGOVERRIDE 0x0004 // Default segment has been overriden
+
+#define DIS_REP 0x0100 // Return: REP prefix found (followed by..)
+#define DIS_REPNE 0x0200 // Return: REPNE prefix found
+#define DIS_GETREPENUM(flags) (((flags)>>8)&3)
+#define DIS_ILLEGALOP 0x8000 // Return: illegal opcode
+
+
+/******************************************************************************
+* *
+* Global Variables *
+* *
+******************************************************************************/
+
+
+/******************************************************************************
+* *
+* External functions (optional) *
+* *
+******************************************************************************/
+
+/******************************************************************************
+* *
+* Local Defines, Variables and Macros *
+* *
+******************************************************************************/
+UCHAR GetUCHAR(ULONG addr)
+{
+ if(IsAddressValid(addr))
+ return *(PUCHAR)addr;
+ else
+ return 0x82; // INVALID OPCODE
+}
+
+static UCHAR GetNextUCHAR(USHORT sel, UCHAR *offset, UCHAR *pCode)
+{
+ pCode[0] = GetUCHAR((ULONG) offset + 0) & 0xFF;
+
+ return( pCode[0] );
+}
+
+static USHORT GetNextUSHORT(USHORT sel, UCHAR *offset, UCHAR *pCode)
+{
+ pCode[0] = GetUCHAR((ULONG) offset + 0) & 0xFF;
+ pCode[1] = GetUCHAR((ULONG) offset + 1) & 0xFF;
+
+ return( *(USHORT *) pCode );
+}
+
+static ULONG GetNextULONG(USHORT sel, UCHAR *offset, UCHAR *pCode)
+{
+ pCode[0] = GetUCHAR((ULONG) offset + 0) & 0xFF;
+ pCode[1] = GetUCHAR((ULONG) offset + 1) & 0xFF;
+ pCode[2] = GetUCHAR((ULONG) offset + 2) & 0xFF;
+ pCode[3] = GetUCHAR((ULONG) offset + 3) & 0xFF;
+
+ return( *(ULONG *) pCode );
+}
+
+
+#define NEXTUCHAR GetNextUCHAR( pDis->wSel, bpTarget, bpCode); bpCode += 1; bpTarget += 1; bInstrLen += 1
+
+#define NEXTUSHORT GetNextUSHORT( pDis->wSel, bpTarget, bpCode); bpCode += 2; bpTarget += 2; bInstrLen += 2
+
+#define NEXTULONG GetNextULONG(pDis->wSel, bpTarget, bpCode); bpCode += 4; bpTarget += 4; bInstrLen += 4
+
+
+/******************************************************************************
+* *
+* Functions *
+* *
+******************************************************************************/
+
+/******************************************************************************
+* *
+* UCHAR Disassembler( TDisassembler *pDis ); *
+* *
+*******************************************************************************
+*
+* This is a generic Intel line disassembler.
+*
+* Where:
+* TDisassembler:
+* bpTarget is the address of instruction to disassemble
+* szDisasm is the address of the buffer to print a line into
+* dwFlags contains the default operand and address bits
+* pCode is the address to store code UCHARs (up to 16)
+*
+* Disassembled instruction is stored as an ASCIIZ string pointed by
+* szDisasm pointer (from the pDis structure).
+*
+* Returns:
+* TDisassembler:
+* *szDisasm contains the disassembled instruction string
+* bAsciiLen is set to the length of the printed string
+* bInstrLen is set to instruction length in UCHARs
+* dwFlags - has operand and address size flags adjusted
+* - DIS_ILLEGALOP set if that was illegal instruction
+* UCHAR - instruction length in UCHARs
+*
+******************************************************************************/
+UCHAR Disassembler( TDisassembler *pDis )
+{
+ TOpcodeData *p; // Pointer to a current instruction record
+ UCHAR *bpTarget; // Pointer to the target code to be disassembled
+ UCHAR *bpCode; // Pointer to code UCHARs
+ ULONG arg; // Argument counter
+ char *sPtr; // Message selection pointer
+ int nPos; // Printing position in the output string
+ UCHAR *pArg; // Pointer to record where instruction arguments are
+ ULONG dwULONG; // Temporary ULONG storage
+ USHORT wUSHORT; // Temporary USHORT storage
+ UCHAR bUCHAR; // Temporary UCHAR storage
+ UCHAR bInstrLen; // Current instruction lenght in UCHARs
+ UCHAR bOpcode; // Current opcode that is being disassembled
+ UCHAR bSegOverride; // 0 default segment. >0, segment index
+ UCHAR bMod=0; // Mod field of the instruction
+ UCHAR bReg=0; // Register field of the instruction
+ UCHAR bRm=0; // R/M field of the instruction
+ UCHAR bW; // Width bit for the register selection
+
+ UCHAR bSib; // S-I-B UCHAR for the instruction
+ UCHAR bSs; // SS field of the s-i-b UCHAR
+ UCHAR bIndex; // Index field of the s-i-b UCHAR
+ UCHAR bBase; // Base field of the s-i-b UCHAR
+ LPSTR pSymbolName; // used to symbolic name of value
+
+ bInstrLen = 0; // Reset instruction lenght to zero
+ bSegOverride = 0; // Set default segment (no override)
+ nPos = 0; // Reset printing position
+ sPtr = NULL; // Points to no message by default
+ bpTarget = pDis->bpTarget; // Set internal pointer to a target address
+ bpCode = pDis->Codes; // Set internal pointer to code UCHARs
+
+ do
+ {
+ bOpcode = NEXTUCHAR; // Get the first opcode UCHAR from the target address
+ p = &Op1[bOpcode]; // Get the address of the instruction record
+
+ if( p->flags & DIS_SPECIAL )
+ {
+ // Opcode is one of the special ones, so do what needs to be done there
+
+ switch( p->name )
+ {
+ case _EscD8:
+ case _EscD9:
+ case _EscDA:
+ case _EscDB:
+ case _EscDC:
+ case _EscDD:
+ case _EscDE:
+ case _EscDF: // Coprocessor escape: UCHARs D8 - DF
+ bOpcode = NEXTUCHAR; // Get the modRM UCHAR of the instruction
+
+ if( bOpcode < 0xC0 )
+ {
+ // Opcodes 00-BF use Coproc1 table
+
+ bReg = (bOpcode >> 3) & 7;
+ p = &Coproc1[ p->name - _EscD8 ][ bReg ];
+
+ goto StartInstructionParseMODRM;
+ }
+ // Opcodes C0-FF use Coproc2 table
+
+ p = &Coproc2[ p->name - _EscD8 ][ bOpcode - 0xC0 ];
+
+ goto StartInstructionNoMODRM;
+
+ case _S_ES: // Segment override
+ case _S_CS:
+ case _S_SS:
+ case _S_DS:
+ case _S_FS:
+ case _S_GS:
+ bSegOverride = p->name - _S_ES + 1;
+ continue;
+
+ case _OPSIZ: // Operand size override - toggle
+ pDis->dwFlags ^= DIS_DATA32;
+ continue;
+
+ case _ADSIZ: // Address size override - toggle
+ pDis->dwFlags ^= DIS_ADDRESS32;
+ continue;
+
+ case _REPNE: // REPNE/REPNZ prefix
+ pDis->dwFlags |= DIS_REPNE;
+ continue;
+
+ case _REP: // REP/REPE/REPZ prefix
+ pDis->dwFlags |= DIS_REP;
+ continue;
+
+ case _2BESC: // 2 UCHAR escape code 0x0F
+ bOpcode = NEXTUCHAR; // Get the second UCHAR of the instruction
+ p = &Op2[bOpcode]; // Get the address of the instruction record
+
+ if( !(p->flags & DIS_SPECIAL) ) goto StartInstruction;
+ if( p->name < _GRP6 ) goto IllegalOpcode;
+
+ case _GRP1a: // Additional groups of instructions
+ case _GRP1b:
+ case _GRP1c:
+ case _GRP2a:
+ case _GRP2b:
+ case _GRP2c:
+ case _GRP2d:
+ case _GRP2e:
+ case _GRP2f:
+ case _GRP3a:
+ case _GRP3b:
+ case _GRP4:
+ case _GRP5:
+ case _GRP6:
+ case _GRP7:
+ case _GRP8:
+ case _GRP9:
+
+ bOpcode = NEXTUCHAR; // Get the Mod R/M UCHAR whose...
+ // bits 3,4,5 select instruction
+
+ bReg = (bOpcode >> 3) & 7;
+ p = &Groups[p->name - _GRP1a][ bReg ];
+
+ if( !(p->flags & DIS_SPECIAL) ) goto StartInstructionParseMODRM;
+
+ case _NDEF : // Not defined or illegal opcode
+ goto IllegalOpcode;
+
+ default :; // Should not happen
+ }
+ }
+ else
+ goto StartInstruction;
+ }
+ while( bInstrLen < 15 );
+
+IllegalOpcode:
+
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "invalid");
+ pDis->dwFlags |= DIS_ILLEGALOP;
+
+ goto DisEnd;
+
+StartInstruction:
+
+ // If this instruction needs additional Mod R/M UCHAR, fetch it
+
+ if( p->flags & DIS_MODRM )
+ {
+ // Get the next UCHAR (modR/M bit field)
+ bOpcode = NEXTUCHAR;
+
+ bReg = (bOpcode >> 3) & 7;
+
+StartInstructionParseMODRM:
+
+ // Parse that UCHAR and get mod, reg and rm fields
+ bMod = bOpcode >> 6;
+ bRm = bOpcode & 7;
+ }
+
+StartInstructionNoMODRM:
+
+ // Print the possible repeat prefix followed by the instruction
+
+ if( p->flags & DIS_COPROC )
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%-6s ", sCoprocNames[ p->name ]);
+ else
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s%-6s ",
+ sRep[DIS_GETREPENUM(pDis->dwFlags)],
+ sNames[ p->name + (DIS_GETNAMEFLAG(p->flags) & DIS_GETDATASIZE(pDis->dwFlags)) ] );
+
+ // Do instruction argument processing, up to 3 times
+
+ pArg = &p->dest;
+
+ for( arg=p->args; arg!=0; arg--, pArg++, arg? nPos += PICE_sprintf( pDis->szDisasm+nPos,", ") : 0 )
+ {
+ switch( *pArg )
+ {
+ case _Eb : // modR/M used - bW = 0
+ bW = 0;
+ goto _E;
+
+ case _Ev : // modR/M used - bW = 1
+ bW = 1;
+ goto _E;
+
+ case _Ew : // always USHORT size
+ pDis->dwFlags &= ~DIS_DATA32;
+ bW = 1;
+ goto _E;
+
+ case _Ms : // fword ptr (sgdt,sidt,lgdt,lidt)
+ sPtr = sFwordPtr;
+ goto _E1;
+
+ case _Mq : // qword ptr (cmpxchg8b)
+ sPtr = sQwordPtr;
+ goto _E1;
+
+ case _Mp : // 32 or 48 bit pointer (les,lds,lfs,lss,lgs)
+ case _Ep : // Always a memory pointer (call, jmp)
+ if( pDis->dwFlags & DIS_DATA32 )
+ sPtr = sFwordPtr;
+ else
+ sPtr = sDwordPtr;
+ goto _E1;
+
+ _E:
+ // Do registers first so that the rest may be done together
+ if( bMod == 3 )
+ {
+ // Registers depending on the w field and data size
+ nPos+=PICE_sprintf(pDis->szDisasm+nPos, "%s", sRegs1[DIS_GETDATASIZE(pDis->dwFlags)][bW][bRm] );
+
+ break;
+ }
+
+ if( bW==0 )
+ sPtr = sBytePtr;
+ else
+ if( pDis->dwFlags & DIS_DATA32 )
+ sPtr = sDwordPtr;
+ else
+ sPtr = sWordPtr;
+
+ case _M : // Pure memory pointer (lea,invlpg,floats)
+ if( bMod == 3 ) goto IllegalOpcode;
+
+ _E1:
+
+ if( sPtr )
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sPtr );
+
+ case _Ma : // Used by bound instruction, skip the pointer info
+
+ // Print the segment if it is overriden
+ //
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s", sSegOverride[ bSegOverride ] );
+
+ //
+ // Special case when sib UCHAR is present in 32 address encoding
+ //
+ if( (bRm==4) && (pDis->dwFlags & DIS_ADDRESS32) )
+ {
+ //
+ // Get the s-i-b UCHAR and parse it
+ //
+ bSib = NEXTUCHAR;
+
+ bSs = bSib >> 6;
+ bIndex = (bSib >> 3) & 7;
+ bBase = bSib & 7;
+
+ // Special case for base=5 && mod==0 -> fetch 32 bit offset
+ if( (bBase==5) && (bMod==0) )
+ {
+ dwULONG = NEXTULONG;
+ if(ScanExportsByAddress(&pSymbolName,dwULONG))
+ {
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%s", pSymbolName );
+ }
+ else
+ {
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%08X", (unsigned int) dwULONG );
+ }
+ }
+ else
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%s", sGenReg16_32[ 1 ][ bBase ] );
+
+ // Scaled index, no index if bIndex is 4
+ if( bIndex != 4 )
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"+%s%s", sScale[ bSs ], sGenReg16_32[ 1 ][ bIndex ] );
+ else
+ if(bSs != 0)
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"<INVALID MODE>" );
+
+ // Offset 8 bit or 32 bit
+ if( bMod == 1 )
+ {
+ bUCHAR = NEXTUCHAR;
+ if( (signed char)bUCHAR < 0 )
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"-%02X", 0-(signed char)bUCHAR );
+ else
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"+%02X", bUCHAR );
+ }
+
+ if( bMod == 2 )
+ {
+ dwULONG = NEXTULONG;
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"+%08X", (unsigned int) dwULONG );
+ }
+
+ // Wrap up the instruction
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"]" );
+ break;
+ }
+
+ //
+ // 16 or 32 address bit cases with mod zero, one or two
+ //
+ // Special cases when r/m is 5 and mod is 0, immediate d16 or d32
+ if( bMod==0 && ((bRm==6 && !(pDis->dwFlags & DIS_ADDRESS32)) || (bRm==5 && (pDis->dwFlags & DIS_ADDRESS32))) )
+ {
+ if( pDis->dwFlags & DIS_ADDRESS32 )
+ {
+ dwULONG = NEXTULONG;
+ if(ScanExportsByAddress(&pSymbolName,dwULONG))
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%s]", pSymbolName );
+ else
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%08X]", (unsigned int) dwULONG );
+ }
+ else
+ {
+ wUSHORT = NEXTUSHORT;
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%04X]", wUSHORT );
+ }
+
+ break;
+ }
+
+ // Print the start of the line
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%s", sAdr1[DIS_GETADDRSIZE(pDis->dwFlags)][ bRm ] );
+
+ // Offset (8 or 16) or (8 or 32) bit - 16, 32 bits are unsigned
+ if( bMod==1 )
+ {
+ bUCHAR = NEXTUCHAR;
+ if( (signed char)bUCHAR < 0 )
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"-%02X", 0-(signed char)bUCHAR );
+ else
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"+%02X", bUCHAR );
+ }
+
+ if( bMod==2 )
+ {
+ if( pDis->dwFlags & DIS_ADDRESS32 )
+ {
+ dwULONG = NEXTULONG;
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"+%08X", (unsigned int) dwULONG );
+ }
+ else
+ {
+ wUSHORT = NEXTUSHORT;
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"+%04X", wUSHORT );
+ }
+ }
+
+ // Wrap up the instruction
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"]" );
+
+ break;
+
+ case _Gb : // general, UCHAR register
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sRegs1[0][0][ bReg ] );
+ break;
+
+ case _Gv : // general, (d)USHORT register
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sGenReg16_32[DIS_GETDATASIZE(pDis->dwFlags)][ bReg ] );
+ break;
+
+ case _Yb : // ES:(E)DI pointer
+ case _Yv :
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s%s", sSegOverrideDefaultES[ bSegOverride ], sYptr[DIS_GETADDRSIZE(pDis->dwFlags)] );
+ break;
+
+ case _Xb : // DS:(E)SI pointer
+ case _Xv :
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s%s", sSegOverrideDefaultDS[ bSegOverride ], sXptr[DIS_GETADDRSIZE(pDis->dwFlags)] );
+ break;
+
+ case _Rd : // general register double USHORT
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sGenReg16_32[ 1 ][ bRm ] );
+ break;
+
+ case _Rw : // register USHORT
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sGenReg16_32[ 0 ][ bMod ] );
+ break;
+
+ case _Sw : // segment register
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sSeg[ bReg ] );
+ break;
+
+ case _Cd : // control register
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sControl[ bReg ] );
+ break;
+
+ case _Dd : // debug register
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sDebug[ bReg ] );
+ break;
+
+ case _Td : // test register
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sTest[ bReg ] );
+ break;
+
+
+ case _Jb : // immediate UCHAR, relative offset
+ bUCHAR = NEXTUCHAR;
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "short %08X", (unsigned int)(pDis->bpTarget + (signed char)bUCHAR + bInstrLen) );
+ break;
+
+ case _Jv : // immediate USHORT or ULONG, relative offset
+ if( pDis->dwFlags & DIS_DATA32 )
+ {
+ dwULONG = NEXTULONG;
+ if(ScanExportsByAddress(&pSymbolName,(unsigned int)(pDis->bpTarget + (signed long)dwULONG + bInstrLen)))
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", pSymbolName );
+ else
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%08X", (unsigned int)(pDis->bpTarget + (signed long)dwULONG + bInstrLen) );
+ }
+ else
+ {
+ wUSHORT = NEXTUSHORT;
+ if(ScanExportsByAddress(&pSymbolName,(unsigned int)(pDis->bpTarget + (signed short)wUSHORT + bInstrLen)))
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", pSymbolName );
+ else
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%08X", (unsigned int)(pDis->bpTarget + (signed short)wUSHORT + bInstrLen) );
+ }
+ break;
+
+ case _O : // Simple USHORT or ULONG offset
+ if( pDis->dwFlags & DIS_ADDRESS32 ) // depending on the address size
+ {
+ dwULONG = NEXTULONG;
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s[%08X]", sSegOverride[ bSegOverride ], (unsigned int) dwULONG );
+ }
+ else
+ {
+ wUSHORT = NEXTUSHORT;
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s[%04X]", sSegOverride[ bSegOverride ], wUSHORT );
+ }
+ break;
+
+ case _Ib : // immediate UCHAR
+ bUCHAR = NEXTUCHAR;
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"%02X", bUCHAR );
+ break;
+
+ case _Iv : // immediate USHORT or ULONG
+ if( pDis->dwFlags & DIS_DATA32 )
+ {
+ dwULONG = NEXTULONG;
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%08X", (unsigned int) dwULONG );
+ }
+ else
+ {
+ wUSHORT = NEXTUSHORT;
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%04X", wUSHORT );
+ }
+ break;
+
+ case _Iw : // Immediate USHORT
+ wUSHORT = NEXTUSHORT;
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%04X", wUSHORT );
+ break;
+
+ case _Ap : // 32 bit or 48 bit pointer (call far, jump far)
+ if( pDis->dwFlags & DIS_DATA32 )
+ {
+ dwULONG = NEXTULONG;
+ wUSHORT = NEXTUSHORT;
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%04X:%08X", wUSHORT, (unsigned int) dwULONG );
+ }
+ else
+ {
+ dwULONG = NEXTULONG;
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%08X", (unsigned int) dwULONG );
+ }
+ break;
+
+ case _1 : // numerical 1
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"1" );
+ break;
+
+ case _3 : // numerical 3
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"3" );
+ break;
+
+ // Hard coded registers
+ case _DX: case _AL: case _AH: case _BL: case _BH: case _CL: case _CH:
+ case _DL: case _DH: case _CS: case _DS: case _ES: case _SS: case _FS:
+ case _GS:
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s", sRegs2[ *pArg - _DX ] );
+ break;
+
+ case _eAX: case _eBX: case _eCX: case _eDX:
+ case _eSP: case _eBP: case _eSI: case _eDI:
+ nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sGenReg16_32[DIS_GETDATASIZE(pDis->dwFlags)][ *pArg - _eAX ]);
+ break;
+
+ case _ST: // Coprocessor ST
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s", sST[9] );
+ break;
+
+ case _ST0: // Coprocessor ST(0) - ST(7)
+ case _ST1:
+ case _ST2:
+ case _ST3:
+ case _ST4:
+ case _ST5:
+ case _ST6:
+ case _ST7:
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s", sST[ *pArg - _ST0 ] );
+ break;
+
+ case _AX: // Coprocessor AX
+ nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s", sGenReg16_32[0][0] );
+ break;
+ }
+ }
+
+DisEnd:
+
+ // Set the returning values and return with the bInstrLen field
+
+ pDis->bAsciiLen = (UCHAR) nPos;
+ pDis->bInstrLen = bInstrLen;
+
+ return bInstrLen;
+}
+
+/******************************************************************************
+* *
+* BOOLEAN Disasm(PULONG pOffset,PUCHAR pchDst) *
+* *
+* entry point for disassembly from other modules *
+******************************************************************************/
+BOOLEAN Disasm(PULONG pOffset,PUCHAR pchDst)
+{
+ TDisassembler dis;
+
+ dis.dwFlags = DIS_DATA32 | DIS_ADDRESS32;
+ dis.bpTarget = (UCHAR*)*pOffset;
+ dis.szDisasm = pchDst;
+ dis.wSel = CurrentCS;
+
+ *pOffset += (ULONG)Disassembler( &dis);
+ return TRUE;
+}
--- /dev/null
+ /* Operand and instruction types */
+#define OP_REG 0x100 /* register */
+#define OP_IMM 0x200 /* immediate value */
+#define OP_IND 0x300 /* indirect memory reference */
+#define OP_BPTR 0x400 /* BYTE Pointer */
+#define OP_WPTR 0x500 /* WORD Pointer */
+#define OP_DPTR 0x600 /* DWORD Pointer */
+#define OP_UNK 0x900
+//#define INS_INVALID 0x00 /* Not a valid instruction */
+ /* Branch Instruction types */
+#define INS_BRANCH 0x01 /* Unconditional branch */
+#define INS_COND 0x02 /* Conditional branch */
+#define INS_SUB 0x04 /* Jump to subroutine */
+#define INS_RET 0x08 /* Return from subroutine */
+ /* modify ( 'w' ) instructions */
+#define INS_ARITH 0x10 /* Arithmetic inst */
+#define INS_LOGIC 0x20 /* logical inst */
+#define INS_FPU 0x40 /* Floating Point inst */
+#define INS_FLAG 0x80 /* Modify flags */
+ /* misc Instruction Types */
+#define INS_MOVE 0x0100
+#define INS_ARRAY 0x0200 /* String and XLAT ops */
+#define INS_PTR 0x0400 /* Load EA/pointer */
+#define INS_STACK 0x1000 /* PUSH, POP, etc */
+#define INS_FRAME 0x2000 /* ENTER, LEAVE, etc */
+#define INS_SYSTEM 0x4000 /* CPUID, WBINVD, etc */
+
+/* Other info */
+#define BIG_ENDIAN_ORDER 0
+#define LITTLE_ENDIAN_ORDER 1
+
+struct code { /* size 100 */
+ unsigned long rva;
+ unsigned short flags;
+ char mnemonic[16];
+ char dest[32];
+ char src[32];
+ char aux[32];
+ int mnemType;
+ int destType;
+ int srcType;
+ int auxType;
+};
+
+/* struct used in Init routine */
+struct CPU_TYPE{
+ char vendor;
+ char model[12];
+};
+
+#define cpu_80386 0x01
+#define cpu_80486 0x02
+#define cpu_PENTIUM 0x04
+#define cpu_PENTMMX 0x08
+#define cpu_PENTPRO 0x10
+#define cpu_PENTIUM2 0x20
+#define cpu_PENTIUM3 0x40
+#define cpu_PENTIUM4 0x80
+
+#define FLAGS_MODRM 0x00001 //contains mod r/m byte
+#define FLAGS_8BIT 0x00002 //force 8-bit arguments
+#define FLAGS_16BIT 0x00004 //force 16-bit arguments
+#define FLAGS_32BIT 0x00008 //force 32-bit arguments
+#define FLAGS_REAL 0x00010 //real mode only
+#define FLAGS_PMODE 0x00020 //protected mode only
+#define FLAGS_PREFIX 0x00040 //for lock and rep prefix
+#define FLAGS_MMX 0x00080 //mmx instruction/registers
+#define FLAGS_FPU 0x00100 //fpu instruction/registers
+#define FLAGS_CJMP 0x00200 //codeflow - conditional jump
+#define FLAGS_JMP 0x00400 //codeflow - jump
+#define FLAGS_IJMP 0x00800 //codeflow - indexed jump
+#define FLAGS_CALL 0x01000 //codeflow - call
+#define FLAGS_ICALL 0x02000 //codeflow - indexed call
+#define FLAGS_RET 0x04000 //codeflow - return
+#define FLAGS_SEGPREFIX 0x08000 //segment prefix
+#define FLAGS_OPERPREFIX 0x10000 //operand prefix
+#define FLAGS_ADDRPREFIX 0x20000 //address prefix
+#define FLAGS_OMODE16 0x40000 //16-bit operand mode only
+#define FLAGS_OMODE32 0x80000 //32-bit operand mode only
+
+enum argtype {
+ ARG_REG=1,ARG_IMM,ARG_NONE,ARG_MODRM,ARG_REG_AX,
+ ARG_REG_ES,ARG_REG_CS,ARG_REG_SS,ARG_REG_DS,ARG_REG_FS,ARG_REG_GS,ARG_REG_BX,
+ ARG_REG_CX,ARG_REG_DX,
+ ARG_REG_SP,ARG_REG_BP,ARG_REG_SI,ARG_REG_DI,ARG_IMM8,ARG_RELIMM8,ARG_FADDR,ARG_REG_AL,
+ ARG_MEMLOC,ARG_SREG,ARG_RELIMM,ARG_16REG_DX,ARG_REG_CL,ARG_REG_DL,ARG_REG_BL,ARG_REG_AH,
+ ARG_REG_CH,ARG_REG_DH,ARG_REG_BH,ARG_MODREG,ARG_CREG,ARG_DREG,ARG_TREG_67,ARG_TREG,
+ ARG_MREG,ARG_MMXMODRM,ARG_MODRM8,ARG_IMM_1,ARG_MODRM_FPTR,ARG_MODRM_S,ARG_MODRMM512,
+ ARG_MODRMQ,ARG_MODRM_SREAL,ARG_REG_ST0,ARG_FREG,ARG_MODRM_PTR,ARG_MODRM_WORD,ARG_MODRM_SINT,
+ ARG_MODRM_EREAL,ARG_MODRM_DREAL,ARG_MODRM_WINT,ARG_MODRM_LINT,ARG_REG_BC,ARG_REG_DE,
+ ARG_REG_HL,ARG_REG_DE_IND,ARG_REG_HL_IND,ARG_REG_BC_IND,ARG_REG_SP_IND,ARG_REG_A,
+ ARG_REG_B,ARG_REG_C,ARG_REG_D,ARG_REG_E,ARG_REG_H,ARG_REG_L,ARG_IMM16,ARG_REG_AF,
+ ARG_REG_AF2,ARG_MEMLOC16,ARG_IMM8_IND,ARG_BIT,ARG_REG_IX,ARG_REG_IX_IND,ARG_REG_IY,
+ ARG_REG_IY_IND,ARG_REG_C_IND,ARG_REG_I,ARG_REG_R,ARG_IMM16_A,ARG_MODRM16,ARG_SIMM8,
+ ARG_IMM32,ARG_STRING,ARG_MODRM_BCD,ARG_PSTRING,ARG_DOSSTRING,ARG_CUNICODESTRING,
+ ARG_PUNICODESTRING,ARG_NONEBYTE,ARG_XREG,ARG_XMMMODRM};
+
+typedef struct x86_inst {
+ int flags;
+ int destType, srcType, auxType;
+ int cpu_type;
+ int inst_type;
+ char *mnem;
+ char *dest, *src, *aux;
+} instr;
+
+
+#define GENREG_8 0x0001
+#define GENREG_16 0x0002
+#define GENREG_32 0x0004
+#define SEGREG 0x0008
+#define MMXREG 0x0010
+#define SIMDREG 0x0020
+#define DEBUGREG 0x0040
+#define CONTROLREG 0x0080
+#define TESTREG 0x0100
+
+#define NO_REG 0x100
+#define DIRECT_REG 0x200
+#define NO_BASE 0x400
+#define NO_INDEX 0x800
+#define DISP8 0x1000
+#define DISP32 0x2000
+#define HAS_SIB 0x4000
+#define HAS_MODRM 0x8000
+
+struct OPERAND { //arg1, arg2, arg3
+ char * str; //temporary buffer for building arg text
+ int type; //argument type
+ int * flag; //pointer to CODE arg flags
+ char * text; //pointer to CODE arg text
+};
+
+struct EA { //effective address [SIB/disp]
+ int mode, flags;
+ int mod, rm, reg;
+ long disp;
+ char sib[32];
+};
+
+struct modRM_byte {
+ unsigned int mod : 2;
+ unsigned int reg : 3;
+ unsigned int rm : 3;
+};
+
+struct SIB_byte {
+ unsigned int scale : 2;
+ unsigned int index : 3;
+ unsigned int base : 3;
+};
+
+typedef struct x86_table { //Assembly instruction tables
+ instr *table; //Pointer to table of instruction encodings
+ char divisor; // number to divide by for look up
+ char mask; // bit mask for look up
+ char minlim,maxlim; // limits on min/max entries.
+ char modrmpos; // modrm byte position plus
+} asmtable;
--- /dev/null
+/*++
+
+Copyright (c) 2000-2001 Goran Devic
+Modified (c) 2001 Klaus P. Gerlicher
+
+Module Name:
+
+ disassembler.h
+
+Abstract:
+
+ header for disassembler.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Goran Devic
+
+Revision History:
+
+ 17-Mar-2000: Original (Goran Devic)
+ 05-Jan-2001: Modified for pICE (Klaus P. Gerlicher)
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+BUGS:
+ There is no segment override for _Ap (look the code)
+--*/
+
+
+/******************************************************************************
+* *
+* Include Files *
+* *
+******************************************************************************/
+
+#include "disassemblerdefines.h" // Include its own defines
+
+/******************************************************************************
+* *
+* Define opcode names as ASCIIZ strings *
+* *
+******************************************************************************/
+char* sNames[] = {
+"", /* 0X000 */
+"AAA", /* 0X001 */
+"AAD", /* 0X002 */
+"AAM", /* 0X003 */
+"AAS", /* 0X004 */
+"ADC", /* 0X005 */
+"ADD", /* 0X006 */
+"AND", /* 0X007 */
+"ARPL", /* 0X008 */
+"BOUND", /* 0X009 */
+"BSF", /* 0X00A */
+"BSR", /* 0X00B */
+"BT", /* 0X00C */
+"BTC", /* 0X00D */
+"BTR", /* 0X00E */
+"BTS", /* 0X00F */
+"CALL", /* 0X010 */
+"CBW", /* 0X011 */
+"CWDE", /* 0X012 */
+"CLC", /* 0X013 */
+"CLD", /* 0X014 */
+"CLI", /* 0X015 */
+"CLTS", /* 0X016 */
+"CMC", /* 0X017 */
+"CMP", /* 0X018 */
+"CMPS", /* 0X019 */
+"CMPSB", /* 0X01A */
+"CMPSW", /* 0X01B */
+"CMPSD", /* 0X01C */
+"CWD", /* 0X01D */
+"CDQ", /* 0X01E */
+"DAA", /* 0X01F */
+"DAS", /* 0X020 */
+"DEC", /* 0X021 */
+"DIV", /* 0X022 */
+"ENTER", /* 0X023 */
+"HLT", /* 0X024 */
+"IDIV", /* 0X025 */
+"IMUL", /* 0X026 */
+"IN", /* 0X027 */
+"INC", /* 0X028 */
+"INS", /* 0X029 */
+"INSB", /* 0X02A */
+"INSW", /* 0X02B */
+"INSD", /* 0X02C */
+"INT", /* 0X02D */
+"INTO", /* 0X02E */
+"IRET", /* 0X02F */
+"IRETD", /* 0X030 */
+"JO", /* 0X031 */
+"JNO", /* 0X032 */
+"JB", /* 0X033 */
+"JNB", /* 0X034 */
+"JZ", /* 0X035 */
+"JNZ", /* 0X036 */
+"JBE", /* 0X037 */
+"JNBE", /* 0X038 */
+"JS", /* 0X039 */
+"JNS", /* 0X03A */
+"JP", /* 0X03B */
+"JNP", /* 0X03C */
+"JL", /* 0X03D */
+"JNL", /* 0X03E */
+"JLE", /* 0X03F */
+"JNLE", /* 0X040 */
+"JMP", /* 0X041 */
+"LAHF", /* 0X042 */
+"LAR", /* 0X043 */
+"LEA", /* 0X044 */
+"LEAVE", /* 0X045 */
+"LGDT", /* 0X046 */
+"LIDT", /* 0X047 */
+"LGS", /* 0X048 */
+"LSS", /* 0X049 */
+"LDS", /* 0X04A */
+"LES", /* 0X04B */
+"LFS", /* 0X04C */
+"LLDT", /* 0X04D */
+"LMSW", /* 0X04E */
+"LOCK", /* 0X04F */
+"LODS", /* 0X050 */
+"LODSB", /* 0X051 */
+"LODSW", /* 0X052 */
+"LODSD", /* 0X053 */
+"LOOP", /* 0X054 */
+"LOOPE", /* 0X055 */
+"LOOPZ", /* 0X056 */
+"LOOPNE", /* 0X057 */
+"LOOPNZ", /* 0X058 */
+"LSL", /* 0X059 */
+"LTR", /* 0X05A */
+"MOV", /* 0X05B */
+"MOVS", /* 0X05C */
+"MOVSB", /* 0X05D */
+"MOVSW", /* 0X05E */
+"MOVSD", /* 0X05F */
+"MOVSX", /* 0X060 */
+"MOVZX", /* 0X061 */
+"MUL", /* 0X062 */
+"NEG", /* 0X063 */
+"NOP", /* 0X064 */
+"NOT", /* 0X065 */
+"OR", /* 0X066 */
+"OUT", /* 0X067 */
+"OUTS", /* 0X068 */
+"OUTSB", /* 0X069 */
+"OUTSW", /* 0X06A */
+"OUTSD", /* 0X06B */
+"POP", /* 0X06C */
+"POPA", /* 0X06D */
+"POPAD", /* 0X06E */
+"POPF", /* 0X06F */
+"POPFD", /* 0X070 */
+"PUSH", /* 0X071 */
+"PUSHA", /* 0X072 */
+"PUSHAD", /* 0X073 */
+"PUSHF", /* 0X074 */
+"PUSHFD", /* 0X075 */
+"RCL", /* 0X076 */
+"RCR", /* 0X077 */
+"ROL", /* 0X078 */
+"ROR", /* 0X079 */
+"REP", /* 0X07A */
+"REPE", /* 0X07B */
+"REPZ", /* 0X07C */
+"REPNE", /* 0X07D */
+"REPNZ", /* 0X07E */
+"RET", /* 0X07F */
+"SAHF", /* 0X080 */
+"SAL", /* 0X081 */
+"SAR", /* 0X082 */
+"SHL", /* 0X083 */
+"SHR", /* 0X084 */
+"SBB", /* 0X085 */
+"SCAS", /* 0X086 */
+"SCASB", /* 0X087 */
+"SCASW", /* 0X088 */
+"SCASD", /* 0X089 */
+"SET", /* 0X08A */
+"SGDT", /* 0X08B */
+"SIDT", /* 0X08C */
+"SHLD", /* 0X08D */
+"SHRD", /* 0X08E */
+"SLDT", /* 0X08F */
+"SMSW", /* 0X090 */
+"STC", /* 0X091 */
+"STD", /* 0X092 */
+"STI", /* 0X093 */
+"STOS", /* 0X094 */
+"STOSB", /* 0X095 */
+"STOSW", /* 0X096 */
+"STOSD", /* 0X097 */
+"STR", /* 0X098 */
+"SUB", /* 0X099 */
+"TEST", /* 0X09A */
+"VERR", /* 0X09B */
+"VERW", /* 0X09C */
+"WAIT", /* 0X09D */
+"XCHG", /* 0X09E */
+"XLAT", /* 0X09F */
+"XLATB", /* 0X0A0 */
+"XOR", /* 0X0A1 */
+"JCXZ", /* 0X0A2 */
+"LOADALL", /* 0X0A3 */
+"INVD", /* 0X0A4 */
+"WBINVD", /* 0X0A5 */
+"SETO", /* 0X0A6 */
+"SETNO", /* 0X0A7 */
+"SETB", /* 0X0A8 */
+"SETNB", /* 0X0A9 */
+"SETZ", /* 0X0AA */
+"SETNZ", /* 0X0AB */
+"SETBE", /* 0X0AC */
+"SETNBE", /* 0X0AD */
+"SETS", /* 0X0AE */
+"SETNS", /* 0X0AF */
+"SETP", /* 0X0B0 */
+"SETNP", /* 0X0B1 */
+"SETL", /* 0X0B2 */
+"SETNL", /* 0X0B3 */
+"SETLE", /* 0X0B4 */
+"SETNLE", /* 0X0B5 */
+"WRMSR", /* 0X0B6 */
+"RDTSC", /* 0X0B7 */
+"RDMSR", /* 0X0B8 */
+"CPUID", /* 0X0B9 */
+"RSM", /* 0X0BA */
+"CMPXCHG", /* 0X0BB */
+"XADD", /* 0X0BC */
+"BSWAP", /* 0X0BD */
+"INVLPG", /* 0X0BE */
+"CMPXCHG8B", /* 0X0BF */
+"JMP FAR", /* 0X0C0 */
+"RETF", /* 0X0C1 */
+"RDPMC" /* 0X0C2 */
+};
+
+
+char* sCoprocNames[] = {
+"", /* 0X000 */
+"F2XM1", /* 0X001 */
+"FABS", /* 0X002 */
+"FADD", /* 0X003 */
+"FADDP", /* 0X004 */
+"FBLD", /* 0X005 */
+"FBSTP", /* 0X006 */
+"FCHS", /* 0X007 */
+"FCLEX", /* 0X008 */
+"FCOM", /* 0X009 */
+"FCOMP", /* 0X00A */
+"FCOMPP", /* 0X00B */
+"FCOS", /* 0X00C */
+"FDECSTP", /* 0X00D */
+"FDIV", /* 0X00E */
+"FDIVP", /* 0X00F */
+"FDIVR", /* 0X010 */
+"FDIVRP", /* 0X011 */
+"FFREE", /* 0X012 */
+"FIADD", /* 0X013 */
+"FICOM", /* 0X014 */
+"FICOMP", /* 0X015 */
+"FIDIV", /* 0X016 */
+"FIDIVR", /* 0X017 */
+"FILD", /* 0X018 */
+"FIMUL", /* 0X019 */
+"FINCSTP", /* 0X01A */
+"FINIT", /* 0X01B */
+"FIST", /* 0X01C */
+"FISTP", /* 0X01D */
+"FISUB", /* 0X01E */
+"FISUBR", /* 0X01F */
+"FLD", /* 0X020 */
+"FLD1", /* 0X021 */
+"FLDCW", /* 0X022 */
+"FLDENV", /* 0X023 */
+"FLDL2E", /* 0X024 */
+"FLDL2T", /* 0X025 */
+"FLDLG2", /* 0X026 */
+"FLDLN2", /* 0X027 */
+"FLDPI", /* 0X028 */
+"FLDZ", /* 0X029 */
+"FMUL", /* 0X02A */
+"FMULP", /* 0X02B */
+"FNOP", /* 0X02C */
+"FPATAN", /* 0X02D */
+"FPREM", /* 0X02E */
+"FPREM1", /* 0X02F */
+"FPTAN", /* 0X030 */
+"FRNDINT", /* 0X031 */
+"FRSTOR", /* 0X032 */
+"FSAVE", /* 0X033 */
+"FSCALE", /* 0X034 */
+"FSIN", /* 0X035 */
+"FSINCOS", /* 0X036 */
+"FSQRT", /* 0X037 */
+"FST", /* 0X038 */
+"FSTCW", /* 0X039 */
+"FSTENV", /* 0X03A */
+"FSTP", /* 0X03B */
+"FSTSW", /* 0X03C */
+"FSUB", /* 0X03D */
+"FSUBP", /* 0X03E */
+"FSUBR", /* 0X03F */
+"FSUBRP", /* 0X040 */
+"FTST", /* 0X041 */
+"FUCOM", /* 0X042 */
+"FUCOMP", /* 0X043 */
+"FUCOMPP", /* 0X044 */
+"FXAM", /* 0X045 */
+"FXCH", /* 0X046 */
+"FXTRACT", /* 0X047 */
+"FYL2X", /* 0X048 */
+"FYL2XP1" /* 0X049 */
+};
+
+
+/******************************************************************************
+*
+* Table of the first byte of an instruction
+*
+******************************************************************************/
+TOpcodeData Op1[ 256 ] = {
+{ /* 00 */ _add ,2 ,_Eb ,_Gb ,0 ,0 ,0, DIS_MODRM },
+{ /* 01 */ _add ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 02 */ _add ,2 ,_Gb ,_Eb ,0 ,0 ,0, DIS_MODRM },
+{ /* 03 */ _add ,2 ,_Gv ,_Ev ,0 ,0 ,0, DIS_MODRM },
+{ /* 04 */ _add ,2 ,_AL ,_Ib ,0 ,0 ,0, 0 },
+{ /* 05 */ _add ,2 ,_eAX,_Iv ,0 ,0 ,0, 0 },
+{ /* 06 */ _push ,1 ,_ES ,0 ,0 ,0 ,0, 0 },
+{ /* 07 */ _pop ,1 ,_ES ,0 ,0 ,0 ,0, 0 },
+{ /* 08 */ _or ,2 ,_Eb ,_Gb ,0 ,0 ,0, DIS_MODRM },
+{ /* 09 */ _or ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 0A */ _or ,2 ,_Gb ,_Eb ,0 ,0 ,0, DIS_MODRM },
+{ /* 0B */ _or ,2 ,_Gv ,_Ev ,0 ,0 ,0, DIS_MODRM },
+{ /* 0C */ _or ,2 ,_AL ,_Ib ,0 ,0 ,0, 0 },
+{ /* 0D */ _or ,2 ,_eAX,_Iv ,0 ,0 ,0, 0 },
+{ /* 0E */ _push ,1 ,_CS ,0 ,0 ,0 ,0, 0 },
+{ /* 0F */ _2BESC ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* 10 */ _adc ,2 ,_Eb ,_Gb ,0 ,0 ,0, DIS_MODRM },
+{ /* 11 */ _adc ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 12 */ _adc ,2 ,_Gb ,_Eb ,0 ,0 ,0, DIS_MODRM },
+{ /* 13 */ _adc ,2 ,_Gv ,_Ev ,0 ,0 ,0, DIS_MODRM },
+{ /* 14 */ _adc ,2 ,_AL ,_Ib ,0 ,0 ,0, 0 },
+{ /* 15 */ _adc ,2 ,_eAX,_Iv ,0 ,0 ,0, 0 },
+{ /* 16 */ _push ,1 ,_SS ,0 ,0 ,0 ,0, 0 },
+{ /* 17 */ _pop ,1 ,_SS ,0 ,0 ,0 ,0, 0 },
+{ /* 18 */ _sbb ,2 ,_Eb ,_Gb ,0 ,0 ,0, DIS_MODRM },
+{ /* 19 */ _sbb ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 1A */ _sbb ,2 ,_Gb ,_Eb ,0 ,0 ,0, DIS_MODRM },
+{ /* 1B */ _sbb ,2 ,_Gv ,_Ev ,0 ,0 ,0, DIS_MODRM },
+{ /* 1C */ _sbb ,2 ,_AL ,_Ib ,0 ,0 ,0, 0 },
+{ /* 1D */ _sbb ,2 ,_eAX,_Iv ,0 ,0 ,0, 0 },
+{ /* 1E */ _push ,1 ,_DS ,0 ,0 ,0 ,0, 0 },
+{ /* 1F */ _pop ,1 ,_DS ,0 ,0 ,0 ,0, 0 },
+
+{ /* 20 */ _and ,2 ,_Eb ,_Gb ,0 ,0 ,0, DIS_MODRM },
+{ /* 21 */ _and ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 22 */ _and ,2 ,_Gb ,_Eb ,0 ,0 ,0, DIS_MODRM },
+{ /* 23 */ _and ,2 ,_Gv ,_Ev ,0 ,0 ,0, DIS_MODRM },
+{ /* 24 */ _and ,2 ,_AL ,_Ib ,0 ,0 ,0, 0 },
+{ /* 25 */ _and ,2 ,_eAX,_Iv ,0 ,0 ,0, 0 },
+{ /* 26 */ _S_ES ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 27 */ _daa ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* 28 */ _sub ,2 ,_Eb ,_Gb ,0 ,0 ,0, DIS_MODRM },
+{ /* 29 */ _sub ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 2A */ _sub ,2 ,_Gb ,_Eb ,0 ,0 ,0, DIS_MODRM },
+{ /* 2B */ _sub ,2 ,_Gv ,_Ev ,0 ,0 ,0, DIS_MODRM },
+{ /* 2C */ _sub ,2 ,_AL ,_Ib ,0 ,0 ,0, 0 },
+{ /* 2D */ _sub ,2 ,_eAX,_Iv ,0 ,0 ,0, 0 },
+{ /* 2E */ _S_CS ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 2F */ _das ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+
+{ /* 30 */ _xor ,2 ,_Eb ,_Gb ,0 ,0 ,0, DIS_MODRM },
+{ /* 31 */ _xor ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 32 */ _xor ,2 ,_Gb ,_Eb ,0 ,0 ,0, DIS_MODRM },
+{ /* 33 */ _xor ,2 ,_Gv ,_Ev ,0 ,0 ,0, DIS_MODRM },
+{ /* 34 */ _xor ,2 ,_AL ,_Ib ,0 ,0 ,0, 0 },
+{ /* 35 */ _xor ,2 ,_eAX,_Iv ,0 ,0 ,0, 0 },
+{ /* 36 */ _S_SS ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 37 */ _aaa ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* 38 */ _cmp ,2 ,_Eb ,_Gb ,0 ,0 ,0, DIS_MODRM },
+{ /* 39 */ _cmp ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 3A */ _cmp ,2 ,_Gb ,_Eb ,0 ,0 ,0, DIS_MODRM },
+{ /* 3B */ _cmp ,2 ,_Gv ,_Ev ,0 ,0 ,0, DIS_MODRM },
+{ /* 3C */ _cmp ,2 ,_AL ,_Ib ,0 ,0 ,0, 0 },
+{ /* 3D */ _cmp ,2 ,_eAX,_Iv ,0 ,0 ,0, 0 },
+{ /* 3E */ _S_DS ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 3F */ _aas ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+
+{ /* 40 */ _inc ,1 ,_eAX,0 ,0 ,0 ,0, 0 },
+{ /* 41 */ _inc ,1 ,_eCX,0 ,0 ,0 ,0, 0 },
+{ /* 42 */ _inc ,1 ,_eDX,0 ,0 ,0 ,0, 0 },
+{ /* 43 */ _inc ,1 ,_eBX,0 ,0 ,0 ,0, 0 },
+{ /* 44 */ _inc ,1 ,_eSP,0 ,0 ,0 ,0, 0 },
+{ /* 45 */ _inc ,1 ,_eBP,0 ,0 ,0 ,0, 0 },
+{ /* 46 */ _inc ,1 ,_eSI,0 ,0 ,0 ,0, 0 },
+{ /* 47 */ _inc ,1 ,_eDI,0 ,0 ,0 ,0, 0 },
+{ /* 48 */ _dec ,1 ,_eAX,0 ,0 ,0 ,0, 0 },
+{ /* 49 */ _dec ,1 ,_eCX,0 ,0 ,0 ,0, 0 },
+{ /* 4A */ _dec ,1 ,_eDX,0 ,0 ,0 ,0, 0 },
+{ /* 4B */ _dec ,1 ,_eBX,0 ,0 ,0 ,0, 0 },
+{ /* 4C */ _dec ,1 ,_eSP,0 ,0 ,0 ,0, 0 },
+{ /* 4D */ _dec ,1 ,_eBP,0 ,0 ,0 ,0, 0 },
+{ /* 4E */ _dec ,1 ,_eSI,0 ,0 ,0 ,0, 0 },
+{ /* 4F */ _dec ,1 ,_eDI,0 ,0 ,0 ,0, 0 },
+
+{ /* 50 */ _push ,1 ,_eAX,0 ,0 ,0 ,0, 0 },
+{ /* 51 */ _push ,1 ,_eCX,0 ,0 ,0 ,0, 0 },
+{ /* 52 */ _push ,1 ,_eDX,0 ,0 ,0 ,0, 0 },
+{ /* 53 */ _push ,1 ,_eBX,0 ,0 ,0 ,0, 0 },
+{ /* 54 */ _push ,1 ,_eSP,0 ,0 ,0 ,0, 0 },
+{ /* 55 */ _push ,1 ,_eBP,0 ,0 ,0 ,0, 0 },
+{ /* 56 */ _push ,1 ,_eSI,0 ,0 ,0 ,0, 0 },
+{ /* 57 */ _push ,1 ,_eDI,0 ,0 ,0 ,0, 0 },
+{ /* 58 */ _pop ,1 ,_eAX,0 ,0 ,0 ,0, 0 },
+{ /* 59 */ _pop ,1 ,_eCX,0 ,0 ,0 ,0, 0 },
+{ /* 5A */ _pop ,1 ,_eDX,0 ,0 ,0 ,0, 0 },
+{ /* 5B */ _pop ,1 ,_eBX,0 ,0 ,0 ,0, 0 },
+{ /* 5C */ _pop ,1 ,_eSP,0 ,0 ,0 ,0, 0 },
+{ /* 5D */ _pop ,1 ,_eBP,0 ,0 ,0 ,0, 0 },
+{ /* 5E */ _pop ,1 ,_eSI,0 ,0 ,0 ,0, 0 },
+{ /* 5F */ _pop ,1 ,_eDI,0 ,0 ,0 ,0, 0 },
+
+{ /* 60 */ _pusha ,0 ,0 ,0 ,0 ,0 ,0, DIS_NAME_FLAG },
+{ /* 61 */ _popa ,0 ,0 ,0 ,0 ,0 ,0, DIS_NAME_FLAG },
+{ /* 62 */ _bound ,2 ,_Gv ,_Ma ,0 ,0 ,0, DIS_MODRM },
+{ /* 63 */ _arpl ,2 ,_Ew ,_Rw ,0 ,0 ,0, DIS_MODRM },
+{ /* 64 */ _S_FS ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 65 */ _S_GS ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 66 */ _OPSIZ ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 67 */ _ADSIZ ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 68 */ _push ,1 ,_Iv ,0 ,0 ,0 ,0, 0 },
+{ /* 69 */ _imul ,2 ,_Gv ,_Ev ,_Iv ,0 ,0, DIS_MODRM },
+{ /* 6A */ _push ,1 ,_Ib ,0 ,0 ,0 ,0, 0 },
+{ /* 6B */ _imul ,3 ,_Gv ,_Ev ,_Ib ,0 ,0, DIS_MODRM },
+{ /* 6C */ _insb ,2 ,_Yb ,_DX ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* 6D */ _insw ,2 ,_Yv ,_DX ,0 ,0 ,0, SCAN_TERMINATING | DIS_NAME_FLAG },
+{ /* 6E */ _outsb ,2 ,_DX ,_Xb ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* 6F */ _outsw ,2 ,_DX ,_Xv ,0 ,0 ,0, SCAN_TERMINATING | DIS_NAME_FLAG },
+
+{ /* 70 */ _jo ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 71 */ _jno ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 72 */ _jb ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 73 */ _jnb ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 74 */ _jz ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 75 */ _jnz ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 76 */ _jbe ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 77 */ _jnbe ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 78 */ _js ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 79 */ _jns ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 7A */ _jp ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 7B */ _jnp ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 7C */ _jl ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 7D */ _jnl ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 7E */ _jle ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 7F */ _jnle ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+
+{ /* 80 */ _GRP1a ,2 ,_Eb ,_Ib ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* 81 */ _GRP1b ,2 ,_Ev ,_Iv ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* 82 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 83 */ _GRP1c ,2 ,_Ev ,_Ib ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* 84 */ _test ,2 ,_Eb ,_Gb ,0 ,0 ,0, DIS_MODRM },
+{ /* 85 */ _test ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 86 */ _xchg ,2 ,_Eb ,_Gb ,0 ,0 ,0, DIS_MODRM },
+{ /* 87 */ _xchg ,2 ,_Ev ,_Gv ,0 ,0 ,INSTR_READ_WRITE | INSTR_WORD_DWORD, DIS_MODRM },
+{ /* 88 */ _mov ,2 ,_Eb ,_Gb ,0 ,0 ,INSTR_WRITE | INSTR_BYTE, DIS_MODRM },
+{ /* 89 */ _mov ,2 ,_Ev ,_Gv ,0 ,0 ,INSTR_WRITE | INSTR_WORD, DIS_MODRM },
+{ /* 8A */ _mov ,2 ,_Gb ,_Eb ,0 ,0 ,INSTR_READ | INSTR_BYTE, DIS_MODRM },
+{ /* 8B */ _mov ,2 ,_Gv ,_Ev ,0 ,0 ,0, DIS_MODRM },
+{ /* 8C */ _mov ,2 ,_Ew ,_Sw ,0 ,0 ,0, DIS_MODRM },
+{ /* 8D */ _lea ,2 ,_Gv ,_M ,0 ,0 ,0, DIS_MODRM },
+{ /* 8E */ _mov ,2 ,_Sw ,_Ew ,0 ,0 ,0, SCAN_TERM_PMODE | DIS_MODRM },
+{ /* 8F */ _pop ,1 ,_Ev ,0 ,0 ,0 ,0, DIS_MODRM },
+
+{ /* 90 */ _nop ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* 91 */ _xchg ,2 ,_eCX,_eAX,0 ,0 ,0, 0 },
+{ /* 92 */ _xchg ,2 ,_eDX,_eAX,0 ,0 ,0, 0 },
+{ /* 93 */ _xchg ,2 ,_eBX,_eAX,0 ,0 ,0, 0 },
+{ /* 94 */ _xchg ,2 ,_eSP,_eAX,0 ,0 ,0, 0 },
+{ /* 95 */ _xchg ,2 ,_eBP,_eAX,0 ,0 ,0, 0 },
+{ /* 96 */ _xchg ,2 ,_eSI,_eAX,0 ,0 ,0, 0 },
+{ /* 97 */ _xchg ,2 ,_eDI,_eAX,0 ,0 ,0, 0 },
+{ /* 98 */ _cbw ,0 ,0 ,0 ,0 ,0 ,0, DIS_NAME_FLAG },
+{ /* 99 */ _cwd ,0 ,0 ,0 ,0 ,0 ,0, DIS_NAME_FLAG },
+{ /* 9A */ _call ,1 ,_Ap ,0 ,0 ,0 ,0, SCAN_SINGLE_STEP },
+{ /* 9B */ _wait ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* 9C */ _pushf ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING | DIS_NAME_FLAG },
+{ /* 9D */ _popf ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING | DIS_NAME_FLAG },
+{ /* 9E */ _sahf ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* 9F */ _lahf ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+
+{ /* A0 */ _mov ,2 ,_AL ,_O ,0 ,0 ,0, 0 },
+{ /* A1 */ _mov ,2 ,_eAX,_O ,0 ,0 ,INSTR_READ | INSTR_WORD_DWORD, 0 },
+{ /* A2 */ _mov ,2 ,_O ,_AL ,0 ,0 ,0, 0 },
+{ /* A3 */ _mov ,2 ,_O ,_eAX,0 ,0 ,INSTR_WRITE | INSTR_WORD_DWORD, 0 },
+{ /* A4 */ _movsb ,2 ,_Yb ,_Xb ,0 ,0 ,0, 0 },
+{ /* A5 */ _movsw ,2 ,_Yv ,_Xv ,0 ,0 ,0, DIS_NAME_FLAG },
+{ /* A6 */ _cmpsb ,2 ,_Xb ,_Yb ,0 ,0 ,0, 0 },
+{ /* A7 */ _cmpsw ,2 ,_Xv ,_Yv ,0 ,0 ,0, DIS_NAME_FLAG },
+{ /* A8 */ _test ,2 ,_AL ,_Ib ,0 ,0 ,0, 0 },
+{ /* A9 */ _test ,2 ,_eAX,_Iv ,0 ,0 ,0, 0 },
+{ /* AA */ _stosb ,2 ,_Yb ,_AL ,0 ,0 ,0, 0 },
+{ /* AB */ _stosw ,2 ,_Yb ,_eAX,0 ,0 ,0, DIS_NAME_FLAG },
+{ /* AC */ _lodsb ,2 ,_AL ,_Xb ,0 ,0 ,INSTR_READ | INSTR_BYTE, 0 },
+{ /* AD */ _lodsw ,2 ,_eAX,_Xv ,0 ,0 ,INSTR_READ | INSTR_WORD_DWORD, DIS_NAME_FLAG },
+{ /* AE */ _scasb ,2 ,_AL ,_Xb ,0 ,0 ,0, 0 },
+{ /* AF */ _scasw ,2 ,_eAX,_Xv ,0 ,0 ,0, DIS_NAME_FLAG },
+
+{ /* B0 */ _mov ,2 ,_AL ,_Ib ,0 ,0 ,0, 0 },
+{ /* B1 */ _mov ,2 ,_CL ,_Ib ,0 ,0 ,0, 0 },
+{ /* B2 */ _mov ,2 ,_DL ,_Ib ,0 ,0 ,0, 0 },
+{ /* B3 */ _mov ,2 ,_BL ,_Ib ,0 ,0 ,0, 0 },
+{ /* B4 */ _mov ,2 ,_AH ,_Ib ,0 ,0 ,0, 0 },
+{ /* B5 */ _mov ,2 ,_CH ,_Ib ,0 ,0 ,0, 0 },
+{ /* B6 */ _mov ,2 ,_DH ,_Ib ,0 ,0 ,0, 0 },
+{ /* B7 */ _mov ,2 ,_BH ,_Ib ,0 ,0 ,0, 0 },
+{ /* B8 */ _mov ,2 ,_eAX,_Iv ,0 ,0 ,0, 0 },
+{ /* B9 */ _mov ,2 ,_eCX,_Iv ,0 ,0 ,0, 0 },
+{ /* BA */ _mov ,2 ,_eDX,_Iv ,0 ,0 ,0, 0 },
+{ /* BB */ _mov ,2 ,_eBX,_Iv ,0 ,0 ,0, 0 },
+{ /* BC */ _mov ,2 ,_eSP,_Iv ,0 ,0 ,0, 0 },
+{ /* BD */ _mov ,2 ,_eBP,_Iv ,0 ,0 ,0, 0 },
+{ /* BE */ _mov ,2 ,_eSI,_Iv ,0 ,0 ,0, 0 },
+{ /* BF */ _mov ,2 ,_eDI,_Iv ,0 ,0 ,0, 0 },
+
+{ /* C0 */ _GRP2a ,2 ,_Eb ,_Ib ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* C1 */ _GRP2b ,2 ,_Ev ,_Ib ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* C2 */ _ret ,1 ,_Iw ,0 ,0 ,0 ,0, SCAN_SINGLE_STEP },
+{ /* C3 */ _ret ,0 ,0 ,0 ,0 ,0 ,0, SCAN_SINGLE_STEP },
+{ /* C4 */ _les ,2 ,_Gv ,_Mp ,0 ,0 ,0, SCAN_TERM_PMODE | DIS_MODRM },
+{ /* C5 */ _lds ,2 ,_Gv ,_Mp ,0 ,0 ,0, SCAN_TERM_PMODE | DIS_MODRM },
+{ /* C6 */ _mov ,2 ,_Eb ,_Ib ,0 ,0 ,0, DIS_MODRM },
+{ /* C7 */ _mov ,2 ,_Ev ,_Iv ,0 ,0 ,0, DIS_MODRM },
+{ /* C8 */ _enter ,2 ,_Iw ,_Ib ,0 ,0 ,0, 0 },
+{ /* C9 */ _leave ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* CA */ _retf ,1 ,_Iw ,0 ,0 ,0 ,0, SCAN_SINGLE_STEP },
+{ /* CB */ _retf ,0 ,0 ,0 ,0 ,0 ,0, SCAN_SINGLE_STEP },
+{ /* CC */ _int ,1 ,_3 ,0 ,0 ,0 ,0, 0 },
+{ /* CD */ _int ,1 ,_Ib ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* CE */ _into ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* CF */ _iret ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+
+{ /* D0 */ _GRP2c ,2 ,_Eb ,_1 ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* D1 */ _GRP2d ,2 ,_Ev ,_1 ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* D2 */ _GRP2e ,2 ,_Eb ,_CL ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* D3 */ _GRP2f ,2 ,_Ev ,_CL ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* D4 */ _aam ,1 ,_Ib ,0 ,0 ,0 ,0, 0 },
+{ /* D5 */ _aad ,1 ,_Ib ,0 ,0 ,0 ,0, 0 },
+{ /* D6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D7 */ _xlat ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* D8 */ _EscD8 ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 */ _EscD9 ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA */ _EscDA ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB */ _EscDB ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC */ _EscDC ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD */ _EscDD ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE */ _EscDE ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF */ _EscDF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* E0 */ _loopne ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* E1 */ _loope ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* E2 */ _loop ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* E3 */ _jcxz ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* E4 */ _in ,2 ,_AL ,_Ib ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* E5 */ _in ,2 ,_eAX,_Ib ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* E6 */ _out ,2 ,_Ib ,_AL ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* E7 */ _out ,2 ,_Ib ,_eAX,0 ,0 ,0, SCAN_TERMINATING },
+{ /* E8 */ _call ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* E9 */ _jmp ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_JUMP },
+{ /* EA */ _jmpf ,1 ,_Ap ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* EB */ _jmp ,1 ,_Jb ,0 ,0 ,0 ,0, SCAN_JUMP },
+{ /* EC */ _in ,2 ,_AL ,_DX ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* ED */ _in ,2 ,_eAX,_DX ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* EE */ _out ,2 ,_DX ,_AL ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* EF */ _out ,2 ,_DX ,_eAX,0 ,0 ,0, SCAN_TERMINATING },
+
+{ /* F0 */ _lock ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* F1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* F2 */ _REPNE ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* F3 */ _REP ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* F4 */ _hlt ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* F5 */ _cmc ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* F6 */ _GRP3a ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* F7 */ _GRP3b ,1 ,_Ev ,0 ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* F8 */ _clc ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* F9 */ _stc ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* FA */ _cli ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* FB */ _sti ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* FC */ _cld ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* FD */ _std ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* FE */ _GRP4 ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* FF */ _GRP5 ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM }
+};
+
+
+/******************************************************************************
+*
+* Table of the second byte of an instruction where the first byte was FF,
+* the 2-byte escape code
+*
+******************************************************************************/
+TOpcodeData Op2[ 256 ] = {
+{ /* 0F 00 */ _GRP6 ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* 0F 01 */ _GRP7 ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* 0F 02 */ _lar ,2 ,_Gv ,_Ew ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 03 */ _lsl ,2 ,_Gv ,_Ew ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 04 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 05 */ _loadall ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* 0F 06 */ _clts ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* 0F 07 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 08 */ _invd ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* 0F 09 */ _wbinv ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* 0F 0A */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 0B */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 0C */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 0D */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 0E */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 0F */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* 0F 10 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 11 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 12 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 13 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 14 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 15 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 16 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 17 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 18 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 19 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 1A */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 1B */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 1C */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 1D */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 1E */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 1F */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* 0F 20 */ _mov ,2 ,_Rd ,_Cd ,0 ,0 ,0, SCAN_TERMINATING | DIS_MODRM },
+{ /* 0F 21 */ _mov ,2 ,_Rd ,_Dd ,0 ,0 ,0, SCAN_TERMINATING | DIS_MODRM },
+{ /* 0F 22 */ _mov ,2 ,_Cd ,_Rd ,0 ,0 ,0, SCAN_TERMINATING | DIS_MODRM },
+{ /* 0F 23 */ _mov ,2 ,_Dd ,_Rd ,0 ,0 ,0, SCAN_TERMINATING | DIS_MODRM },
+{ /* 0F 24 */ _mov ,2 ,_Rd ,_Td ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 25 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 26 */ _mov ,2 ,_Td ,_Rd ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 27 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 28 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 29 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 2A */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 2B */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 2C */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 2D */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 2E */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 2F */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* 0F 30 */ _wrmsr ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* 0F 31 */ _rdtsc ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* 0F 32 */ _rdmsr ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* 0F 33 */ _rdpmc ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* 0F 34 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 35 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 36 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 37 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 38 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 39 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 3A */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 3B */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 3C */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 3D */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 3E */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 3F */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* 0F 40 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 41 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 42 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 43 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 44 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 45 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 46 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 47 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 48 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 49 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 4A */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 4B */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 4C */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 4D */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 4E */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 4F */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* 0F 50 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 51 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 52 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 53 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 54 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 55 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 56 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 57 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 58 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 59 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 5A */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 5B */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 5C */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 5D */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 5E */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 5F */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* 0F 60 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 61 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 62 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 63 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 64 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 65 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 66 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 67 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 68 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 69 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 6A */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 6B */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 6C */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 6D */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 6E */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 6F */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* 0F 70 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 71 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 72 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 73 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 74 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 75 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 76 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 77 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 78 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 79 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 7A */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 7B */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 7C */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 7D */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 7E */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F 7F */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* 0F 80 */ _jo ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 81 */ _jno ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 82 */ _jb ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 83 */ _jnb ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 84 */ _jz ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 85 */ _jnz ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 86 */ _jbe ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 87 */ _jnbe ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 88 */ _js ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 89 */ _jns ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 8A */ _jp ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 8B */ _jnp ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 8C */ _jl ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 8D */ _jnl ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 8E */ _jle ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+{ /* 0F 8F */ _jnle ,1 ,_Jv ,0 ,0 ,0 ,0, SCAN_COND_JUMP },
+
+{ /* 0F 90 */ _seto ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 91 */ _setno ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 92 */ _setb ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 93 */ _setnb ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 94 */ _setz ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 95 */ _setnz ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 96 */ _setbe ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 97 */ _setnbe ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 98 */ _sets ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 99 */ _setns ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 9A */ _setp ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 9B */ _setnp ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 9C */ _setl ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 9D */ _setnl ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 9E */ _setle ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F 9F */ _setnle ,1 ,_Eb ,0 ,0 ,0 ,0, DIS_MODRM },
+
+{ /* 0F A0 */ _push ,1 ,_FS ,0 ,0 ,0 ,0, 0 },
+{ /* 0F A1 */ _pop ,1 ,_FS ,0 ,0 ,0 ,0, 0 },
+{ /* 0F A2 */ _cpuid ,0 ,0 ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+{ /* 0F A3 */ _bt ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F A4 */ _shld ,3 ,_Ev ,_Gv ,_Ib ,0 ,0, DIS_MODRM },
+{ /* 0F A5 */ _shld ,3 ,_Ev ,_Gv ,_CL ,0 ,0, DIS_MODRM },
+{ /* 0F A6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F A7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F A8 */ _push ,1 ,_GS ,0 ,0 ,0 ,0, 0 },
+{ /* 0F A9 */ _pop ,1 ,_GS ,0 ,0 ,0 ,0, 0 },
+{ /* 0F AA */ _rsm ,0 ,0 ,0 ,0 ,0 ,0, 0 },
+{ /* 0F AB */ _bts ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F AC */ _shrd ,3 ,_Ev ,_Gv ,_Ib ,0 ,0, DIS_MODRM },
+{ /* 0F AD */ _shrd ,3 ,_Ev ,_Gv ,_CL ,0 ,0, DIS_MODRM },
+{ /* 0F AE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F AF */ _imul ,2 ,_Gv ,_Ev ,0 ,0 ,0, DIS_MODRM },
+
+{ /* 0F B0 */ _cmpx ,2 ,_Eb ,_Gb ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F B1 */ _cmpx ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F B2 */ _lss ,2 ,_Gv ,_Mp ,0 ,0 ,0, SCAN_TERM_PMODE | DIS_MODRM },
+{ /* 0F B3 */ _btr ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F B4 */ _lfs ,2 ,_Gv ,_Mp ,0 ,0 ,0, SCAN_TERM_PMODE | DIS_MODRM },
+{ /* 0F B5 */ _lgs ,2 ,_Gv ,_Mp ,0 ,0 ,0, SCAN_TERM_PMODE | DIS_MODRM },
+{ /* 0F B6 */ _movzx ,2 ,_Gv ,_Eb ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F B7 */ _movzx ,2 ,_Gv ,_Ew ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F B8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F B9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F BA */ _GRP8 ,2 ,_Ev ,_Ib ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* 0F BB */ _btc ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F BC */ _bsf ,2 ,_Gv ,_Ev ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F BD */ _bsr ,2 ,_Gv ,_Ev ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F BE */ _movsx ,2 ,_Gv ,_Eb ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F BF */ _movsx ,2 ,_Gv ,_Ew ,0 ,0 ,0, DIS_MODRM },
+
+{ /* 0F C0 */ _xadd ,2 ,_Eb ,_Gb ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F C1 */ _xadd ,2 ,_Ev ,_Gv ,0 ,0 ,0, DIS_MODRM },
+{ /* 0F C2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F C3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F C4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F C5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F C6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F C7 */ _GRP9 ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL | DIS_MODRM },
+{ /* 0F C8 */ _bswap ,1 ,_eAX,0 ,0 ,0 ,0, 0 },
+{ /* 0F C9 */ _bswap ,1 ,_eCX,0 ,0 ,0 ,0, 0 },
+{ /* 0F CA */ _bswap ,1 ,_eDX,0 ,0 ,0 ,0, 0 },
+{ /* 0F CB */ _bswap ,1 ,_eBX,0 ,0 ,0 ,0, 0 },
+{ /* 0F CC */ _bswap ,1 ,_eSP,0 ,0 ,0 ,0, 0 },
+{ /* 0F CD */ _bswap ,1 ,_eBP,0 ,0 ,0 ,0, 0 },
+{ /* 0F CE */ _bswap ,1 ,_eSI,0 ,0 ,0 ,0, 0 },
+{ /* 0F CF */ _bswap ,1 ,_eDI,0 ,0 ,0 ,0, 0 },
+
+{ /* 0F D0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F D1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F D2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F D3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F D4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F D5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F D6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F D7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F D8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F D9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F DA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F DB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F DC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F DD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F DE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F DF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* 0F E0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F E1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F E2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F E3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F E4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F E5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F E6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F E7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F E8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F E9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F EA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F EB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F EC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F ED */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F EE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F EF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* 0F F0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F F1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F F2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F F3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F F4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F F5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F F6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F F7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F F8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F F9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F FA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F FB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F FC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F FD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F FE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* 0F FF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL }
+};
+
+
+/******************************************************************************
+*
+* Table for Groups codes; groups 1 - 9
+*
+* (These records have DIS_MODRM implied)
+*
+******************************************************************************/
+TOpcodeData Groups[ 17 ][ 8 ] = {
+{{ /* Group 1a */ _add ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 001 */ _or ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 010 */ _adc ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 011 */ _sbb ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 100 */ _and ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 101 */ _sub ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 110 */ _xor ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 111 */ _cmp ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 }},
+
+{{ /* Group 1b */ _add ,2 ,_Ev ,_Iv ,0 ,0 ,0, 0 },
+ { /* 001 */ _or ,2 ,_Ev ,_Iv ,0 ,0 ,0, 0 },
+ { /* 010 */ _adc ,2 ,_Ev ,_Iv ,0 ,0 ,0, 0 },
+ { /* 011 */ _sbb ,2 ,_Ev ,_Iv ,0 ,0 ,0, 0 },
+ { /* 100 */ _and ,2 ,_Ev ,_Iv ,0 ,0 ,0, 0 },
+ { /* 101 */ _sub ,2 ,_Ev ,_Iv ,0 ,0 ,0, 0 },
+ { /* 110 */ _xor ,2 ,_Ev ,_Iv ,0 ,0 ,0, 0 },
+ { /* 111 */ _cmp ,2 ,_Ev ,_Iv ,0 ,0 ,0, 0 }},
+
+{{ /* Group 1c */ _add ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 001 */ _or ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 010 */ _adc ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 011 */ _sbb ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 100 */ _and ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 101 */ _sub ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 110 */ _xor ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 111 */ _cmp ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 }},
+
+{{ /* Group 2a */ _rol ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 001 */ _ror ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 010 */ _rcl ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 011 */ _rcr ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 100 */ _sal ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 101 */ _shr ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 110 */ _shl ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 111 */ _sar ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 }},
+
+{{ /* Group 2b */ _rol ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 001 */ _ror ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 010 */ _rcl ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 011 */ _rcr ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 100 */ _sal ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 101 */ _shr ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 110 */ _shl ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 111 */ _sar ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 }},
+
+{{ /* Group 2c */ _rol ,2 ,_Eb ,_1 ,0 ,0 ,0, 0 },
+ { /* 001 */ _ror ,2 ,_Eb ,_1 ,0 ,0 ,0, 0 },
+ { /* 010 */ _rcl ,2 ,_Eb ,_1 ,0 ,0 ,0, 0 },
+ { /* 011 */ _rcr ,2 ,_Eb ,_1 ,0 ,0 ,0, 0 },
+ { /* 100 */ _sal ,2 ,_Eb ,_1 ,0 ,0 ,0, 0 },
+ { /* 101 */ _shr ,2 ,_Eb ,_1 ,0 ,0 ,0, 0 },
+ { /* 110 */ _shl ,2 ,_Eb ,_1 ,0 ,0 ,0, 0 },
+ { /* 111 */ _sar ,2 ,_Eb ,_1 ,0 ,0 ,0, 0 }},
+
+{{ /* Group 2d */ _rol ,2 ,_Ev ,_1 ,0 ,0 ,0, 0 },
+ { /* 001 */ _ror ,2 ,_Ev ,_1 ,0 ,0 ,0, 0 },
+ { /* 010 */ _rcl ,2 ,_Ev ,_1 ,0 ,0 ,0, 0 },
+ { /* 011 */ _rcr ,2 ,_Ev ,_1 ,0 ,0 ,0, 0 },
+ { /* 100 */ _sal ,2 ,_Ev ,_1 ,0 ,0 ,0, 0 },
+ { /* 101 */ _shr ,2 ,_Ev ,_1 ,0 ,0 ,0, 0 },
+ { /* 110 */ _shl ,2 ,_Ev ,_1 ,0 ,0 ,0, 0 },
+ { /* 111 */ _sar ,2 ,_Ev ,_1 ,0 ,0 ,0, 0 }},
+
+{{ /* Group 2e */ _rol ,2 ,_Eb ,_CL ,0 ,0 ,0, 0 },
+ { /* 001 */ _ror ,2 ,_Eb ,_CL ,0 ,0 ,0, 0 },
+ { /* 010 */ _rcl ,2 ,_Eb ,_CL ,0 ,0 ,0, 0 },
+ { /* 011 */ _rcr ,2 ,_Eb ,_CL ,0 ,0 ,0, 0 },
+ { /* 100 */ _sal ,2 ,_Eb ,_CL ,0 ,0 ,0, 0 },
+ { /* 101 */ _shr ,2 ,_Eb ,_CL ,0 ,0 ,0, 0 },
+ { /* 110 */ _shl ,2 ,_Eb ,_CL ,0 ,0 ,0, 0 },
+ { /* 111 */ _sar ,2 ,_Eb ,_CL ,0 ,0 ,0, 0 }},
+
+{{ /* Group 2f */ _rol ,2 ,_Ev ,_CL ,0 ,0 ,0, 0 },
+ { /* 001 */ _ror ,2 ,_Ev ,_CL ,0 ,0 ,0, 0 },
+ { /* 010 */ _rcl ,2 ,_Ev ,_CL ,0 ,0 ,0, 0 },
+ { /* 011 */ _rcr ,2 ,_Ev ,_CL ,0 ,0 ,0, 0 },
+ { /* 100 */ _sal ,2 ,_Ev ,_CL ,0 ,0 ,0, 0 },
+ { /* 101 */ _shr ,2 ,_Ev ,_CL ,0 ,0 ,0, 0 },
+ { /* 110 */ _shl ,2 ,_Ev ,_CL ,0 ,0 ,0, 0 },
+ { /* 111 */ _sar ,2 ,_Ev ,_CL ,0 ,0 ,0, 0 }},
+
+{{ /* Group 3a */ _test ,2 ,_Eb ,_Ib ,0 ,0 ,0, 0 },
+ { /* 001 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 010 */ _not ,1 ,_Eb ,0 ,0 ,0 ,0, 0 },
+ { /* 011 */ _neg ,1 ,_Eb ,0 ,0 ,0 ,0, 0 },
+ { /* 100 */ _mul ,1 ,_Eb ,0 ,0 ,0 ,0, 0 },
+ { /* 101 */ _imul ,1 ,_Eb ,0 ,0 ,0 ,0, 0 },
+ { /* 110 */ _div ,1 ,_Eb ,0 ,0 ,0 ,0, 0 },
+ { /* 111 */ _idiv ,1 ,_Eb ,0 ,0 ,0 ,0, 0 }},
+
+{{ /* Group 3b */ _test ,2 ,_Ev ,_Iv ,0 ,0 ,0, 0 },
+ { /* 001 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 010 */ _not ,1 ,_Ev ,0 ,0 ,0 ,0, 0 },
+ { /* 011 */ _neg ,1 ,_Ev ,0 ,0 ,0 ,0, 0 },
+ { /* 100 */ _mul ,1 ,_Ev ,0 ,0 ,0 ,0, 0 },
+ { /* 101 */ _imul ,1 ,_Ev ,0 ,0 ,0 ,0, 0 },
+ { /* 110 */ _div ,1 ,_Ev ,0 ,0 ,0 ,0, 0 },
+ { /* 111 */ _idiv ,1 ,_Ev ,0 ,0 ,0 ,0, 0 }},
+
+{{ /* Group 4 */ _inc ,1 ,_Eb ,0 ,0 ,0 ,0, 0 },
+ { /* 001 */ _dec ,1 ,_Eb ,0 ,0 ,0 ,0, 0 },
+ { /* 010 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 011 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 100 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 101 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 110 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 111 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL }},
+
+{{ /* Group 5 */ _inc ,1 ,_Ev ,0 ,0 ,0 ,0, 0 },
+ { /* 001 */ _dec ,1 ,_Ev ,0 ,0 ,0 ,0, 0 },
+ { /* 010 */ _call ,1 ,_Ev ,0 ,0 ,0 ,0, SCAN_SINGLE_STEP },
+ { /* 011 */ _call ,1 ,_Ep ,0 ,0 ,0 ,0, SCAN_SINGLE_STEP },
+ { /* 100 */ _jmp ,1 ,_Ev ,0 ,0 ,0 ,0, SCAN_SINGLE_STEP },
+ { /* 101 */ _jmp ,1 ,_Ep ,0 ,0 ,0 ,0, SCAN_SINGLE_STEP },
+ { /* 110 */ _push ,1 ,_Ev ,0 ,0 ,0 ,0, 0 },
+ { /* 111 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL }},
+
+{{ /* Group 6 */ _sldt ,1 ,_Ew ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+ { /* 001 */ _str ,1 ,_Ew ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+ { /* 010 */ _lldt ,1 ,_Ew ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+ { /* 011 */ _ltr ,1 ,_Ew ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+ { /* 100 */ _verr ,1 ,_Ew ,0 ,0 ,0 ,0, 0 },
+ { /* 101 */ _verw ,1 ,_Ew ,0 ,0 ,0 ,0, 0 },
+ { /* 110 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 111 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL }},
+
+{{ /* Group 7 */ _sgdt ,1 ,_Ms ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+ { /* 001 */ _sidt ,1 ,_Ms ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+ { /* 010 */ _lgdt ,1 ,_Ms ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+ { /* 011 */ _lidt ,1 ,_Ms ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+ { /* 100 */ _smsw ,1 ,_Ew ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+ { /* 101 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 110 */ _lmsw ,1 ,_Ew ,0 ,0 ,0 ,0, SCAN_TERMINATING },
+ { /* 111 */ _invpg ,1 ,_M ,0 ,0 ,0 ,0, SCAN_TERMINATING }},
+
+{{ /* Group 8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 001 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 010 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 011 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 100 */ _bt ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 101 */ _bts ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 110 */ _btr ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 },
+ { /* 111 */ _btc ,2 ,_Ev ,_Ib ,0 ,0 ,0, 0 }},
+
+{{ /* Group 9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 001 */ _cmpx8 ,1 ,_Mq ,0 ,0 ,0 ,0, 0 },
+ { /* 010 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 011 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 100 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 101 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 110 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+ { /* 111 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL }}
+};
+
+
+/******************************************************************************
+*
+* Coprocessor instructions have the prefix byte of D8-DF.
+* The Coproc1 table defines instructions that have the second byte in the
+* range 00-BF
+*
+******************************************************************************/
+TOpcodeData Coproc1[ 8 ][ 8 ] = {
+{{ /* D8 000 */ _fadd ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D8 001 */ _fmul ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D8 010 */ _fcom ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D8 011 */ _fcomp ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D8 100 */ _fsub ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D8 101 */ _fsubr ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D8 110 */ _fdiv ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D8 111 */ _fdivr ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC }},
+
+{{ /* D9 000 */ _fld ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 001 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 010 */ _fst ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 011 */ _fstp ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 100 */ _fldenv ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 101 */ _fldcw ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 110 */ _fstenv ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 111 */ _fstcw ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC }},
+
+{{ /* DA 000 */ _fiadd ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DA 001 */ _fimul ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DA 010 */ _ficom ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DA 011 */ _ficomp ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DA 100 */ _fisub ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DA 101 */ _fisubr ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DA 110 */ _fidiv ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DA 111 */ _fidivr ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC }},
+
+{{ /* DB 000 */ _fild ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DB 001 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB 010 */ _fist ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DB 011 */ _fistp ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DB 100 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB 101 */ _fld ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DB 110 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB 111 */ _fstp ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC }},
+
+{{ /* DC 000 */ _fadd ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DC 001 */ _fmul ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DC 010 */ _fcom ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DC 011 */ _fcomp ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DC 100 */ _fsub ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DC 101 */ _fsubr ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DC 110 */ _fdiv ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DC 111 */ _fdivr ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC }},
+
+{{ /* DD 000 */ _fld ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD 001 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD 010 */ _fst ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD 011 */ _fstp ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD 100 */ _frstor ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD 101 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD 110 */ _fsave ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD 111 */ _fstsw ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC }},
+
+{{ /* DE 000 */ _fiadd ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DE 001 */ _fimul ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DE 010 */ _ficom ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DE 011 */ _ficomp ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DE 100 */ _fisub ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DE 101 */ _fisubr ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DE 110 */ _fidiv ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DE 111 */ _fidivr ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC }},
+
+{{ /* DF 000 */ _fild ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DF 001 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF 010 */ _fist ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DF 011 */ _fistp ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DF 100 */ _fbld ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DF 101 */ _fild ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DF 110 */ _fbstp ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DF 111 */ _fistp ,1 ,_M ,0 ,0 ,0 ,0, DIS_COPROC }}
+};
+
+
+/******************************************************************************
+*
+* The Coproc2 table defines coprocessor instructions that have the second
+* byte in the range C0-FF
+*
+******************************************************************************/
+TOpcodeData Coproc2[ 8 ][ 16 * 4 ] = {
+{{ /* D8 C0 */ _fadd ,2 ,_ST ,_ST0,0 ,0 ,0, DIS_COPROC },
+{ /* D8 C1 */ _fadd ,2 ,_ST ,_ST1,0 ,0 ,0, DIS_COPROC },
+{ /* D8 C2 */ _fadd ,2 ,_ST ,_ST2,0 ,0 ,0, DIS_COPROC },
+{ /* D8 C3 */ _fadd ,2 ,_ST ,_ST3,0 ,0 ,0, DIS_COPROC },
+{ /* D8 C4 */ _fadd ,2 ,_ST ,_ST4,0 ,0 ,0, DIS_COPROC },
+{ /* D8 C5 */ _fadd ,2 ,_ST ,_ST5,0 ,0 ,0, DIS_COPROC },
+{ /* D8 C6 */ _fadd ,2 ,_ST ,_ST6,0 ,0 ,0, DIS_COPROC },
+{ /* D8 C7 */ _fadd ,2 ,_ST ,_ST7,0 ,0 ,0, DIS_COPROC },
+
+{ /* D8 C8 */ _fmul ,2 ,_ST ,_ST0,0 ,0 ,0, DIS_COPROC },
+{ /* D8 C9 */ _fmul ,2 ,_ST ,_ST1,0 ,0 ,0, DIS_COPROC },
+{ /* D8 CA */ _fmul ,2 ,_ST ,_ST2,0 ,0 ,0, DIS_COPROC },
+{ /* D8 CB */ _fmul ,2 ,_ST ,_ST3,0 ,0 ,0, DIS_COPROC },
+{ /* D8 CC */ _fmul ,2 ,_ST ,_ST4,0 ,0 ,0, DIS_COPROC },
+{ /* D8 CD */ _fmul ,2 ,_ST ,_ST5,0 ,0 ,0, DIS_COPROC },
+{ /* D8 CE */ _fmul ,2 ,_ST ,_ST6,0 ,0 ,0, DIS_COPROC },
+{ /* D8 CF */ _fmul ,2 ,_ST ,_ST7,0 ,0 ,0, DIS_COPROC },
+
+{ /* D8 D0 */ _fcom ,2 ,_ST ,_ST0,0 ,0 ,0, DIS_COPROC },
+{ /* D8 D1 */ _fcom ,2 ,_ST ,_ST1,0 ,0 ,0, DIS_COPROC },
+{ /* D8 D2 */ _fcom ,2 ,_ST ,_ST2,0 ,0 ,0, DIS_COPROC },
+{ /* D8 D3 */ _fcom ,2 ,_ST ,_ST3,0 ,0 ,0, DIS_COPROC },
+{ /* D8 D4 */ _fcom ,2 ,_ST ,_ST4,0 ,0 ,0, DIS_COPROC },
+{ /* D8 D5 */ _fcom ,2 ,_ST ,_ST5,0 ,0 ,0, DIS_COPROC },
+{ /* D8 D6 */ _fcom ,2 ,_ST ,_ST6,0 ,0 ,0, DIS_COPROC },
+{ /* D8 D7 */ _fcom ,2 ,_ST ,_ST7,0 ,0 ,0, DIS_COPROC },
+
+{ /* D8 D8 */ _fcomp ,2 ,_ST ,_ST0,0 ,0 ,0, DIS_COPROC },
+{ /* D8 D9 */ _fcomp ,2 ,_ST ,_ST1,0 ,0 ,0, DIS_COPROC },
+{ /* D8 DA */ _fcomp ,2 ,_ST ,_ST2,0 ,0 ,0, DIS_COPROC },
+{ /* D8 DB */ _fcomp ,2 ,_ST ,_ST3,0 ,0 ,0, DIS_COPROC },
+{ /* D8 DC */ _fcomp ,2 ,_ST ,_ST4,0 ,0 ,0, DIS_COPROC },
+{ /* D8 DD */ _fcomp ,2 ,_ST ,_ST5,0 ,0 ,0, DIS_COPROC },
+{ /* D8 DE */ _fcomp ,2 ,_ST ,_ST6,0 ,0 ,0, DIS_COPROC },
+{ /* D8 DF */ _fcomp ,2 ,_ST ,_ST7,0 ,0 ,0, DIS_COPROC },
+
+{ /* D8 E0 */ _fsub ,2 ,_ST ,_ST0,0 ,0 ,0, DIS_COPROC },
+{ /* D8 E1 */ _fsub ,2 ,_ST ,_ST1,0 ,0 ,0, DIS_COPROC },
+{ /* D8 E2 */ _fsub ,2 ,_ST ,_ST2,0 ,0 ,0, DIS_COPROC },
+{ /* D8 E3 */ _fsub ,2 ,_ST ,_ST3,0 ,0 ,0, DIS_COPROC },
+{ /* D8 E4 */ _fsub ,2 ,_ST ,_ST4,0 ,0 ,0, DIS_COPROC },
+{ /* D8 E5 */ _fsub ,2 ,_ST ,_ST5,0 ,0 ,0, DIS_COPROC },
+{ /* D8 E6 */ _fsub ,2 ,_ST ,_ST6,0 ,0 ,0, DIS_COPROC },
+{ /* D8 E7 */ _fsub ,2 ,_ST ,_ST7,0 ,0 ,0, DIS_COPROC },
+
+{ /* D8 E8 */ _fsubr ,2 ,_ST ,_ST0,0 ,0 ,0, DIS_COPROC },
+{ /* D8 E9 */ _fsubr ,2 ,_ST ,_ST1,0 ,0 ,0, DIS_COPROC },
+{ /* D8 EA */ _fsubr ,2 ,_ST ,_ST2,0 ,0 ,0, DIS_COPROC },
+{ /* D8 EB */ _fsubr ,2 ,_ST ,_ST3,0 ,0 ,0, DIS_COPROC },
+{ /* D8 EC */ _fsubr ,2 ,_ST ,_ST4,0 ,0 ,0, DIS_COPROC },
+{ /* D8 ED */ _fsubr ,2 ,_ST ,_ST5,0 ,0 ,0, DIS_COPROC },
+{ /* D8 EE */ _fsubr ,2 ,_ST ,_ST6,0 ,0 ,0, DIS_COPROC },
+{ /* D8 EF */ _fsubr ,2 ,_ST ,_ST7,0 ,0 ,0, DIS_COPROC },
+
+{ /* D8 F0 */ _fdiv ,2 ,_ST ,_ST0,0 ,0 ,0, DIS_COPROC },
+{ /* D8 F1 */ _fdiv ,2 ,_ST ,_ST1,0 ,0 ,0, DIS_COPROC },
+{ /* D8 F2 */ _fdiv ,2 ,_ST ,_ST2,0 ,0 ,0, DIS_COPROC },
+{ /* D8 F3 */ _fdiv ,2 ,_ST ,_ST3,0 ,0 ,0, DIS_COPROC },
+{ /* D8 F4 */ _fdiv ,2 ,_ST ,_ST4,0 ,0 ,0, DIS_COPROC },
+{ /* D8 F5 */ _fdiv ,2 ,_ST ,_ST5,0 ,0 ,0, DIS_COPROC },
+{ /* D8 F6 */ _fdiv ,2 ,_ST ,_ST6,0 ,0 ,0, DIS_COPROC },
+{ /* D8 F7 */ _fdiv ,2 ,_ST ,_ST7,0 ,0 ,0, DIS_COPROC },
+
+{ /* D8 F8 */ _fdivr ,2 ,_ST ,_ST0,0 ,0 ,0, DIS_COPROC },
+{ /* D8 F9 */ _fdivr ,2 ,_ST ,_ST1,0 ,0 ,0, DIS_COPROC },
+{ /* D8 FA */ _fdivr ,2 ,_ST ,_ST2,0 ,0 ,0, DIS_COPROC },
+{ /* D8 FB */ _fdivr ,2 ,_ST ,_ST3,0 ,0 ,0, DIS_COPROC },
+{ /* D8 FC */ _fdivr ,2 ,_ST ,_ST4,0 ,0 ,0, DIS_COPROC },
+{ /* D8 FD */ _fdivr ,2 ,_ST ,_ST5,0 ,0 ,0, DIS_COPROC },
+{ /* D8 FE */ _fdivr ,2 ,_ST ,_ST6,0 ,0 ,0, DIS_COPROC },
+{ /* D8 FF */ _fdivr ,2 ,_ST ,_ST7,0 ,0 ,0, DIS_COPROC }},
+/*----------------------------------------------------*/
+{{ /* D9 C0 */ _fld ,2 ,_ST ,_ST0,0 ,0 ,0, DIS_COPROC },
+{ /* D9 C1 */ _fld ,2 ,_ST ,_ST1,0 ,0 ,0, DIS_COPROC },
+{ /* D9 C2 */ _fld ,2 ,_ST ,_ST2,0 ,0 ,0, DIS_COPROC },
+{ /* D9 C3 */ _fld ,2 ,_ST ,_ST3,0 ,0 ,0, DIS_COPROC },
+{ /* D9 C4 */ _fld ,2 ,_ST ,_ST4,0 ,0 ,0, DIS_COPROC },
+{ /* D9 C5 */ _fld ,2 ,_ST ,_ST5,0 ,0 ,0, DIS_COPROC },
+{ /* D9 C6 */ _fld ,2 ,_ST ,_ST6,0 ,0 ,0, DIS_COPROC },
+{ /* D9 C7 */ _fld ,2 ,_ST ,_ST7,0 ,0 ,0, DIS_COPROC },
+
+{ /* D9 C8 */ _fxch ,2 ,_ST ,_ST0,0 ,0 ,0, DIS_COPROC },
+{ /* D9 C9 */ _fxch ,2 ,_ST ,_ST1,0 ,0 ,0, DIS_COPROC },
+{ /* D9 CA */ _fxch ,2 ,_ST ,_ST2,0 ,0 ,0, DIS_COPROC },
+{ /* D9 CB */ _fxch ,2 ,_ST ,_ST3,0 ,0 ,0, DIS_COPROC },
+{ /* D9 CC */ _fxch ,2 ,_ST ,_ST4,0 ,0 ,0, DIS_COPROC },
+{ /* D9 CD */ _fxch ,2 ,_ST ,_ST5,0 ,0 ,0, DIS_COPROC },
+{ /* D9 CE */ _fxch ,2 ,_ST ,_ST6,0 ,0 ,0, DIS_COPROC },
+{ /* D9 CF */ _fxch ,2 ,_ST ,_ST7,0 ,0 ,0, DIS_COPROC },
+
+{ /* D9 D0 */ _fnop ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 D1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 D2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 D3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 D4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 D5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 D6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 D7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* D9 D8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 D9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 DA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 DB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 DC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 DD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 DE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 DF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* D9 E0 */ _fchs ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 E1 */ _fabs ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 E2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 E3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 E4 */ _ftst ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 E5 */ _fxam ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 E6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* D9 E7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* D9 E8 */ _fld1 ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 E9 */ _fldl2t ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 EA */ _fldl2e ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 EB */ _fldpi ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 EC */ _fldlg2 ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 ED */ _fldln2 ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 EE */ _fldz ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 EF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* D9 F0 */ _f2xm1 ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 F1 */ _fyl2x ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 F2 */ _fptan ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 F3 */ _fpatan ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 F4 */ _fxtract ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 F5 */ _fprem1 ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 F6 */ _fdecstp ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 F7 */ _fincstp ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+
+{ /* D9 F8 */ _fprem ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 F9 */ _fyl2xp1 ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 FA */ _fsqrt ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 FB */ _fsincos ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 FC */ _frndint ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 FD */ _fscale ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 FE */ _fsin ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* D9 FF */ _fcos ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC }},
+/*----------------------------------------------------*/
+{{ /* DA C0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA C1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA C2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA C3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA C4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA C5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA C6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA C7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DA C8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA C9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA CA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA CB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA CC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA CD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA CE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA CF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DA D0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA D1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA D2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA D3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA D4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA D5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA D6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA D7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DA D8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA D9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA DA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA DB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA DC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA DD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA DE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA DF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DA E0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA E1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA E2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA E3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA E4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA E5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA E6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA E7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DA E8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA E9 */ _fucompp ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DA EA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA EB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA EC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA ED */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA EE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA EF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DA F0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA F1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA F2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA F3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA F4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA F5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA F6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA F7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DA F8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA F9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA FA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA FB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA FC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA FD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA FE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DA FF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL }},
+/*----------------------------------------------------*/
+{{ /* DB C0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB C1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB C2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB C3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB C4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB C5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB C6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB C7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DB C8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB C9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB CA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB CB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB CC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB CD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB CE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB CF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DB D0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB D1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB D2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB D3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB D4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB D5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB D6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB D7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DB D8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB D9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB DA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB DB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB DC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB DD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB DE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB DF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DB E0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB E1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB E2 */ _fclex ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DB E3 */ _finit ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DB E4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB E5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB E6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB E7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DB E8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB E9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB EA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB EB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB EC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB ED */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB EE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB EF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DB F0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB F1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB F2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB F3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB F4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB F5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB F6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB F7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DB F8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB F9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB FA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB FB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB FC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB FD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB FE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DB FF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL }},
+/*----------------------------------------------------*/
+{{ /* DC C0 */ _fadd ,2 ,_ST0,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC C1 */ _fadd ,2 ,_ST1,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC C2 */ _fadd ,2 ,_ST2,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC C3 */ _fadd ,2 ,_ST3,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC C4 */ _fadd ,2 ,_ST4,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC C5 */ _fadd ,2 ,_ST5,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC C6 */ _fadd ,2 ,_ST6,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC C7 */ _fadd ,2 ,_ST7,_ST ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DC C8 */ _fmul ,2 ,_ST0,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC C9 */ _fmul ,2 ,_ST1,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC CA */ _fmul ,2 ,_ST2,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC CB */ _fmul ,2 ,_ST3,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC CC */ _fmul ,2 ,_ST4,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC CD */ _fmul ,2 ,_ST5,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC CE */ _fmul ,2 ,_ST6,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC CF */ _fmul ,2 ,_ST7,_ST ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DC D0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC D1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC D2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC D3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC D4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC D5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC D6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC D7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DC D8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC D9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC DA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC DB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC DC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC DD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC DE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DC DF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DC E0 */ _fsubr ,2 ,_ST0,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC E1 */ _fsubr ,2 ,_ST1,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC E2 */ _fsubr ,2 ,_ST2,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC E3 */ _fsubr ,2 ,_ST3,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC E4 */ _fsubr ,2 ,_ST4,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC E5 */ _fsubr ,2 ,_ST5,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC E6 */ _fsubr ,2 ,_ST6,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC E7 */ _fsubr ,2 ,_ST7,_ST ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DC E8 */ _fsub ,2 ,_ST0,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC E9 */ _fsub ,2 ,_ST1,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC EA */ _fsub ,2 ,_ST2,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC EB */ _fsub ,2 ,_ST3,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC EC */ _fsub ,2 ,_ST4,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC ED */ _fsub ,2 ,_ST5,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC EE */ _fsub ,2 ,_ST6,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC EF */ _fsub ,2 ,_ST7,_ST ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DC F0 */ _fdivr ,2 ,_ST0,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC F1 */ _fdivr ,2 ,_ST1,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC F2 */ _fdivr ,2 ,_ST2,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC F3 */ _fdivr ,2 ,_ST3,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC F4 */ _fdivr ,2 ,_ST4,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC F5 */ _fdivr ,2 ,_ST5,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC F6 */ _fdivr ,2 ,_ST6,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC F7 */ _fdivr ,2 ,_ST7,_ST ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DC F8 */ _fdiv ,2 ,_ST0,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC F9 */ _fdiv ,2 ,_ST1,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC FA */ _fdiv ,2 ,_ST2,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC FB */ _fdiv ,2 ,_ST3,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC FC */ _fdiv ,2 ,_ST4,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC FD */ _fdiv ,2 ,_ST5,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC FE */ _fdiv ,2 ,_ST6,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DC FF */ _fdiv ,2 ,_ST7,_ST ,0 ,0 ,0, DIS_COPROC }},
+/*----------------------------------------------------*/
+{{ /* DD C0 */ _ffree ,1 ,_ST0,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD C1 */ _ffree ,1 ,_ST1,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD C2 */ _ffree ,1 ,_ST2,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD C3 */ _ffree ,1 ,_ST3,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD C4 */ _ffree ,1 ,_ST4,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD C5 */ _ffree ,1 ,_ST5,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD C6 */ _ffree ,1 ,_ST6,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD C7 */ _ffree ,1 ,_ST7,0 ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DD C8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD C9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD CA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD CB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD CC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD CD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD CE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD CF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DD D0 */ _fst ,1 ,_ST0,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD D1 */ _fst ,1 ,_ST1,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD D2 */ _fst ,1 ,_ST2,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD D3 */ _fst ,1 ,_ST3,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD D4 */ _fst ,1 ,_ST4,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD D5 */ _fst ,1 ,_ST5,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD D6 */ _fst ,1 ,_ST6,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD D7 */ _fst ,1 ,_ST7,0 ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DD D8 */ _fstp ,1 ,_ST0,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD D9 */ _fstp ,1 ,_ST1,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD DA */ _fstp ,1 ,_ST2,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD DB */ _fstp ,1 ,_ST3,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD DC */ _fstp ,1 ,_ST4,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD DD */ _fstp ,1 ,_ST5,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD DE */ _fstp ,1 ,_ST6,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD DF */ _fstp ,1 ,_ST7,0 ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DD E0 */ _fucom ,2 ,_ST0,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DD E1 */ _fucom ,2 ,_ST1,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DD E2 */ _fucom ,2 ,_ST2,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DD E3 */ _fucom ,2 ,_ST3,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DD E4 */ _fucom ,2 ,_ST4,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DD E5 */ _fucom ,2 ,_ST5,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DD E6 */ _fucom ,2 ,_ST6,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DD E7 */ _fucom ,2 ,_ST7,_ST ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DD E8 */ _fucomp ,1 ,_ST0,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD E9 */ _fucomp ,1 ,_ST1,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD EA */ _fucomp ,1 ,_ST2,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD EB */ _fucomp ,1 ,_ST3,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD EC */ _fucomp ,1 ,_ST4,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD ED */ _fucomp ,1 ,_ST5,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD EE */ _fucomp ,1 ,_ST6,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DD EF */ _fucomp ,1 ,_ST7,0 ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DD F0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD F1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD F2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD F3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD F4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD F5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD F6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD F7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DD F8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD F9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD FA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD FB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD FC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD FD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD FE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DD FF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL }},
+/*----------------------------------------------------*/
+{{ /* DE C0 */ _faddp ,2 ,_ST0,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE C1 */ _faddp ,2 ,_ST1,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE C2 */ _faddp ,2 ,_ST2,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE C3 */ _faddp ,2 ,_ST3,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE C4 */ _faddp ,2 ,_ST4,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE C5 */ _faddp ,2 ,_ST5,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE C6 */ _faddp ,2 ,_ST6,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE C7 */ _faddp ,2 ,_ST7,_ST ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DE C8 */ _fmulp ,2 ,_ST0,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE C9 */ _fmulp ,2 ,_ST1,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE CA */ _fmulp ,2 ,_ST2,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE CB */ _fmulp ,2 ,_ST3,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE CC */ _fmulp ,2 ,_ST4,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE CD */ _fmulp ,2 ,_ST5,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE CE */ _fmulp ,2 ,_ST6,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE CF */ _fmulp ,2 ,_ST7,_ST ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DE D0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE D1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE D2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE D3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE D4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE D5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE D6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE D7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DE D8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE D9 */ _fcompp ,0 ,0 ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DE DA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE DB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE DC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE DD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE DE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DE DF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DE E0 */ _fsubrp ,2 ,_ST0,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE E1 */ _fsubrp ,2 ,_ST1,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE E2 */ _fsubrp ,2 ,_ST2,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE E3 */ _fsubrp ,2 ,_ST3,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE E4 */ _fsubrp ,2 ,_ST4,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE E5 */ _fsubrp ,2 ,_ST5,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE E6 */ _fsubrp ,2 ,_ST6,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE E7 */ _fsubrp ,2 ,_ST7,_ST ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DE E8 */ _fsubp ,2 ,_ST0,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE E9 */ _fsubp ,2 ,_ST1,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE EA */ _fsubp ,2 ,_ST2,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE EB */ _fsubp ,2 ,_ST3,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE EC */ _fsubp ,2 ,_ST4,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE ED */ _fsubp ,2 ,_ST5,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE EE */ _fsubp ,2 ,_ST6,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE EF */ _fsubp ,2 ,_ST7,_ST ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DE F0 */ _fdivrp ,2 ,_ST0,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE F1 */ _fdivrp ,2 ,_ST1,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE F2 */ _fdivrp ,2 ,_ST2,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE F3 */ _fdivrp ,2 ,_ST3,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE F4 */ _fdivrp ,2 ,_ST4,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE F5 */ _fdivrp ,2 ,_ST5,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE F6 */ _fdivrp ,2 ,_ST6,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE F7 */ _fdivrp ,2 ,_ST7,_ST ,0 ,0 ,0, DIS_COPROC },
+
+{ /* DE F8 */ _fdivp ,2 ,_ST0,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE F9 */ _fdivp ,2 ,_ST1,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE FA */ _fdivp ,2 ,_ST2,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE FB */ _fdivp ,2 ,_ST3,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE FC */ _fdivp ,2 ,_ST4,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE FD */ _fdivp ,2 ,_ST5,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE FE */ _fdivp ,2 ,_ST6,_ST ,0 ,0 ,0, DIS_COPROC },
+{ /* DE FF */ _fdivp ,2 ,_ST7,_ST ,0 ,0 ,0, DIS_COPROC }},
+/*----------------------------------------------------*/
+{{ /* DF C0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF C1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF C2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF C3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF C4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF C5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF C6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF C7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DF C8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF C9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF CA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF CB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF CC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF CD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF CE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF CF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DF D0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF D1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF D2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF D3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF D4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF D5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF D6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF D7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DF D8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF D9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF DA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF DB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF DC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF DD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF DE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF DF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DF E0 */ _fstsw ,1 ,_AX ,0 ,0 ,0 ,0, DIS_COPROC },
+{ /* DF E1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF E2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF E3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF E4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF E5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF E6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF E7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DF E8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF E9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF EA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF EB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF EC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF ED */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF EE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF EF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DF F0 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF F1 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF F2 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF F3 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF F4 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF F5 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF F6 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF F7 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+
+{ /* DF F8 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF F9 */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF FA */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF FB */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF FC */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF FD */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF FE */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL },
+{ /* DF FF */ _NDEF ,0 ,0 ,0 ,0 ,0 ,0, DIS_SPECIAL }}
+};
+
+/******************************************************************************
+*
+* Generic messages used by the disassembler
+*
+******************************************************************************/
+char *sBytePtr = "BYTE PTR ";
+char *sWordPtr = "WORD PTR ";
+char *sDwordPtr = "DWORD PTR ";
+char *sFwordPtr = "FWORD PTR ";
+char *sQwordPtr = "QWORD PTR ";
+
+/******************************************************************************
+*
+* Different register messages used by the disassembler
+*
+******************************************************************************/
+char *sGenReg16_32[ 2 ][ 8 ] = {
+{ "AX","CX","DX","BX","SP","BP","SI","DI" },
+{ "EAX","ECX","EDX","EBX","ESP","EBP","ESI","EDI" }
+};
+
+char *sSeg[ 8 ] = {
+"ES","CS","SS","DS","FS","GS","?","?"
+};
+
+char *sSegOverride[ 8 ] = {
+"", "ES:","CS:","SS:","DS:","FS:","GS:","?:"
+};
+
+char *sSegOverrideDefaultES[ 8 ] = {
+"ES:", "ES:","CS:","SS:","DS:","FS:","GS:","?:"
+};
+
+char *sSegOverrideDefaultDS[ 8 ] = {
+"DS:", "ES:","CS:","SS:","DS:","FS:","GS:","?:"
+};
+
+char *sScale[ 4 ] = {
+"", "2*", "4*", "8*"
+};
+
+char *sAdr1[ 2 ][ 8 ] = {
+{ "BX+SI","BX+DI","BP+SI","BP+DI","SI","DI","BP","BX" },
+{ "EAX","ECX","EDX","EBX","?","EBP","ESI","EDI" }
+};
+
+char *sRegs1[ 2 ][ 2 ][ 8 ] = {
+{{ "AL","CL","DL","BL","AH","CH","DH","BH" },
+ { "AX","CX","DX","BX","SP","BP","SI","DI" } },
+{{ "AL","CL","DL","BL","AH","CH","DH","BH" },
+ { "EAX","ECX","EDX","EBX","ESP","EBP","ESI","EDI" } }
+};
+
+char *sRegs2[] = {
+"DX", "AL", "AH", "BL", "BH", "CL", "CH", "DL", "DH", "CS", "DS", "ES", "SS", "FS", "GS"
+};
+
+char *sControl[ 8 ] = {
+"CR0","CR1","CR2","CR3","CR4","?","?","?"
+};
+
+char *sDebug[ 8 ] = {
+"DR0","DR1","DR2","DR3","DR4","DR5","DR6","DR7"
+};
+
+char *sTest[ 8 ] = {
+"?","?","?","?","?","?","TR6","TR7"
+};
+
+char *sYptr[ 2 ] = {
+"[DI]", "[EDI]"
+};
+
+char *sXptr[ 2 ] = {
+"[SI]", "[ESI]"
+};
+
+char *sRep[ 4 ] = {
+"", "REP ", "REPNZ ", "?"
+};
+
+char *sST[ 9 ] = {
+"ST(0)","ST(1)","ST(2)","ST(3)","ST(4)","ST(5)","ST(6)","ST(7)","ST"
+};
+
+
--- /dev/null
+/******************************************************************************
+* *
+* Module: disassemblerdefines.h *
+* *
+* Revision: 1.00 *
+* *
+* Date: 3/17/2000 *
+* *
+* Copyright (c) 2000 Goran Devic *
+* *
+* Author: Goran Devic *
+* *
+*******************************************************************************
+
+ Module Description:
+
+ This is a header file containing the disassembler defines that are
+ used in DisassemblerData.h
+
+*******************************************************************************
+* *
+* Changes: *
+* *
+* DATE DESCRIPTION OF CHANGES AUTHOR *
+* -------- --------------------------------------------------- ----------- *
+* 4/28/2000 Original Goran Devic *
+* 11/4/2000 Modified for LinIce Goran Devic *
+* -------- --------------------------------------------------- ----------- *
+*******************************************************************************
+* Important Defines *
+******************************************************************************/
+#ifndef _DDEF_H_
+#define _DDEF_H_
+
+/******************************************************************************
+*
+* Groups and special codes in place of name index
+*
+******************************************************************************/
+#define _NDEF 0x00 // Udefined/reserved opcode
+#define _2BESC 0x01 // 2 byte escape code
+#define _S_ES 0x02 // Segment ES override | these defines
+#define _S_CS 0x03 // Segment CS override | must have
+#define _S_SS 0x04 // Segment SS override | consecutive
+#define _S_DS 0x05 // Segment DS override | enumeration
+#define _S_FS 0x06 // Segment FS override | numbers.
+#define _S_GS 0x07 // Segment GS override |
+#define _OPSIZ 0x08 // Operand size override
+#define _ADSIZ 0x09 // Address size override
+#define _REPNE 0x0A // REPNE/REPNZ prefix
+#define _REP 0x0B // REP/REPE/REPZ prefix
+#define _EscD8 0x0C // Escape to coprocessor set: prefix D8
+#define _EscD9 0x0D // Escape to coprocessor set: prefix D9
+#define _EscDA 0x0E // Escape to coprocessor set: prefix DA
+#define _EscDB 0x0F // Escape to coprocessor set: prefix DB
+#define _EscDC 0x10 // Escape to coprocessor set: prefix DC
+#define _EscDD 0x11 // Escape to coprocessor set: prefix DD
+#define _EscDE 0x12 // Escape to coprocessor set: prefix DE
+#define _EscDF 0x13 // Escape to coprocessor set: prefix DF
+#define _GRP1a 0x14 // Group 1a extended opcode
+#define _GRP1b 0x15 // Group 1b extended opcode
+#define _GRP1c 0x16 // Group 1c extended opcode
+#define _GRP2a 0x17 // Group 2a extended opcode
+#define _GRP2b 0x18 // Group 2b extended opcode
+#define _GRP2c 0x19 // Group 2c extended opcode
+#define _GRP2d 0x1A // Group 2d extended opcode
+#define _GRP2e 0x1B // Group 2e extended opcode
+#define _GRP2f 0x1C // Group 2f extended opcode
+#define _GRP3a 0x1D // Group 3a extended opcode
+#define _GRP3b 0x1E // Group 3b extended opcode
+#define _GRP4 0x1F // Group 4 extended opcode
+#define _GRP5 0x20 // Group 5 extended opcode
+#define _GRP6 0x21 // Group 6 extended opcode
+#define _GRP7 0x22 // Group 7 extended opcode
+#define _GRP8 0x23 // Group 8 extended opcode
+#define _GRP9 0x24 // Group 9 extended opcode
+
+/******************************************************************************
+*
+* Addressing modes argument definiton for the opcodes in a table
+*
+******************************************************************************/
+#define _O 0x01
+
+#define _Ib 0x03
+#define _Iv 0x04
+#define _Iw 0x05
+#define _Yb 0x06
+#define _Yv 0x07
+#define _Xb 0x08
+#define _Xv 0x09
+#define _Jb 0x0A
+#define _Jv 0x0B
+#define _Ap 0x0C
+#define _1 0x10
+#define _3 0x11
+#define _DX 0x12
+#define _AL 0x13
+#define _AH 0x14
+#define _BL 0x15
+#define _BH 0x16
+#define _CL 0x17
+#define _CH 0x18
+#define _DL 0x19
+#define _DH 0x1A
+#define _CS 0x1B
+#define _DS 0x1C
+#define _ES 0x1D
+#define _SS 0x1E
+#define _FS 0x1F
+#define _GS 0x20
+#define _eAX 0x21
+#define _eCX 0x22
+#define _eDX 0x23
+#define _eBX 0x24
+#define _eSP 0x25
+#define _eBP 0x26
+#define _eSI 0x27
+#define _eDI 0x28
+#define _Eb 0x2F
+#define _Ev 0x30
+#define _Ew 0x31
+#define _Ep 0x32
+#define _Gb 0x33
+#define _Gv 0x34
+#define _M 0x35
+#define _Ma 0x36
+#define _Mp 0x37
+#define _Ms 0x38
+#define _Mq 0x39
+#define _Rd 0x3A
+#define _Rw 0x3B
+#define _Sw 0x3C
+#define _Cd 0x3D
+#define _Dd 0x3E
+#define _Td 0x3F
+#define _ST 0x40
+#define _ST0 0x41
+#define _ST1 0x42
+#define _ST2 0x43
+#define _ST3 0x44
+#define _ST4 0x45
+#define _ST5 0x46
+#define _ST6 0x47
+#define _ST7 0x48
+#define _AX 0x49
+
+/******************************************************************************
+*
+* Define holding structure for opcode
+*
+******************************************************************************/
+
+typedef struct
+{
+ UCHAR name; // Index into the opcode name table
+ UCHAR args; // Number of addressing codes that follow
+ UCHAR dest; // Destination operand addressing code
+ UCHAR src; // Source operand addressing code
+ UCHAR thrid; // Third operand addressing code
+ UCHAR v_instruction; // Virtual instruction index
+ UCHAR access; // Instruction data access type
+ UCHAR flags; // Miscellaneous flags
+} TOpcodeData;
+
+// `access' field:
+// Data access flags are used with memory access instructions
+
+#define INSTR_READ 0x80 // Faulting instruction reads memory
+#define INSTR_WRITE 0x40 // Faulting instruction writes to memory
+#define INSTR_READ_WRITE 0x20 // Faulting instruction is read-modify-write
+
+// Low nibble contains the data length code - do not change these values as
+// they represent the data width value as well
+
+#define INSTR_BYTE 0x01 // Byte access instruction
+#define INSTR_WORD 0x02 // Word access instruction
+#define INSTR_WORD_DWORD 0x03 // Word or dword, depending on operand size
+#define INSTR_DWORD 0x04 // Dword access instruction
+
+// `flags' field:
+// Disassembler flags; bottom 4 bits are used by the scanner flags
+
+#define DIS_SPECIAL 0x80 // Special opcode
+#define DIS_NAME_FLAG 0x40 // Name changes
+#define DIS_GETNAMEFLAG(flags) (((flags)>>6)&1)
+#define DIS_COPROC 0x20 // Coprocessor instruction
+#define DIS_MODRM 0x10 // Use additional Mod R/M byte
+
+// Scanner enums: 4 bits wide
+
+#define SCAN_NATIVE 0x0 // Native instruction are default 0
+#define SCAN_JUMP 0x1 // Evaluate new path
+#define SCAN_COND_JUMP 0x2 // Evaluate both paths
+#define SCAN_TERMINATING 0x3 // Terminating instruction needs virtualization
+#define SCAN_TERM_PMODE 0x4 // Terminating instruction in protected mode only
+#define SCAN_SINGLE_STEP 0x5 // Single-step instruction
+
+// Define values stored in meta pages (bits [7:4])
+
+#define META_NATIVE 0x0 // Native instruction are default 0
+#define META_UNDEF 0x1 // Undefined/illegal instruction
+#define META_TERMINATING 0x2 // Terminating instruction
+#define META_SINGLE_STEP 0x3 // Execute natively single step
+
+/******************************************************************************
+* *
+* Define opcode values for the main table *
+* *
+******************************************************************************/
+#define _aaa 0x001
+#define _aad 0x002
+#define _aam 0x003
+#define _aas 0x004
+#define _adc 0x005
+#define _add 0x006
+#define _and 0x007
+#define _arpl 0x008
+#define _bound 0x009
+#define _bsf 0x00a
+#define _bsr 0x00b
+#define _bt 0x00c
+#define _btc 0x00d
+#define _btr 0x00e
+#define _bts 0x00f
+#define _call 0x010
+#define _cbw 0x011
+#define _cwde 0x012
+#define _clc 0x013
+#define _cld 0x014
+#define _cli 0x015
+#define _clts 0x016
+#define _cmc 0x017
+#define _cmp 0x018
+#define _cmps 0x019
+#define _cmpsb 0x01a
+#define _cmpsw 0x01b
+#define _cmpsd 0x01c
+#define _cwd 0x01d
+#define _cdq 0x01e
+#define _daa 0x01f
+#define _das 0x020
+#define _dec 0x021
+#define _div 0x022
+#define _enter 0x023
+#define _hlt 0x024
+#define _idiv 0x025
+#define _imul 0x026
+#define _in 0x027
+#define _inc 0x028
+#define _ins 0x029
+#define _insb 0x02a
+#define _insw 0x02b
+#define _insd 0x02c
+#define _int 0x02d
+#define _into 0x02e
+#define _iret 0x02f
+#define _iretd 0x030
+#define _jo 0x031
+#define _jno 0x032
+#define _jb 0x033
+#define _jnb 0x034
+#define _jz 0x035
+#define _jnz 0x036
+#define _jbe 0x037
+#define _jnbe 0x038
+#define _js 0x039
+#define _jns 0x03a
+#define _jp 0x03b
+#define _jnp 0x03c
+#define _jl 0x03d
+#define _jnl 0x03e
+#define _jle 0x03f
+#define _jnle 0x040
+#define _jmp 0x041
+#define _lahf 0x042
+#define _lar 0x043
+#define _lea 0x044
+#define _leave 0x045
+#define _lgdt 0x046
+#define _lidt 0x047
+#define _lgs 0x048
+#define _lss 0x049
+#define _lds 0x04a
+#define _les 0x04b
+#define _lfs 0x04c
+#define _lldt 0x04d
+#define _lmsw 0x04e
+#define _lock 0x04f
+#define _lods 0x050
+#define _lodsb 0x051
+#define _lodsw 0x052
+#define _lodsd 0x053
+#define _loop 0x054
+#define _loope 0x055
+#define _loopz 0x056
+#define _loopne 0x057
+#define _loopnz 0x058
+#define _lsl 0x059
+#define _ltr 0x05a
+#define _mov 0x05b
+#define _movs 0x05c
+#define _movsb 0x05d
+#define _movsw 0x05e
+#define _movsd 0x05f
+#define _movsx 0x060
+#define _movzx 0x061
+#define _mul 0x062
+#define _neg 0x063
+#define _nop 0x064
+#define _not 0x065
+#define _or 0x066
+#define _out 0x067
+#define _outs 0x068
+#define _outsb 0x069
+#define _outsw 0x06a
+#define _outsd 0x06b
+#define _pop 0x06c
+#define _popa 0x06d
+#define _popad 0x06e
+#define _popf 0x06f
+#define _popfd 0x070
+#define _push 0x071
+#define _pusha 0x072
+#define _pushad 0x073
+#define _pushf 0x074
+#define _pushfd 0x075
+#define _rcl 0x076
+#define _rcr 0x077
+#define _rol 0x078
+#define _ror 0x079
+#define _rep 0x07a
+#define _repe 0x07b
+#define _repz 0x07c
+#define _repne 0x07d
+#define _repnz 0x07e
+#define _ret 0x07f
+#define _sahf 0x080
+#define _sal 0x081
+#define _sar 0x082
+#define _shl 0x083
+#define _shr 0x084
+#define _sbb 0x085
+#define _scas 0x086
+#define _scasb 0x087
+#define _scasw 0x088
+#define _scasd 0x089
+#define _set 0x08a
+#define _sgdt 0x08b
+#define _sidt 0x08c
+#define _shld 0x08d
+#define _shrd 0x08e
+#define _sldt 0x08f
+#define _smsw 0x090
+#define _stc 0x091
+#define _std 0x092
+#define _sti 0x093
+#define _stos 0x094
+#define _stosb 0x095
+#define _stosw 0x096
+#define _stosd 0x097
+#define _str 0x098
+#define _sub 0x099
+#define _test 0x09a
+#define _verr 0x09b
+#define _verw 0x09c
+#define _wait 0x09d
+#define _xchg 0x09e
+#define _xlat 0x09f
+#define _xlatb 0x0a0
+#define _xor 0x0a1
+#define _jcxz 0x0a2
+#define _loadall 0x0a3
+#define _invd 0x0a4
+#define _wbinv 0x0a5
+#define _seto 0x0a6
+#define _setno 0x0a7
+#define _setb 0x0a8
+#define _setnb 0x0a9
+#define _setz 0x0aa
+#define _setnz 0x0ab
+#define _setbe 0x0ac
+#define _setnbe 0x0ad
+#define _sets 0x0ae
+#define _setns 0x0af
+#define _setp 0x0b0
+#define _setnp 0x0b1
+#define _setl 0x0b2
+#define _setnl 0x0b3
+#define _setle 0x0b4
+#define _setnle 0x0b5
+#define _wrmsr 0x0b6
+#define _rdtsc 0x0b7
+#define _rdmsr 0x0b8
+#define _cpuid 0x0b9
+#define _rsm 0x0ba
+#define _cmpx 0x0bb
+#define _xadd 0x0bc
+#define _bswap 0x0bd
+#define _invpg 0x0be
+#define _cmpx8 0x0bf
+#define _jmpf 0x0c0
+#define _retf 0x0c1
+#define _rdpmc 0x0c2
+
+#define _f2xm1 0x001
+#define _fabs 0x002
+#define _fadd 0x003
+#define _faddp 0x004
+#define _fbld 0x005
+#define _fbstp 0x006
+#define _fchs 0x007
+#define _fclex 0x008
+#define _fcom 0x009
+#define _fcomp 0x00a
+#define _fcompp 0x00b
+#define _fcos 0x00c
+#define _fdecstp 0x00d
+#define _fdiv 0x00e
+#define _fdivp 0x00f
+#define _fdivr 0x010
+#define _fdivrp 0x011
+#define _ffree 0x012
+#define _fiadd 0x013
+#define _ficom 0x014
+#define _ficomp 0x015
+#define _fidiv 0x016
+#define _fidivr 0x017
+#define _fild 0x018
+#define _fimul 0x019
+#define _fincstp 0x01a
+#define _finit 0x01b
+#define _fist 0x01c
+#define _fistp 0x01d
+#define _fisub 0x01e
+#define _fisubr 0x01f
+#define _fld 0x020
+#define _fld1 0x021
+#define _fldcw 0x022
+#define _fldenv 0x023
+#define _fldl2e 0x024
+#define _fldl2t 0x025
+#define _fldlg2 0x026
+#define _fldln2 0x027
+#define _fldpi 0x028
+#define _fldz 0x029
+#define _fmul 0x02a
+#define _fmulp 0x02b
+#define _fnop 0x02c
+#define _fpatan 0x02d
+#define _fprem 0x02e
+#define _fprem1 0x02f
+#define _fptan 0x030
+#define _frndint 0x031
+#define _frstor 0x032
+#define _fsave 0x033
+#define _fscale 0x034
+#define _fsin 0x035
+#define _fsincos 0x036
+#define _fsqrt 0x037
+#define _fst 0x038
+#define _fstcw 0x039
+#define _fstenv 0x03a
+#define _fstp 0x03b
+#define _fstsw 0x03c
+#define _fsub 0x03d
+#define _fsubp 0x03e
+#define _fsubr 0x03f
+#define _fsubrp 0x040
+#define _ftst 0x041
+#define _fucom 0x042
+#define _fucomp 0x043
+#define _fucompp 0x044
+#define _fxam 0x045
+#define _fxch 0x046
+#define _fxtract 0x047
+#define _fyl2x 0x048
+#define _fyl2xp1 0x049
+
+/******************************************************************************
+*
+* External data and strings
+*
+******************************************************************************/
+extern char* sNames[];
+extern char* sCoprocNames[];
+extern TOpcodeData Op1[ 256 ];
+extern TOpcodeData Op2[ 256 ];
+extern TOpcodeData Groups[ 17 ][ 8 ];
+extern TOpcodeData Coproc1[ 8 ][ 8 ];
+extern TOpcodeData Coproc2[ 8 ][ 16 * 4 ];
+extern char *sBytePtr;
+extern char *sWordPtr;
+extern char *sDwordPtr;
+extern char *sFwordPtr;
+extern char *sQwordPtr;
+extern char *sGenReg16_32[ 2 ][ 8 ];
+extern char *sSeg[ 8 ];
+extern char *sSegOverride[ 8 ];
+extern char *sSegOverrideDefaultES[ 8 ];
+extern char *sSegOverrideDefaultDS[ 8 ];
+extern char *sScale[ 4 ];
+extern char *sAdr1[ 2 ][ 8 ];
+extern char *sRegs1[ 2 ][ 2 ][ 8 ];
+extern char *sRegs2[];
+extern char *sControl[ 8 ];
+extern char *sDebug[ 8 ];
+extern char *sTest[ 8 ];
+extern char *sYptr[ 2 ];
+extern char *sXptr[ 2 ];
+extern char *sRep[ 4 ];
+extern char *sST[ 9 ];
+
+
+#endif // _DDEF_H_
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ GPFault.c
+
+Abstract:
+
+ handle general protection faults on x86
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 13-Nov-1999: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+
+////////////////////////////////////////////////////
+// GLOBALS
+////
+ULONG OldGPFaultHandler = 0;
+
+char tempGP[1024];
+
+////////////////////////////////////////////////////
+// FUNCTIONS
+////
+
+//*************************************************************************
+// NewGPFaultHandler()
+//
+//*************************************************************************
+void HandleGPFault(FRAME* ptr)
+{
+ DPRINT((0,"HandleGPFault(): ptr = %x at eip: %x\n",ptr, ptr->eip));
+}
+
+//*************************************************************************
+// NewGPFaultHandler()
+//
+//*************************************************************************
+__asm__ ("\n\t \
+ NewGPFaultHandler:\n\t \
+ pushfl\n\t \
+ cli\n\t \
+ cld\n\t \
+ pushal\n\t \
+ pushl %ds\n\t \
+\n\t \
+ // test for v86 mode\n\t \
+ testl $0x20000,40(%esp)\n\t \
+ jnz notv86\n\t \
+ popl %ds\n\t \
+ popal\n\t \
+ popfl\n\t \
+ .byte 0x2e\n\t \
+ jmp *_OldGPFaultHandler\n\t \
+ notv86:\n\t \
+ // setup default data selectors\n\t \
+ movw %ss,%ax\n\t \
+ movw %ax,%ds\n\t \
+\n\t \
+ // get frame ptr\n\t \
+ lea 40(%esp),%eax\n\t \
+ pushl %eax\n\t \
+ call _HandleGPFault\n\t \
+ addl $4,%esp\n\t \
+\n \t \
+ popl %ds\n\t \
+ popal\n\t \
+ popfl\n\t \
+ // remove error code from stack and replace with reason code\n\t \
+ movl $" STR(REASON_GP_FAULT) ",(%esp)\n\t \
+ // call debugger loop\n\t \
+ jmp NewInt31Handler\n\t \
+ ");
+
+//*************************************************************************
+// InstallGPFaultHook()
+//
+//*************************************************************************
+void InstallGPFaultHook(void)
+{
+ ULONG LocalGPFaultHandler;
+
+ ENTER_FUNC();
+
+ MaskIrqs();
+ if(!OldGPFaultHandler)
+ {
+ __asm__("mov $NewGPFaultHandler,%0"
+ :"=r" (LocalGPFaultHandler)
+ :
+ :"eax");
+ OldGPFaultHandler=SetGlobalInt(0x0D,(ULONG)LocalGPFaultHandler);
+ }
+ UnmaskIrqs();
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// DeInstallGPFaultHook()
+//
+//*************************************************************************
+void DeInstallGPFaultHook(void)
+{
+ ENTER_FUNC();
+
+ MaskIrqs();
+ if(OldGPFaultHandler)
+ {
+ RemoveAllSWBreakpoints(TRUE);
+ SetGlobalInt(0x0D,(ULONG)OldGPFaultHandler);
+ OldGPFaultHandler=0;
+ }
+ UnmaskIrqs();
+
+ LEAVE_FUNC();
+}
+
+// EOF
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ gpfault.h
+
+Abstract:
+
+ HEADER for gpfault.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+void InstallGPFaultHook(void);
+void DeInstallGPFaultHook(void);
+
+extern ULONG OldGPFaultHandler;
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ hardware.c
+
+Abstract:
+
+ output to console
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 04-Aug-1998: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+
+////////////////////////////////////////////////////
+// PROTOTYPES
+////
+
+////////////////////////////////////////////////////
+// DEFINES
+////
+
+////////////////////////////////////////////////////
+// GLOBALS
+////
+
+// flagging stuff
+BOOLEAN bCursorEnabled = FALSE;
+BOOLEAN bConsoleIsInitialized = FALSE;
+
+
+// terminal emulation
+ETERMINALMODE eTerminalMode = TERMINAL_MODE_NONE;
+
+// window stuff
+WINDOW wWindow[4];
+
+// screen parameter
+ULONG GLOBAL_SCREEN_WIDTH,GLOBAL_SCREEN_HEIGHT;
+
+// jump table to real output functions
+OUTPUT_HANDLERS ohandlers;
+INPUT_HANDLERS ihandlers;
+
+// ring buffer stuff
+ULONG ulInPos = 0,ulLastPos = 0;
+ULONG ulOldInPos = 0,ulOldDelta = 0;
+BOOLEAN bSuspendPrintRingBuffer = FALSE;
+
+char aBuffers[LINES_IN_BUFFER][1024];
+
+// output lock
+ULONG ulOutputLock;
+
+// color of windows pane separation bars
+USHORT usCaptionColor = BLUE;
+USHORT usCaptionText = WHITE;
+USHORT usForegroundColor = LTGRAY;
+USHORT usBackgroundColor = BLACK;
+USHORT usHiLiteColor = WHITE;
+
+////////////////////////////////////////////////////
+// FUNCTIONS
+////
+
+//*************************************************************************
+// SuspendPrintRingBuffer()
+//
+//*************************************************************************
+void SuspendPrintRingBuffer(BOOLEAN bSuspend)
+{
+ ENTER_FUNC();
+ bSuspendPrintRingBuffer = bSuspend;
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// EmptyRingBuffer()
+//
+//*************************************************************************
+void EmptyRingBuffer(void)
+{
+ //ENTER_FUNC();
+ ulLastPos = ulInPos = ulOldInPos = ulOldDelta = 0;
+ PICE_memset(aBuffers,0,sizeof(aBuffers));
+ //LEAVE_FUNC();
+}
+
+//*************************************************************************
+// LinesInRingBuffer()
+//
+//*************************************************************************
+ULONG LinesInRingBuffer(void)
+{
+ ULONG ulResult;
+
+// ENTER_FUNC();
+
+ ulResult = (ulInPos-ulLastPos)%LINES_IN_BUFFER;
+
+// LEAVE_FUNC();
+
+ return ulResult;
+}
+
+//*************************************************************************
+// CheckRingBuffer()
+//
+//*************************************************************************
+void CheckRingBuffer(void)
+{
+// ENTER_FUNC();
+
+ Acquire_Output_Lock();
+
+ if(ulInPos != ulOldInPos )
+ {
+ ulOldInPos = ulInPos;
+ PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
+ }
+
+ Release_Output_Lock();
+
+// LEAVE_FUNC();
+}
+
+//*************************************************************************
+// AddToRingBuffer()
+//
+//*************************************************************************
+BOOLEAN AddToRingBuffer(LPSTR p)
+{
+ ULONG i,j,len;
+ BOOLEAN bHadReturn = FALSE;
+ char temp[sizeof(aBuffers[0])];
+
+// ENTER_FUNC();
+
+ // size of current string
+ j=PICE_strlen(aBuffers[ulInPos]);
+
+ // start with ':' and current has ':' in front
+ if(aBuffers[ulInPos][0]==':' && *p==':')
+ {
+ if(j==1)
+ {
+ //LEAVE_FUNC();
+ return FALSE;
+ }
+ aBuffers[ulInPos][j++]='\n';
+ aBuffers[ulInPos][j]=0;
+ ulInPos = (ulInPos+1)%LINES_IN_BUFFER;
+ // wrap around
+ if(ulInPos == ulLastPos)
+ {
+ ulLastPos = (ulLastPos+1)%LINES_IN_BUFFER;
+ PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
+ }
+ // reset to start of buffer
+ j = 0;
+ }
+ // it's an internal print ("pICE: ...")
+ else if(aBuffers[ulInPos][0]==':' && PICE_strncmpi(p,"pICE:",5)==0)
+ {
+ if(j==1)
+ {
+ PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
+ }
+ else
+ {
+ aBuffers[ulInPos][j++]='\n';
+ aBuffers[ulInPos][j]=0;
+ ulInPos = (ulInPos+1)%LINES_IN_BUFFER;
+ // wrap around
+ if(ulInPos == ulLastPos)
+ {
+ ulLastPos = (ulLastPos+1)%LINES_IN_BUFFER;
+ PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
+ }
+ }
+ // reset to start of buffer
+ j = 0;
+ }
+ // it's a debug print and the current line is starting with ':'
+ else if(aBuffers[ulInPos][0]==':' &&
+ ( (*p=='<' && PICE_isdigit(*(p+1)) && *(p+2)=='>') || bIsDebugPrint) )
+ {
+ if(j==1)
+ {
+ PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
+ }
+ else
+ {
+ aBuffers[ulInPos][j++]='\n';
+ aBuffers[ulInPos][j]=0;
+ ulInPos = (ulInPos+1)%LINES_IN_BUFFER;
+ // wrap around
+ if(ulInPos == ulLastPos)
+ {
+ ulLastPos = (ulLastPos+1)%LINES_IN_BUFFER;
+ PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
+ }
+ }
+ // reset to start of buffer
+ j = 0;
+ }
+ // it's a debug print
+ else if(( (*p=='<' && PICE_isdigit(*(p+1)) && *(p+2)=='>') || bIsDebugPrint) )
+ {
+ p += 3;
+ }
+
+ // size of new string
+ len=PICE_strlen(p);
+
+ // if combined string length too big
+ // reduce to maximum
+ if( (len+j) > sizeof(aBuffers[0])-2 )
+ {
+ PICE_memcpy(temp,p,sizeof(aBuffers[0])-2);
+ p = temp;
+ // assume we end in NEWLINE
+ p[sizeof(aBuffers[0])-2]='\n';
+ p[sizeof(aBuffers[0])-1]=0;
+ }
+
+ for(i=0;p[i]!=0;i++)
+ {
+ // newline
+ if(p[i]=='\n')
+ {
+ aBuffers[ulInPos][j++]='\n';
+ aBuffers[ulInPos][j]=0;
+ ulInPos = (ulInPos+1)%LINES_IN_BUFFER;
+ // wrap around
+ if(ulInPos == ulLastPos)
+ {
+ ulLastPos = (ulLastPos+1)%LINES_IN_BUFFER;
+ PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
+ }
+ // reset to start of buffer
+ j = 0;
+ // notify that we had a NEWLINE
+ bHadReturn = TRUE;
+ }
+ // backspace
+ else if(p[i]=='\b')
+ {
+ if(j!=0)
+ {
+ j--;
+ aBuffers[ulInPos][j] = 0;
+ }
+ }
+ // TAB
+ else if(p[i]=='\t')
+ {
+ // copy TAB
+ aBuffers[ulInPos][j++] = p[i];
+ }
+ else
+ {
+ if((UCHAR)p[i]<0x20 && (UCHAR)p[i]>0x7f)
+ p[i]=0x20;
+
+ aBuffers[ulInPos][j++] = p[i];
+ }
+ }
+// LEAVE_FUNC();
+
+ return bHadReturn;
+}
+
+//*************************************************************************
+// ReplaceRingBufferCurrent()
+//
+//*************************************************************************
+void ReplaceRingBufferCurrent(LPSTR s)
+{
+// ENTER_FUNC();
+
+ PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
+ PICE_strcpy(aBuffers[ulInPos],s);
+
+// LEAVE_FUNC();
+}
+
+//*************************************************************************
+// PrintRingBuffer()
+//
+//*************************************************************************
+void PrintRingBuffer(ULONG ulLines)
+{
+ ULONG ulDelta = LinesInRingBuffer();
+ ULONG ulOutPos,i=0;
+
+// ENTER_FUNC();
+
+ if(bSuspendPrintRingBuffer)
+ {
+ DPRINT((0,"PrintRingBuffer(): suspended\n"));
+ LEAVE_FUNC();
+ return;
+ }
+
+ if(!ulDelta)
+ {
+ DPRINT((0,"PrintRingBuffer(): no lines in ring buffer\n"));
+ LEAVE_FUNC();
+ return;
+ }
+
+ if(ulDelta<ulOldDelta)
+ {
+ DPRINT((0,"PrintRingBuffer(): lines already output\n"));
+ LEAVE_FUNC();
+ return;
+ }
+
+ ulOldDelta = ulDelta;
+
+ if(ulDelta < ulLines)
+ {
+ DPRINT((0,"PrintRingBuffer(): less lines than requested: ulDelta: %x, ulLines: %x\n", ulDelta, ulLines));
+ ulLines = ulDelta;
+ }
+
+ ulOutPos = (ulInPos-ulLines)%LINES_IN_BUFFER;
+ DPRINT((0,"PrintRingBuffer(): ulOutPos = %u\n",ulOutPos));
+
+ Home(OUTPUT_WINDOW);
+
+ while(ulLines--)
+ {
+ ClrLine(wWindow[OUTPUT_WINDOW].y+i);
+ Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulOutPos]);
+ i++;
+ ulOutPos = (ulOutPos+1)%LINES_IN_BUFFER;
+ }
+
+ if(aBuffers[ulOutPos][0]==':')
+ {
+ ClrLine(wWindow[OUTPUT_WINDOW].y+i);
+ Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulOutPos]);
+ wWindow[OUTPUT_WINDOW].usCurX = 1;
+ }
+
+// LEAVE_FUNC();
+}
+
+//*************************************************************************
+// PrintRingBufferOffset()
+//
+//*************************************************************************
+BOOLEAN PrintRingBufferOffset(ULONG ulLines,ULONG ulOffset)
+{
+ ULONG ulLinesInRingBuffer = LinesInRingBuffer();
+ ULONG ulOutPos,i=0;
+
+// ENTER_FUNC();
+
+ // no lines in ring buffer
+ if(!ulLinesInRingBuffer)
+ {
+ DPRINT((0,"PrintRingBufferOffset(): ulLinesInRingBuffer is 0\n"));
+ LEAVE_FUNC();
+ return FALSE;
+ }
+
+ // more lines inc. offset to display than in ring buffer
+ if(ulLinesInRingBuffer < ulLines)
+ {
+ ulLines = ulLinesInRingBuffer;
+ }
+
+ if(ulLinesInRingBuffer < ulOffset+ulLines)
+ {
+ DPRINT((0,"PrintRingBufferOffset(): ulLinesInRingBuffer < ulOffset+ulLines\n"));
+ LEAVE_FUNC();
+ return FALSE;
+ }
+
+ DPRINT((0,"PrintRingBufferOffset(): ulLinesInRingBuffer %u ulLines %u ulOffset %u\n",ulLinesInRingBuffer,ulLines,ulOffset));
+
+ ulOutPos = (ulInPos-ulOffset-ulLines)%LINES_IN_BUFFER;
+
+ DPRINT((0,"PrintRingBufferOffset(): ulOutPos = %u\n",ulOutPos));
+
+ if(ulOutPos == ulInPos)
+ {
+ DPRINT((0,"PrintRingBufferOffset(): ulOutPos == ulInPos\n"));
+ LEAVE_FUNC();
+ return FALSE;
+ }
+
+ // start to output upper left corner of window
+ Home(OUTPUT_WINDOW);
+
+ // while not end reached...
+ while(ulLines--)
+ {
+ ClrLine(wWindow[OUTPUT_WINDOW].y+i);
+ Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulOutPos]);
+ i++;
+ ulOutPos = (ulOutPos+1)%LINES_IN_BUFFER;
+ }
+
+ if(aBuffers[ulInPos][0]==':')
+ {
+ ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy-1);
+ wWindow[OUTPUT_WINDOW].usCurY = wWindow[OUTPUT_WINDOW].cy-1;
+ Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulInPos]);
+ wWindow[OUTPUT_WINDOW].usCurX = PICE_strlen(aBuffers[ulInPos])+1;
+ }
+
+// LEAVE_FUNC();
+ return TRUE;
+}
+
+//*************************************************************************
+// PrintRingBufferHome()
+//
+//*************************************************************************
+BOOLEAN PrintRingBufferHome(ULONG ulLines)
+{
+ ULONG ulDelta = LinesInRingBuffer();
+ ULONG ulOutPos,i=0;
+
+// ENTER_FUNC();
+
+ // no lines in ring buffer
+ if(!ulDelta)
+ {
+ DPRINT((0,"PrintRingBufferHome(): no lines in ring buffer\n"));
+ LEAVE_FUNC();
+ return FALSE;
+ }
+
+ // more lines inc. offset to display than in ring buffer
+ if(ulDelta < ulLines)
+ {
+ ulLines = ulDelta;
+ }
+
+ // calc the start out position
+ ulOutPos = ulLastPos;
+
+ // start to output upper left corner of window
+ Home(OUTPUT_WINDOW);
+
+ // while not end reached...
+ while(ulLines--)
+ {
+ ClrLine(wWindow[OUTPUT_WINDOW].y+i);
+ Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulOutPos]);
+ i++;
+ ulOutPos = (ulOutPos+1)%LINES_IN_BUFFER;
+ }
+
+ if(aBuffers[ulInPos][0]==':')
+ {
+ ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy-1);
+ wWindow[OUTPUT_WINDOW].usCurY = wWindow[OUTPUT_WINDOW].cy-1;
+ Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulInPos]);
+ wWindow[OUTPUT_WINDOW].usCurX = PICE_strlen(aBuffers[ulInPos])+1;
+ }
+
+// LEAVE_FUNC();
+
+ return TRUE;
+}
+
+//*************************************************************************
+// ResetColor()
+//
+//*************************************************************************
+void ResetColor(void)
+{
+ SetForegroundColor(COLOR_FOREGROUND);
+ SetBackgroundColor(COLOR_BACKGROUND);
+}
+
+// OUTPUT handlers
+
+//*************************************************************************
+// PrintGraf()
+//
+//*************************************************************************
+void PrintGraf(ULONG x,ULONG y,UCHAR c)
+{
+ ohandlers.PrintGraf(x,y,c);
+}
+
+//*************************************************************************
+// Flush()
+//
+// Flush the stream of chars to PrintGraf()
+//*************************************************************************
+void Flush(void)
+{
+ if(ohandlers.Flush)
+ ohandlers.Flush();
+}
+
+//*************************************************************************
+// EnableScroll()
+//
+//*************************************************************************
+void EnableScroll(USHORT Window)
+{
+ ENTER_FUNC();
+ wWindow[Window].bScrollDisabled=FALSE;
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// DisableScroll()
+//
+//*************************************************************************
+void DisableScroll(USHORT Window)
+{
+ ENTER_FUNC();
+ wWindow[Window].bScrollDisabled=TRUE;
+ LEAVE_FUNC();
+}
+
+
+//*************************************************************************
+// ShowCursor()
+//
+// show hardware cursor
+//*************************************************************************
+void ShowCursor(void)
+{
+ ohandlers.ShowCursor();
+}
+
+//*************************************************************************
+// HideCursor()
+//
+// hide hardware cursor
+//*************************************************************************
+void HideCursor(void)
+{
+ ohandlers.HideCursor();
+}
+
+//*************************************************************************
+// SetForegroundColor()
+//
+// set foreground color
+//*************************************************************************
+void SetForegroundColor(ECOLORS c)
+{
+// ENTER_FUNC();
+
+ ohandlers.SetForegroundColor(c);
+
+// LEAVE_FUNC();
+}
+
+//*************************************************************************
+// SetBackgroundColor()
+//
+// set background color
+//*************************************************************************
+void SetBackgroundColor(ECOLORS c)
+{
+// ENTER_FUNC();
+
+ ohandlers.SetBackgroundColor(c);
+
+// LEAVE_FUNC();
+}
+
+//*************************************************************************
+// PutChar()
+//
+// put a zero terminated string at position (x,y)
+//*************************************************************************
+void PutChar(LPSTR p,ULONG x,ULONG y)
+{
+ ULONG i;
+
+// ENTER_FUNC();
+
+ Acquire_Output_Lock();
+
+ for(i=0;p[i]!=0;i++)
+ {
+ if((UCHAR)p[i]>=0x20 && (UCHAR)p[i]<0x80)
+ {
+ PrintGraf(x+i,y,p[i]);
+ }
+ }
+
+ Flush();
+
+ Release_Output_Lock();
+
+// LEAVE_FUNC();
+}
+
+//*************************************************************************
+// CopyLineTo()
+//
+// copy a line from src to dest
+//*************************************************************************
+void CopyLineTo(USHORT dest,USHORT src)
+{
+ ohandlers.CopyLineTo(dest,src);
+}
+
+//*************************************************************************
+// InvertLine()
+//
+// invert a line on the screen
+//*************************************************************************
+void InvertLine(ULONG line)
+{
+ ohandlers.InvertLine(line);
+}
+
+//*************************************************************************
+// HatchLine()
+//
+// hatches a line on the screen
+//*************************************************************************
+void HatchLine(ULONG line)
+{
+ ohandlers.HatchLine(line);
+}
+
+//*************************************************************************
+// ClrLine()
+//
+// clear a line on the screen
+//*************************************************************************
+void ClrLine(ULONG line)
+{
+ ohandlers.ClrLine(line);
+}
+
+//*************************************************************************
+// ScrollUp()
+//
+// Scroll a specific window up one line
+//*************************************************************************
+void ScrollUp(USHORT Window)
+{
+ USHORT i;
+
+ return;
+
+ if(!wWindow[Window].bScrollDisabled)
+ {
+ for(i=1;i<wWindow[Window].cy;i++)
+ {
+ CopyLineTo((USHORT)(wWindow[Window].y+i-1),(USHORT)(wWindow[Window].y+i));
+ }
+ ClrLine((USHORT)(wWindow[Window].y+wWindow[Window].cy-1));
+ }
+}
+
+//*************************************************************************
+// Home()
+//
+// cursor to home position
+//*************************************************************************
+void Home(USHORT Window)
+{
+ wWindow[Window].usCurX=0;
+ wWindow[Window].usCurY=0;
+
+}
+
+//*************************************************************************
+// Clear()
+//
+// clear a specific window
+//*************************************************************************
+void Clear(USHORT Window)
+{
+ ULONG j;
+
+ for(j=0;j<wWindow[Window].cy;j++)
+ {
+ ClrLine(wWindow[Window].y+j);
+ }
+
+ Home(Window);
+}
+
+//*************************************************************************
+// PrintCaption()
+//
+//*************************************************************************
+void PrintCaption(void)
+{
+ const char title[]=" PrivateICE system level debugger (REACTOS) ";
+
+ SetForegroundColor(COLOR_TEXT);
+ SetBackgroundColor(COLOR_CAPTION);
+
+ ClrLine(0);
+ PutChar((LPSTR)title,
+ (GLOBAL_SCREEN_WIDTH-sizeof(title))/2,
+ 0);
+
+ ResetColor();
+}
+
+//*************************************************************************
+// PrintTemplate()
+//
+// print the screen template
+//*************************************************************************
+void PrintTemplate(void)
+{
+ USHORT i,j;
+
+ ENTER_FUNC();
+
+ ResetColor();
+
+ for(j=0;j<4;j++)
+ {
+ for(i=wWindow[j].y;i<(wWindow[j].y+wWindow[j].cy);i++)
+ {
+ ClrLine(i);
+ }
+ }
+
+ PrintCaption();
+
+ SetForegroundColor(COLOR_TEXT);
+ SetBackgroundColor(COLOR_CAPTION);
+
+ ClrLine(wWindow[DATA_WINDOW].y-1);
+ ClrLine(wWindow[SOURCE_WINDOW].y-1);
+ ClrLine(wWindow[OUTPUT_WINDOW].y-1);
+
+ ResetColor();
+
+ ShowRunningMsg();
+ PrintLogo(TRUE);
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// PrintLogo()
+//
+//*************************************************************************
+void PrintLogo(BOOLEAN bShow)
+{
+ ohandlers.PrintLogo(bShow);
+}
+
+//*************************************************************************
+// PrintCursor()
+//
+// emulate a blinking cursor block
+//*************************************************************************
+void PrintCursor(BOOLEAN bForce)
+{
+ ohandlers.PrintCursor(bForce);
+}
+
+//*************************************************************************
+// Print()
+//
+//*************************************************************************
+void Print(USHORT Window,LPSTR p)
+{
+ ULONG i;
+
+ DPRINT((11,"%s",p));
+
+ //ENTER_FUNC();
+ if(!bConsoleIsInitialized)
+ {
+ DPRINT((0,"Print(): console is not initialized!\n"));
+ //LEAVE_FUNC();
+ return;
+ }
+
+
+ // the OUTPUT_WINDOW is specially handled
+ if(Window == OUTPUT_WINDOW)
+ {
+ DPRINT((0,"Print(): OUTPUT_WINDOW\n"));
+ if(AddToRingBuffer(p))
+ {
+ DPRINT((0,"Print(): checking ring buffer\n"));
+ CheckRingBuffer();
+ }
+ else
+ {
+ DPRINT((0,"Print(): outputting a line from ring buffer\n"));
+ wWindow[OUTPUT_WINDOW].usCurX = 0;
+ ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].usCurY);
+ Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulInPos]);
+ }
+ }
+ else
+ {
+ BOOLEAN bOutput = TRUE;
+
+ if(Window == OUTPUT_WINDOW_UNBUFFERED)
+ {
+ Window = OUTPUT_WINDOW;
+ }
+
+ for(i=0;p[i]!=0;i++)
+ {
+ if(wWindow[Window].usCurX > (GLOBAL_SCREEN_WIDTH-1))
+ bOutput = FALSE;
+
+ // newline
+ if(p[i]=='\n')
+ {
+ wWindow[Window].usCurX = 0;
+ wWindow[Window].usCurY++;
+ if(wWindow[Window].usCurY>=wWindow[Window].cy)
+ {
+ wWindow[Window].usCurY=wWindow[Window].cy-1;
+ ScrollUp(Window);
+ }
+ if(wWindow[Window].bScrollDisabled==TRUE)break;
+ }
+ // backspace
+ else if(p[i]=='\b')
+ {
+ if(wWindow[Window].usCurX>0)
+ {
+ wWindow[Window].usCurX--;
+ if(bOutput)
+ PrintGraf(wWindow[Window].usCurX,wWindow[Window].y+wWindow[Window].usCurY,0x20);
+ }
+
+ }
+ // TAB
+ else if(p[i]=='\t')
+ {
+ if((wWindow[Window].usCurX + 4) < (GLOBAL_SCREEN_WIDTH-1))
+ {
+ wWindow[Window].usCurX += 4;
+ }
+ }
+ else
+ {
+ if((UCHAR)p[i]<0x20 && (UCHAR)p[i]>0x7f)
+ p[i]=0x20;
+
+ if(bOutput)
+ PrintGraf(wWindow[Window].usCurX,wWindow[Window].y+wWindow[Window].usCurY,p[i]);
+
+ wWindow[Window].usCurX++;
+ }
+ }
+
+ // flush
+ Flush();
+ }
+ //LEAVE_FUNC();
+}
+
+
+//*************************************************************************
+// SaveGraphicsState()
+//
+//*************************************************************************
+void SaveGraphicsState(void)
+{
+ ohandlers.SaveGraphicsState();
+}
+
+//*************************************************************************
+// RestoreGraphicsState()
+//
+//*************************************************************************
+void RestoreGraphicsState(void)
+{
+ ohandlers.RestoreGraphicsState();
+}
+
+//*************************************************************************
+// SetWindowGeometry()
+//
+//*************************************************************************
+void SetWindowGeometry(PVOID pWindow)
+{
+ PICE_memcpy(wWindow,pWindow,sizeof(wWindow));
+}
+
+// INPUT handlers
+
+//*************************************************************************
+// GetKeyPolled()
+//
+//*************************************************************************
+UCHAR GetKeyPolled(void)
+{
+ return ihandlers.GetKeyPolled();
+}
+
+//*************************************************************************
+// FlushKeyboardQueue()
+//
+//*************************************************************************
+void FlushKeyboardQueue(void)
+{
+ ihandlers.FlushKeyboardQueue();
+}
+
+
+//*************************************************************************
+// ConsoleInit()
+//
+// init terminal screen
+//*************************************************************************
+BOOLEAN ConsoleInit(void)
+{
+ BOOLEAN bResult = FALSE;
+
+ ENTER_FUNC();
+
+ // preset ohandlers and ihandler to NULL
+ PICE_memset((void*)&ohandlers,0,sizeof(ohandlers));
+ PICE_memset((void*)&ihandlers,0,sizeof(ihandlers));
+
+ switch(eTerminalMode)
+ {
+ case TERMINAL_MODE_HERCULES_GRAPHICS:
+ bResult = ConsoleInitHercules();
+ break;
+ case TERMINAL_MODE_HERCULES_TEXT:
+ break;
+ case TERMINAL_MODE_VGA_TEXT:
+ bResult = ConsoleInitVga();
+ break;
+ case TERMINAL_MODE_SERIAL:
+ bResult = ConsoleInitSerial();
+ break;
+ case TERMINAL_MODE_NONE:
+ default:
+ // fail
+ break;
+ }
+
+ // check that outputhandlers have all been set
+ // ohandlers.Flush may be zero on return
+ if( !ohandlers.ClrLine ||
+ !ohandlers.CopyLineTo ||
+ !ohandlers.HatchLine ||
+ !ohandlers.HideCursor ||
+ !ohandlers.InvertLine ||
+ !ohandlers.PrintCursor ||
+ !ohandlers.PrintGraf ||
+ !ohandlers.PrintLogo ||
+ !ohandlers.RestoreGraphicsState ||
+ !ohandlers.SaveGraphicsState ||
+ !ohandlers.SetBackgroundColor ||
+ !ohandlers.SetForegroundColor ||
+ !ohandlers.ShowCursor)
+ {
+ bResult = FALSE;
+ }
+
+ // check that inputhandlers were installed
+ if( !ihandlers.GetKeyPolled ||
+ !ihandlers.FlushKeyboardQueue)
+ {
+ bResult = FALSE;
+ }
+
+ LEAVE_FUNC();
+
+ bConsoleIsInitialized = bResult;
+
+ return bResult;
+}
+
+//*************************************************************************
+// ConsoleShutdown()
+//
+// exit terminal screen
+//*************************************************************************
+void ConsoleShutdown(void)
+{
+ ENTER_FUNC();
+
+ // sleep for a few seconds
+ KeStallExecutionProcessor(1000*5000);
+
+ switch(eTerminalMode)
+ {
+ case TERMINAL_MODE_HERCULES_GRAPHICS:
+ ConsoleShutdownHercules();
+ break;
+ case TERMINAL_MODE_HERCULES_TEXT:
+ break;
+ case TERMINAL_MODE_VGA_TEXT:
+ ConsoleShutdownVga();
+ break;
+ case TERMINAL_MODE_SERIAL:
+ ConsoleShutdownSerial();
+ break;
+ case TERMINAL_MODE_NONE:
+ default:
+ // fail
+ break;
+ }
+
+ LEAVE_FUNC();
+}
+
+// EOF
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ hardwar.h
+
+Abstract:
+
+ HEADER for hardware.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+typedef struct tagWindow
+{
+ USHORT y,cy;
+ USHORT usCurX,usCurY;
+ BOOLEAN bScrollDisabled;
+}WINDOW,*PWINDOW;
+
+// pointer indirection table for output functions
+typedef struct _OUTPUT_HANDLERS
+{
+ void (*CopyLineTo) (USHORT dest,USHORT src);
+ void (*PrintGraf) (ULONG x,ULONG y,UCHAR c);
+ void (*Flush) (void);
+ void (*ClrLine) (ULONG line);
+ void (*InvertLine) (ULONG line);
+ void (*HatchLine) (ULONG line);
+ void (*PrintLogo) (BOOLEAN bShow);
+ void (*PrintCursor) (BOOLEAN bForce);
+ void (*SaveGraphicsState) (void);
+ void (*RestoreGraphicsState) (void);
+ void (*ShowCursor) (void);
+ void (*HideCursor) (void);
+ void (*SetForegroundColor) (ECOLORS);
+ void (*SetBackgroundColor) (ECOLORS);
+}OUTPUT_HANDLERS,*POUTPUT_HANDLERS;
+
+// pointer indirection table for input functions
+typedef struct _INPUT_HANDLERS
+{
+ UCHAR (*GetKeyPolled) (void);
+ void (*FlushKeyboardQueue) (void);
+}INPUT_HANDLERS,*PINPUT_HANDLERS;
+
+extern OUTPUT_HANDLERS ohandlers;
+extern INPUT_HANDLERS ihandlers;
+
+enum
+{
+ REGISTER_WINDOW = 0 ,
+ DATA_WINDOW ,
+ SOURCE_WINDOW ,
+ OUTPUT_WINDOW ,
+ OUTPUT_WINDOW_UNBUFFERED
+};
+
+typedef enum _ETERMINALMODE
+{
+ TERMINAL_MODE_HERCULES_GRAPHICS = 0 ,
+ TERMINAL_MODE_HERCULES_TEXT,
+ TERMINAL_MODE_VGA_TEXT,
+ TERMINAL_MODE_SERIAL,
+ TERMINAL_MODE_NONE
+}ETERMINALMODE;
+
+extern ETERMINALMODE eTerminalMode;
+
+extern WINDOW wWindow[];
+extern BOOLEAN bRev;
+extern BOOLEAN bGrayed;
+extern BOOLEAN bCursorEnabled;
+
+// install and remove handler
+BOOLEAN ConsoleInit(void);
+void ConsoleShutdown(void);
+
+// OUTPUT handler
+void Print(USHORT Window,LPSTR p);
+void SetBackgroundColor(ECOLORS c);
+void SetForegroundColor(ECOLORS c);
+void Clear(USHORT window);
+void PutChar(LPSTR p,ULONG x,ULONG y);
+void ClrLine(ULONG line);
+void ShowCursor(void);
+void HideCursor(void);
+void EnableScroll(USHORT Window);
+void DisableScroll(USHORT Window);
+void CopyLineTo(USHORT dest,USHORT src);
+void PrintLogo(BOOLEAN bShow);
+void PrintCursor(BOOLEAN bForce);
+void PrintGraf(ULONG x,ULONG y,UCHAR c);
+void ScrollUp(USHORT Window);
+void Home(USHORT Window);
+void InvertLine(ULONG line);
+void FillLine(ULONG line,UCHAR c);
+void PrintTemplate(void);
+void PrintCaption(void);
+void ClrLineToEnd(USHORT Window,ULONG line,ULONG x);
+void SuspendPrintRingBuffer(BOOLEAN bSuspend);
+void HatchLine(ULONG line);
+void SaveGraphicsState(void);
+void RestoreGraphicsState(void);
+void SetWindowGeometry(PVOID pWindow);
+
+// INPUT handler
+UCHAR GetKeyPolled(void);
+void FlushKeyboardQueue(void);
+
+
+BOOLEAN PrintRingBufferOffset(ULONG ulLines,ULONG ulOffset);
+BOOLEAN PrintRingBufferHome(ULONG ulLines);
+void PrintRingBuffer(ULONG ulLines);
+ULONG LinesInRingBuffer(void);
+void ReplaceRingBufferCurrent(LPSTR s);
+void EmptyRingBuffer(void);
+void CheckRingBuffer(void);
+BOOLEAN AddToRingBuffer(LPSTR p);
+void ResetColor(void);
+
+extern ULONG GLOBAL_SCREEN_WIDTH;
+extern ULONG GLOBAL_SCREEN_HEIGHT;
+
+extern ULONG ulOutputLock;
+
+#define Acquire_Output_Lock() \
+{ \
+ save_flags(ulOutputLock); \
+ cli(); \
+}
+
+#define Release_Output_Lock() \
+ restore_flags(ulOutputLock);
+
+#define NOT_IMPLEMENTED()
+
+extern USHORT usCaptionColor;
+#define COLOR_CAPTION usCaptionColor
+extern USHORT usCaptionText;
+#define COLOR_TEXT usCaptionText
+extern USHORT usForegroundColor;
+#define COLOR_FOREGROUND usForegroundColor
+extern USHORT usBackgroundColor;
+
+#undef COLOR_BACKGROUND
+#define COLOR_BACKGROUND usBackgroundColor
+extern USHORT usHiLiteColor;
+#define COLOR_HILITE usHiLiteColor
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ hercules.c
+
+Abstract:
+
+ HW dependent draw routines
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 04-Aug-1998: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+
+#include "charset.h"
+#include "logo.h"
+
+////////////////////////////////////////////////////
+// PROTOTYPES
+////
+
+////////////////////////////////////////////////////
+// DEFINES
+////
+
+////////////////////////////////////////////////////
+// GLOBALS
+////
+// cursor state
+BOOLEAN bRev=FALSE;
+
+// HERCULES graphics adapter stuff
+// 43 line graphics mode
+UCHAR MGATable43[]={53,45,46, 7,96, 2,91,91, 2, 3, 0, 0, 0, 0, 0, 0};
+
+PUCHAR pVgaOffset[4];
+// END of HERCULES graphics adapter stuff
+
+// used for HERCULES graphics mode
+WINDOW wWindowHercGraph[4]=
+{
+ {1,3,1,0,FALSE},
+ {5,6,1,0,FALSE},
+ {12,19,1,0,FALSE},
+ {32,12,1,0,FALSE}
+};
+// used for HERCUELS text and VGA text mode
+WINDOW wWindowHerc[4]=
+{
+ {1,3,1,0,FALSE},
+ {5,4,1,0,FALSE},
+ {10,9,1,0,FALSE},
+ {20,4,1,0,FALSE}
+};
+
+PUCHAR pScreenBufferHercules;
+
+struct _attr
+{
+ union
+ {
+ struct
+ {
+
+ UCHAR fgcol : 4;
+ UCHAR bkcol : 3;
+ UCHAR blink : 1;
+ }bits;
+ UCHAR Asuchar;
+ }u;
+}attr;
+
+//*************************************************************************
+// SetForegroundColorVga()
+//
+//*************************************************************************
+void SetForegroundColorHercules(ECOLORS col)
+{
+ attr.u.bits.fgcol = col;
+ attr.u.bits.blink = 0;
+}
+
+//*************************************************************************
+// SetBackgroundColorVga()
+//
+//*************************************************************************
+void SetBackgroundColorHercules(ECOLORS col)
+{
+ attr.u.bits.bkcol = col;
+ attr.u.bits.blink = 0;
+}
+
+//*************************************************************************
+// PrintGrafHercules()
+//
+//*************************************************************************
+void PrintGrafHercules(ULONG x,ULONG y,UCHAR c)
+{
+ ULONG i;
+ PUCHAR p;
+ ULONG _line = y<<3;
+
+ if(!pScreenBufferHercules)
+ return;
+
+ p=&cGraphTable[(ULONG)c<<3];
+
+ if((attr.u.bits.bkcol == COLOR_FOREGROUND && attr.u.bits.fgcol == COLOR_BACKGROUND) ||
+ (attr.u.bits.bkcol == COLOR_CAPTION && attr.u.bits.fgcol == COLOR_TEXT) )
+ for(i=0 ;i<8 ;i++,_line++)
+ {
+ *(PUCHAR)(pVgaOffset[_line & 0x3] + ( 90* (_line >> 2) ) + x) = ~*p++;
+ }
+ else
+ for(i=0 ;i<8 ;i++,_line++)
+ {
+ *(PUCHAR)(pVgaOffset[_line & 0x3] + ( 90* (_line >> 2) ) + x) = *p++;
+ }
+}
+
+
+//*************************************************************************
+// FlushHercules()
+//
+//*************************************************************************
+void FlushHercules(void)
+{
+}
+
+//*************************************************************************
+// ShowCursor()
+//
+// show hardware cursor
+//*************************************************************************
+void ShowCursorHercules(void)
+{
+ ENTER_FUNC();
+
+ bCursorEnabled=TRUE;
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// HideCursorHercules()
+//
+// hide hardware cursor
+//*************************************************************************
+void HideCursorHercules(void)
+{
+ ENTER_FUNC();
+
+ bCursorEnabled=FALSE;
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// CopyLineTo()
+//
+// copy a line from src to dest
+//*************************************************************************
+void CopyLineToHercules(USHORT dest,USHORT src)
+{
+ USHORT i,j;
+ PULONG pDest,pSrc;
+
+ ENTER_FUNC();
+
+ dest <<= 3;
+ src <<= 3;
+ for(i=0;i<8;i++)
+ {
+ (PUCHAR)pDest = (PUCHAR)pScreenBufferHercules + ( ( ( dest+i )&3) <<13 )+ 90 * ((dest+i) >> 2);
+ (PUCHAR)pSrc = (PUCHAR)pScreenBufferHercules + ( ( ( src+i )&3) <<13 )+ 90 * ((src+i) >> 2);
+ for(j=0;j<(GLOBAL_SCREEN_WIDTH>>2);j++)
+ {
+ *pDest++=*pSrc++;
+ }
+ }
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// InvertLineHercules()
+//
+// invert a line on the screen
+//*************************************************************************
+void InvertLineHercules(ULONG line)
+{
+ ULONG i,j;
+ ULONG _line = line<<3;
+ PUSHORT p;
+
+ //ENTER_FUNC();
+
+ for(j=0;j<8;j++)
+ {
+ p=(PUSHORT)( pVgaOffset[_line&3] + (90*(_line>>2)) );
+ for(i=0;i<(GLOBAL_SCREEN_WIDTH>>1);i++)
+ {
+ p[i]=~p[i];
+ }
+ _line++;
+ }
+
+ //LEAVE_FUNC();
+}
+
+//*************************************************************************
+// HatchLineHercules()
+//
+// hatches a line on the screen
+//*************************************************************************
+void HatchLineHercules(ULONG line)
+{
+ USHORT cc;
+ ULONG i,j;
+ ULONG _line = (line<<3) ;
+ PUSHORT p;
+ USHORT mask_odd[]={0x8888,0x2222};
+ USHORT mask_even[]={0xaaaa,0x5555};
+ PUSHORT pmask;
+
+ ENTER_FUNC();
+
+ pmask = (line&1)?mask_odd:mask_even;
+
+ for(j=0;j<8;j++,_line++)
+ {
+ p=(PUSHORT)( pVgaOffset[_line&3] + (90*(_line>>2)) );
+ for(i=0;i<(GLOBAL_SCREEN_WIDTH/sizeof(USHORT));i++)
+ {
+ cc = p[i];
+
+ p[i]=(p[i]^pmask[j&1])|cc;
+ }
+ }
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// ClrLineHercules()
+//
+// clear a line on the screen
+//*************************************************************************
+void ClrLineHercules(ULONG line)
+{
+ ULONG j;
+ BOOLEAN bTemplateLine=( (USHORT)line==wWindow[DATA_WINDOW].y-1 ||
+ (USHORT)line==wWindow[SOURCE_WINDOW].y-1 ||
+ (USHORT)line==wWindow[OUTPUT_WINDOW].y-1 ||
+ 0);
+ ULONG _line = line<<3;
+ ULONG cc=0;
+ PUCHAR p;
+
+// ENTER_FUNC();
+
+ if(line > GLOBAL_SCREEN_HEIGHT )
+ {
+ DPRINT((0,"ClrLineHercules(): line %u is out of screen\n",line));
+ //LEAVE_FUNC();
+ return;
+ }
+
+ if(attr.u.bits.bkcol == COLOR_CAPTION && attr.u.bits.fgcol == COLOR_TEXT )
+ cc=~cc;
+
+ if(bTemplateLine)
+ {
+ for(j=0;j<8;j++,_line++)
+ {
+ p = (PUCHAR)(pVgaOffset[_line&3] + (90*(_line>>2)) );
+
+/*
+ if(j==2 || j==5)cc=0xFF;
+ else if(j==3)cc=0xaa;
+ else if(j==4)cc=0x55;
+ else cc = 0;*/
+ if(j==2 || j==5)cc=0xFF;
+ else cc = 0;
+
+ PICE_memset(p,(UCHAR)cc,GLOBAL_SCREEN_WIDTH);
+ }
+ }
+ else
+ {
+ for(j=0;j<8;j++,_line++)
+ {
+ p = (PUCHAR)(pVgaOffset[_line&3] + (90*(_line>>2)) );
+
+ PICE_memset(p,(UCHAR)cc,GLOBAL_SCREEN_WIDTH);
+ }
+ }
+ //LEAVE_FUNC();
+}
+
+//*************************************************************************
+// PrintLogoHercules()
+//
+//*************************************************************************
+void PrintLogoHercules(BOOLEAN bShow)
+{
+ LONG x,y;
+ PUCHAR p;
+
+ p=(PUCHAR)pScreenBufferHercules;
+ for(y=0;y<24;y++)
+ {
+ for(x=0;x<8;x++)
+ {
+ p[ ( 0x2000* (( y + 8 ) & 0x3) )+
+ ( 90* ( (y + 8 ) >> 2) )+
+ (81+x)] = cLogo[y*8+x];
+ }
+ }
+}
+
+//*************************************************************************
+// PrintCursorHercules()
+//
+// emulate a blinking cursor block
+//*************************************************************************
+void PrintCursorHercules(BOOLEAN bForce)
+{
+ static ULONG count=0;
+
+ if( (bForce) || ((count++>100) && bCursorEnabled) )
+ {
+ ULONG i;
+ ULONG x,y;
+ ULONG _line;
+
+ x=wWindow[OUTPUT_WINDOW].usCurX;
+ y=wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].usCurY;
+
+ _line = y<<3;
+ for(i=0;i<8;i++,_line++)
+ {
+ *(PUCHAR)(pVgaOffset[_line & 0x3] + ( 90* (_line >> 2) ) + x) ^= 0xFF ;
+ }
+ bRev=!bRev;
+ count=0;
+ }
+
+ KeStallExecutionProcessor(2500);
+}
+
+//*************************************************************************
+// SaveGraphicsHercules()
+//
+//*************************************************************************
+void SaveGraphicsStateHercules(void)
+{
+ // not implemented
+}
+
+//*************************************************************************
+// RestoreGraphicsStateHercules()
+//
+//*************************************************************************
+void RestoreGraphicsStateHercules(void)
+{
+ // not implemented
+}
+
+//*************************************************************************
+// ConsoleInitHercules()
+//
+// init terminal screen
+//*************************************************************************
+BOOLEAN ConsoleInitHercules(void)
+{
+ BOOLEAN bResult = FALSE;
+ PUCHAR pMGATable = MGATable43;
+ UCHAR i,reg,data;
+ PHYSICAL_ADDRESS FrameBuffer;
+
+ ENTER_FUNC();
+
+ ohandlers.CopyLineTo = CopyLineToHercules;
+ ohandlers.PrintGraf = PrintGrafHercules;
+ ohandlers.Flush = FlushHercules;
+ ohandlers.ClrLine = ClrLineHercules;
+ ohandlers.InvertLine = InvertLineHercules;
+ ohandlers.HatchLine = HatchLineHercules;
+ ohandlers.PrintLogo = PrintLogoHercules;
+ ohandlers.PrintCursor = PrintCursorHercules;
+ ohandlers.SaveGraphicsState = SaveGraphicsStateHercules;
+ ohandlers.RestoreGraphicsState = RestoreGraphicsStateHercules;
+ ohandlers.ShowCursor = ShowCursorHercules;
+ ohandlers.HideCursor = HideCursorHercules;
+ ohandlers.SetForegroundColor = SetForegroundColorHercules;
+ ohandlers.SetBackgroundColor = SetBackgroundColorHercules;
+
+ ihandlers.GetKeyPolled = KeyboardGetKeyPolled;
+ ihandlers.FlushKeyboardQueue = KeyboardFlushKeyboardQueue;
+
+ // init HERCULES adapter
+ outb_p(0,0x3b8);
+ outb_p(0x03,0x3bf);
+ for(i=0;i<sizeof(MGATable43);i++)
+ {
+ reg=i;
+ outb_p(reg,0x3b4);
+ data=pMGATable[i];
+ outb_p(data,0x3b5);
+ }
+ outb_p(0x0a,0x3b8);
+
+ SetWindowGeometry(wWindowHercGraph);
+
+ GLOBAL_SCREEN_WIDTH = 90;
+ GLOBAL_SCREEN_HEIGHT = 45;
+
+ attr.u.Asuchar = 0x07;
+ FrameBuffer.u.LowPart = 0xb0000;
+ pScreenBufferHercules=MmMapIoSpace(FrameBuffer,FRAMEBUFFER_SIZE,MmNonCached);
+
+ DPRINT((0,"VGA memory phys. 0xb0000 mapped to virt. 0x%x\n",pScreenBufferHercules));
+
+ if(pScreenBufferHercules)
+ {
+ for(i=0;i<4;i++)
+ {
+ pVgaOffset[i] = (PUCHAR)pScreenBufferHercules+0x2000*i;
+ DPRINT((0,"VGA offset %u = 0x%.8X\n",i,pVgaOffset[i]));
+ }
+ bResult = TRUE;
+
+ PICE_memset(pScreenBufferHercules,0x0,FRAMEBUFFER_SIZE);
+
+ EmptyRingBuffer();
+
+ DPRINT((0,"ConsoleInitHercules() SUCCESS!\n"));
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+//*************************************************************************
+// ConsoleShutdownHercules()
+//
+// exit terminal screen
+//*************************************************************************
+void ConsoleShutdownHercules(void)
+{
+ ENTER_FUNC();
+
+ // HERC video off
+ outb_p(0,0x3b8);
+ outb_p(0,0x3bf);
+
+ if(pScreenBufferHercules)
+ MmUnmapIoSpace(pScreenBufferHercules,FRAMEBUFFER_SIZE);
+
+ LEAVE_FUNC();
+}
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ hercules.h
+
+Abstract:
+
+ HEADER for hercules.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+BOOLEAN ConsoleInitHercules(void);
+void ConsoleShutdownHercules(void);
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ hooks.c
+
+Abstract:
+
+ hooking of interrupts
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 16-Jul-1998: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+
+////////////////////////////////////////////////////
+// PROTOTYPES
+////
+void DeinstallHooks(void);
+
+////////////////////////////////////////////////////
+// DEFINES
+////
+
+////////////////////////////////////////////////////
+// GLOBALS
+////
+
+// IDT entries
+//PIDTENTRY pidt[256];
+IDTENTRY oldidt[256]={{0},};
+
+IDTENTRY idt_snapshot[256]={{0},};
+
+// processor flag for interrupt suspension
+ULONG ulOldFlags;
+
+////////////////////////////////////////////////////
+// PROCEDURES
+////
+
+//*************************************************************************
+// MaskIrqs()
+//
+//*************************************************************************
+void MaskIrqs(void)
+{
+ ENTER_FUNC();
+
+ save_flags(ulOldFlags);
+ cli();
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// UnmaskIrqs()
+//
+//*************************************************************************
+void UnmaskIrqs(void)
+{
+ ENTER_FUNC();
+
+ restore_flags(ulOldFlags);
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// SetGlobalInt()
+//
+//*************************************************************************
+ULONG SetGlobalInt(ULONG dwInt,ULONG NewIntHandler)
+{
+ ULONG idt[2];
+ ULONG OldIntHandler;
+ struct IdtEntry* pidt;
+ struct IdtEntry oldidt;
+
+ ENTER_FUNC();
+
+ // get linear location of IDT
+ __asm__("sidt %0":"=m" (idt));
+
+ // get pointer to idte for int 3
+ pidt=((struct IdtEntry*)((idt[1]<<16)|((idt[0]>>16)&0x0000FFFF)))+dwInt;
+
+ oldidt=*pidt;
+
+ // set new handler address
+ pidt->HiOffset=(USHORT)(((ULONG)NewIntHandler)>>16);
+ pidt->LoOffset=(USHORT)(((ULONG)NewIntHandler)&0x0000FFFF);
+
+ DPRINT((0,"new INT(%0.2x) handler = %0.4x:%x\n",dwInt,pidt->SegSel,(pidt->HiOffset<<16)|(pidt->LoOffset&0x0000FFFF)));
+
+ OldIntHandler=(oldidt.HiOffset<<16)|(oldidt.LoOffset&0x0000FFFF);
+
+ DPRINT((0,"old INT(%0.2x) handler = %0.4x:%x\n",dwInt,pidt->SegSel,OldIntHandler));
+
+ LEAVE_FUNC();
+
+ return OldIntHandler;
+}
+
+//*************************************************************************
+// TakeIdtSnapshot()
+//
+//*************************************************************************
+void TakeIdtSnapshot(void)
+{
+ ULONG idt[2],i;
+ struct IdtEntry* pidt;
+
+ __asm__("sidt %0":"=m" (idt));
+
+ // get pointer to idte for int 3
+ pidt=((struct IdtEntry*)((idt[1]<<16)|((idt[0]>>16)&0x0000FFFF)));
+
+ for(i=0;i<256;i++)
+ {
+ DPRINT((11,"TakeIdtSnapShot(): saving vector %u\n",i));
+ if(IsRangeValid((ULONG)pidt,sizeof(*pidt)) )
+ {
+ DPRINT((11,"TakeIdtSnapShot(): vector %u valid\n",i));
+ idt_snapshot[i] = *pidt++;
+ }
+ }
+}
+
+//*************************************************************************
+// RestoreIdt()
+//
+//*************************************************************************
+void RestoreIdt(void)
+{
+ ULONG idt[2],i;
+ struct IdtEntry* pidt;
+
+ __asm__("sidt %0":"=m" (idt));
+
+ // get pointer to idte for int 3
+ pidt=((struct IdtEntry*)((idt[1]<<16)|((idt[0]>>16)&0x0000FFFF)));
+
+ for(i=0;i<256;i++)
+ {
+ DPRINT((11,"TakeIdtSnapShot(): restoring vector %u\n",i));
+ if(IsRangeValid((ULONG)pidt,sizeof(*pidt)) )
+ {
+ DPRINT((11,"TakeIdtSnapShot(): vector %u valid\n",i));
+ *pidt++ = idt_snapshot[i];
+ }
+ }
+}
+
+// EOF
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ hooks.h
+
+Abstract:
+
+ HEADER for hooks.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+void DeinstallHooks(void);
+//ULONG HookInt(ULONG dwInt,ULONG NewIntHandler);
+//void UnhookInt(ULONG dwInt);
+void MaskIrqs(void);
+void UnmaskIrqs(void);
+ULONG SetGlobalInt(ULONG dwInt,ULONG NewIntHandler);
+ULONG GetIRQVector(ULONG dwInt);
+void TakeIdtSnapshot(void);
+void RestoreIdt(void);
+
+// structure of an IDT entry
+typedef struct IdtEntry
+{
+ USHORT LoOffset;
+ USHORT SegSel;
+ USHORT Flags;
+ USHORT HiOffset;
+}IDTENTRY,*PIDTENTRY;
+
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ init.c
+
+Abstract:
+
+ initialisation and cleanup of debugger kernel module
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 25-Jan-1999: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+
+////////////////////////////////////////////////////
+// GLOBALS
+ULONG ulDoInitialBreak=1;
+char szBootParams[1024]="";
+char tempInit[256];
+
+PDIRECTORY_OBJECT *pNameSpaceRoot = NULL;
+PDEBUG_MODULE pdebug_module_tail = NULL;
+PDEBUG_MODULE pdebug_module_head = NULL;
+PMADDRESS_SPACE mm_init_mm;
+extern LIST_ENTRY *pModuleListHead;
+
+ULONG KeyboardIRQL;
+
+extern void NewInt31Handler(void);
+//*************************************************************************
+// InitPICE()
+//
+//*************************************************************************
+BOOLEAN InitPICE(void)
+{
+ ULONG ulHandleScancode=0,ulHandleKbdEvent=0;
+ ARGS Args;
+ KIRQL Dirql;
+ KAFFINITY Affinity;
+ ULONG ulAddr;
+
+ ENTER_FUNC();
+
+ DPRINT((0,"InitPICE(): trace step 0.5\n"));
+ KeyboardIRQL = HalGetInterruptVector(Internal,
+ 0,
+ 0,
+ KEYBOARD_IRQ,
+ &Dirql,
+ &Affinity);
+ DPRINT((0,"KeyboardIRQL: %x\n", KeyboardIRQL));
+
+ DPRINT((0,"InitPICE(): trace step 1\n"));
+ // enable monochrome passthrough on BX type chipset
+ EnablePassThrough();
+
+ DPRINT((0,"InitPICE(): trace step 2\n"));
+ // now load all symbol files described in /etc/pice.conf
+ if(!LoadSymbolsFromConfig(FALSE))
+ {
+ DPRINT((0,"InitPICE: LoadSymbolsFromConfig() failed\n"));
+ LEAVE_FUNC();
+ return FALSE;
+ }
+
+ DPRINT((0,"InitPICE(): trace step 3\n"));
+ // init the output console
+ // this might be one of the following depending setup
+ // a) monochrome card
+ // b) serial terminal (TODO)
+ if(!ConsoleInit())
+ {
+ DPRINT((0,"InitPICE: ConsoleInit() failed\n"));
+ UnloadSymbols();
+ LEAVE_FUNC();
+ return FALSE;
+ }
+
+ DPRINT((0,"InitPICE(): trace step 4\n"));
+ // print the initial screen template
+ PrintTemplate();
+/*
+ DPRINT((0,"InitPICE(): trace step 5\n"));
+ // ask the user if he wants to abort the debugger load
+ if(!CheckLoadAbort())
+ {
+ Print(OUTPUT_WINDOW,"pICE: ABORT (abort by user)\n");
+ UnloadSymbols();
+ ConsoleShutdown();
+ LEAVE_FUNC();
+ return FALSE;
+ }
+*/
+
+ DPRINT((0,"InitPICE(): trace step 6\n"));
+ // load the file /boot/System.map.
+ // !!! It must be consistent with the current kernel at all cost!!!
+ if(!LoadExports())
+ {
+ Print(OUTPUT_WINDOW,"pICE: failed to load exports\n");
+ Print(OUTPUT_WINDOW,"press any key to continue...\n");
+ while(!GetKeyPolled());
+ UnloadSymbols();
+ ConsoleShutdown();
+ LEAVE_FUNC();
+ return FALSE;
+ }
+
+ DPRINT((0,"InitPICE(): trace step 7\n"));
+ ScanExports("_KernelAddressSpace", &ulAddr);
+ my_init_mm = (PMADDRESS_SPACE) ulAddr;
+ DPRINT((0,"init_mm %x @ %x\n",&my_init_mm,my_init_mm));
+ if(!my_init_mm)
+ {
+ Print(OUTPUT_WINDOW,"pICE: ABORT (initial memory map not found)\n");
+ Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
+ DbgPrint("pICE: ABORT (initial memory map not found)\n");
+ DbgPrint("pICE: press any key to continue...\n");
+ while(!GetKeyPolled());
+ UnloadSymbols();
+ ConsoleShutdown();
+ LEAVE_FUNC();
+ return FALSE;
+ }
+
+ DPRINT((0,"InitPICE(): trace step 7.1\n"));
+ ScanExports("_ModuleListHead",&ulAddr);
+ pModuleListHead = (LIST_ENTRY*)ulAddr;
+ DPRINT((0,"pModuleListHead @ %X\n",pModuleListHead));
+ if(!pModuleListHead)
+ {
+ Print(OUTPUT_WINDOW,"pICE: ABORT (pModuleListHead not found)\n");
+ Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
+ while(!GetKeyPolled());
+ UnloadSymbols();
+ ConsoleShutdown();
+ LEAVE_FUNC();
+ return FALSE;
+ }
+
+ DPRINT((0,"InitPICE(): trace step 7.2\n"));
+ ScanExports("_PsProcessListHead",&ulAddr);
+ pPsProcessListHead = (LIST_ENTRY*)ulAddr;
+ DPRINT((0,"pPsProcessListHead @ %X\n",pPsProcessListHead));
+ if(!pPsProcessListHead)
+ {
+ Print(OUTPUT_WINDOW,"pICE: ABORT (PsProcessListHead not found)\n");
+ Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
+ while(!GetKeyPolled());
+ UnloadSymbols();
+ ConsoleShutdown();
+ LEAVE_FUNC();
+ return FALSE;
+ }
+
+ DPRINT((0,"InitPICE(): trace step 8\n"));
+ // end of the kernel
+ /*
+ ScanExports("_end",(PULONG)&kernel_end);
+ if(!kernel_end)
+ {
+ Print(OUTPUT_WINDOW,"pICE: ABORT (kernel size is unknown)\n");
+ Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
+ while(!GetKeyPolled());
+ UnloadExports();
+ UnloadSymbols();
+ ConsoleShutdown();
+ LEAVE_FUNC();
+ return FALSE;
+ }
+ */
+
+ DPRINT((0,"InitPICE(): trace step 9\n"));
+
+ // the loaded module list
+ ScanExports("_NameSpaceRoot", &ulAddr);
+ pNameSpaceRoot = (PDIRECTORY_OBJECT *)ulAddr;
+ DPRINT((0,"pNameSpaceRoot @ %X\n",pNameSpaceRoot));
+ if(!pNameSpaceRoot)
+ {
+ Print(OUTPUT_WINDOW,"pICE: ABORT (couldn't retreive name space root)\n");
+ Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
+ while(!GetKeyPolled());
+ UnloadExports();
+ UnloadSymbols();
+ ConsoleShutdown();
+ LEAVE_FUNC();
+ return FALSE;
+ }
+
+ DPRINT((0,"InitPICE(): trace step 10\n"));
+ // setup a linked list for use in module parsing routines.
+ if(!InitModuleList(&pdebug_module_head, 100))
+ {
+ Print(OUTPUT_WINDOW,"pICE: ABORT (couldn't initialize kernel module list)\n");
+ Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
+ FreeModuleList( pdebug_module_head );
+ while(!GetKeyPolled());
+ UnloadExports();
+ UnloadSymbols();
+ ConsoleShutdown();
+ LEAVE_FUNC();
+ return FALSE;
+ }
+ pdebug_module_tail = pdebug_module_head;
+
+ DPRINT((0,"InitPICE(): trace step 11\n"));
+ // do a sanity check on exports
+ if(!SanityCheckExports())
+ {
+ Print(OUTPUT_WINDOW,"pICE: ABORT (exports are conflicting with kernel symbols)\n");
+ Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
+ while(!GetKeyPolled());
+ UnloadExports();
+ UnloadSymbols();
+ ConsoleShutdown();
+ LEAVE_FUNC();
+ return FALSE;
+ }
+
+ DPRINT((0,"InitPICE(): trace step 12\n"));
+
+
+ DPRINT((0,"InitPICE(): trace step 13\n"));
+ // patch the keyboard driver
+
+ if(!PatchKeyboardDriver())
+ {
+ Print(OUTPUT_WINDOW,"pICE: ABORT (couldn't patch keyboard driver)\n");
+ Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
+ while(!GetKeyPolled());
+ UnloadSymbols();
+ UnloadExports();
+ ConsoleShutdown();
+ LEAVE_FUNC();
+ return FALSE;
+ }
+
+ DPRINT((0,"InitPICE(): trace step 14\n"));
+ // partial init of shadow registers
+ CurrentCS = GLOBAL_CODE_SEGMENT;
+ CurrentEIP = (ULONG)RealIsr;
+
+ CurrentDS = CurrentSS = GLOBAL_DATA_SEGMENT;
+ __asm__("\n\t \
+ mov %%esp,%%eax\n\t \
+ mov %%eax,_CurrentESP\n\t \
+ ":::"eax");
+
+
+ // display version and symbol information
+ Ver(NULL);
+
+ // disable HW breakpoints
+ __asm__("\n\t \
+ xorl %%eax,%%eax\n\t \
+ mov %%eax,%%dr6\n\t \
+ mov %%eax,%%dr7\n\t \
+ mov %%dr0,%%eax\n\t \
+ mov %%dr1,%%eax\n\t \
+ mov %%dr2,%%eax\n\t \
+ mov %%dr3,%%eax"
+ :::"eax"
+ );
+
+ DPRINT((0,"InitPICE(): trace step 15\n"));
+ TakeIdtSnapshot();
+
+ DPRINT((0,"InitPICE(): trace step 16\n"));
+ // install all hooks
+ InstallTraceHook();
+ InstallGlobalKeyboardHook();
+ InstallSyscallHook();
+ InstallInt3Hook();
+ InstallDblFltHook();
+ InstallGPFaultHook();
+ InstallIntEHook();
+ InstallPrintkHook();
+
+ DPRINT((0,"InitPICE(): trace step 16\n"));
+ if(ulDoInitialBreak)
+ {
+ DPRINT((0,"about to do initial break...\n"));
+
+ // simulate an initial break
+ __asm__("\n\t \
+ pushfl\n\t \
+ pushl %cs\n\t \
+ pushl $initialreturnpoint\n\t \
+ pushl $" STR(REASON_CTRLF) "\n\t \
+ jmp NewInt31Handler\n\t \
+initialreturnpoint:");
+ }
+ else
+ {
+ // display register contents
+ DisplayRegs();
+
+ // display data window
+ Args.Value[0]=CurrentDS;
+ Args.Value[1]=CurrentEIP;
+ Args.Count=2;
+ DisplayMemory(&Args);
+
+ // disassembly from current address
+ Args.Value[0]=CurrentCS;
+ Args.Value[1]=CurrentEIP;
+ Args.Count=2;
+ Unassemble(&Args);
+ }
+
+ DPRINT((0,"InitPICE(): trace step 17\n"));
+ InitPiceRunningTimer();
+
+ LEAVE_FUNC();
+ return TRUE;
+}
+
+//*************************************************************************
+// CleanUpPICE()
+//
+//*************************************************************************
+void CleanUpPICE(void)
+{
+ DPRINT((0,"CleanUpPICE(): trace step 1\n"));
+ RemovePiceRunningTimer();
+
+ DPRINT((0,"CleanUpPICE(): trace step 2\n"));
+ // de-install all hooks
+ DeInstallGlobalKeyboardHook();
+ DeInstallSyscallHook();
+ DeInstallInt3Hook();
+ DeInstallPrintkHook();
+ DeInstallDblFltHook();
+ DeInstallGPFaultHook();
+ DeInstallIntEHook();
+ DeInstallTraceHook();
+
+ DPRINT((0,"CleanUpPICE(): trace step 3\n"));
+ RestoreIdt();
+
+ DPRINT((0,"CleanUpPICE(): trace step 4\n"));
+ UnloadExports(); // don't use ScanExports() after this
+ UnloadSymbols();
+
+ DPRINT((0,"CleanUpPICE(): trace step 5\n"));
+ // restore patch of keyboard driver
+ RestoreKeyboardDriver();
+
+ DPRINT((0,"CleanUpPICE(): trace step 6\n"));
+ Print(OUTPUT_WINDOW,"pICE: shutting down...\n");
+
+ DPRINT((0,"CleanUpPICE(): trace step 7\n"));
+ // cleanup the console
+ ConsoleShutdown();
+}
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ init.h
+
+Abstract:
+
+ HEADER for init.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+BOOLEAN InitPICE(void);
+void CleanUpPICE(void);
+
+extern char szBootParams[1024];
--- /dev/null
+// start of
+// structure of symbol file
+///////////////////////////////////////////////////
+typedef struct tagLoaderSymbolHeader
+{
+ ULONG dwMagic,dwSize;
+ char Copyright[256];
+ char ModuleName[256];
+ ULONG NumberOfSymbols;
+ ULONG Reserved; // for future extension
+}LOADERSYMBOLHEADER,*PLOADERSYMBOLHEADER;
+
+typedef struct tagLoaderSymbolRecord
+{
+ ULONG ModuleNameLength;
+ ULONG NameLength;
+ ULONG Address;
+ ULONG Type;
+ ULONG Class;
+}LOADERSYMBOLRECORD,*PLOADERSYMBOLRECORD;
+
+typedef struct tagLoaderSymbolFile
+{
+ LOADERSYMBOLHEADER LoaderSymbolHeader; // file header
+ LOADERSYMBOLRECORD LoaderSymbolRecord[1]; // symbol records (symbol + source file)
+}LOADERSYMBOLFILE,*PLOADERSYMBOLFILE;
+
+typedef struct tagLoaderSymbolPool
+{
+ ULONG NumberOfFiles;
+ ULONG SizeOfThisHeap;
+ LOADERSYMBOLHEADER LoaderSymbolHeader; // file header
+ LOADERSYMBOLRECORD LoaderSymbolRecord[1]; // symbol records (symbol + source file)
+}LOADERSYMBOLPOOL,*PLOADERSYMBOLPOOL;
+
+// end of
+// structure of symbol file
+///////////////////////////////////////////////////
--- /dev/null
+// this file is dynamically generated: DON'T TOUCH
+
+UCHAR cLogo[96]={
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xab,
+0xeb,
+0xfb,
+0xaf,
+0xbf,
+0xbf,
+0xab,
+0xab,
+0x81,
+0xe0,
+0x78,
+0x37,
+0x9c,
+0x1c,
+0x03,
+0x01,
+0x88,
+0xe2,
+0x3c,
+0x63,
+0x9e,
+0x3f,
+0x8f,
+0x1f,
+0x9c,
+0x67,
+0x1c,
+0x71,
+0x1c,
+0x1f,
+0x1f,
+0x1f,
+0x98,
+0xe2,
+0x3c,
+0x73,
+0x3c,
+0x9f,
+0x9f,
+0x03,
+0x81,
+0xe0,
+0x7c,
+0x71,
+0x3d,
+0xdf,
+0x1f,
+0x17,
+0x83,
+0xe0,
+0x7c,
+0x78,
+0x38,
+0x0f,
+0x9f,
+0x3f,
+0x9f,
+0xe7,
+0x3c,
+0x7c,
+0x70,
+0x07,
+0x1f,
+0x1f,
+0x8f,
+0xe3,
+0x38,
+0x38,
+0x79,
+0xcf,
+0x9f,
+0x03,
+0x9f,
+0xe7,
+0x18,
+0x3c,
+0x71,
+0xc7,
+0x1f,
+0x01,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+};
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ output.c
+
+Abstract:
+
+ catch debugging outputs
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 14-Nov-1999: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+/*
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <linux/utsname.h>
+#include <linux/sched.h>
+#include <linux/console.h>
+#include <asm/delay.h>
+*/
+
+char tempOutput[1024],tempOutput2[1024];
+
+//ULONG ulPrintk=0;
+
+ULONG (*ulPrintk) (PANSI_STRING String);
+
+BOOLEAN bInPrintk = FALSE;
+BOOLEAN bIsDebugPrint = FALSE;
+BOOLEAN bIsPrintkPatched = FALSE;
+
+ULONG ulCountTimerEvents = 0;
+
+#ifdef __cplusplus
+#define CPP_ASMLINKAGE extern "C"
+#else
+#define CPP_ASMLINKAGE
+#endif
+#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
+
+asmlinkage int printk(const char *fmt, ...);
+
+//EXPORT_SYMBOL(printk);
+
+//*************************************************************************
+// printk()
+//
+// this function overrides printk() in the kernel
+//*************************************************************************
+asmlinkage int printk(const char *fmt, ...)
+{
+ ULONG len,ulRingBufferLock;
+ static LONGLONG ulOldJiffies = 0;
+ LARGE_INTEGER jiffies;
+
+ va_list args;
+ va_start(args, fmt);
+
+ if((len = PICE_strlen((LPSTR)fmt)) )
+ {
+ save_flags(ulRingBufferLock);
+ cli();
+
+ PICE_vsprintf(tempOutput, fmt, args);
+ bIsDebugPrint = TRUE;
+ // if the last debug print was longer than 50 ms ago
+ // directly print it, else just add it to the ring buffer
+ // and let the timer process it.
+ KeQuerySystemTime(&jiffies);
+ if( (jiffies.QuadPart-ulOldJiffies) > 10000*(1*wWindow[OUTPUT_WINDOW].cy)/2)
+ {
+ ulOldJiffies = jiffies.QuadPart;
+ Print(OUTPUT_WINDOW,tempOutput);
+ }
+ else
+ {
+ AddToRingBuffer(tempOutput);
+ }
+
+ bIsDebugPrint = FALSE;
+ restore_flags(ulRingBufferLock);
+ }
+ va_end(args);
+
+ return 0;
+}
+
+//*************************************************************************
+// CountArgs()
+//
+// count occurrence of '%' in format string (except %%)
+// validity of whole format string must have been enforced
+//*************************************************************************
+ULONG CountArgs(LPSTR fmt)
+{
+ ULONG count=0;
+
+ while(*fmt)
+ {
+ if(*fmt=='%' && *(fmt+1)!='%')
+ count++;
+ fmt++;
+ }
+ return count;
+}
+
+//***********************************************************************************
+// Our replacement of kernel function.
+// Must not make any calls to KdpPrintString (e.g. by calling DbgPrint).
+//***********************************************************************************
+ULONG PICE_KdpPrintString(PANSI_STRING String)
+{
+ ULONG ulRingBufferLock;
+
+ save_flags(ulRingBufferLock);
+ cli();
+
+ /* CH: What is bIsDebugPrint used for? */
+ bIsDebugPrint = FALSE;
+
+ DPRINT((0,"PICE_KdpPrintString\n\n\n"));
+ AddToRingBuffer(String->Buffer);
+ restore_flags(ulRingBufferLock);
+}
+//*************************************************************************
+// PrintkCallback()
+//
+// called from RealIsr() when processing INT3 placed
+// Must not make any calls to KdpPrintString (e.g. by calling DbgPrint).
+//*************************************************************************
+void PrintkCallback(void)
+{
+ LPSTR fmt,args;
+ ULONG ulAddress;
+ ULONG countArgs,i,len;
+ PANSI_STRING temp;
+ CHAR buf[128];
+
+ DPRINT((0,"In PrintkCallback\n"));
+
+ bInPrintk = TRUE;
+
+ // get the linear address of stack where string resides
+ ulAddress = GetLinearAddress(CurrentSS,CurrentESP);
+ if(ulAddress)
+ {
+ DPRINT((0,"In PrintkCallback: ulAddress: %x\n", ulAddress));
+ if(IsAddressValid(ulAddress+sizeof(char *)) )
+ {
+ //KdpPrintString has PANSI_STRING as a parameter
+ temp = (PANSI_STRING)*(PULONG)(ulAddress+sizeof(char *));
+ DPRINT((0,"PrintkCallback: %s\n", temp->Buffer));
+ /* Call our version of KdpPrintString() */
+ CurrentEIP = (ULONG_PTR)PICE_KdpPrintString;
+ }
+ }
+ bInPrintk = FALSE;
+}
+
+//*************************************************************************
+// PiceRunningTimer()
+//
+//*************************************************************************
+
+KTIMER PiceTimer;
+KDPC PiceTimerDPC;
+
+// do I need it here? Have to keep DPC memory resident #pragma code_seg()
+VOID PiceRunningTimer(IN PKDPC Dpc,
+ IN PVOID DeferredContext,
+ IN PVOID SystemArgument1,
+ IN PVOID SystemArgument2)
+{
+ CheckRingBuffer();
+
+ if(ulCountTimerEvents++ > 10)
+ {
+ LARGE_INTEGER jiffies;
+
+ ulCountTimerEvents = 0;
+
+ KeQuerySystemTime(&jiffies);
+ SetForegroundColor(COLOR_TEXT);
+ SetBackgroundColor(COLOR_CAPTION);
+ PICE_sprintf(tempOutput,"jiffies = %.8X\n",jiffies.u.LowPart);
+ PutChar(tempOutput,GLOBAL_SCREEN_WIDTH-strlen(tempOutput),GLOBAL_SCREEN_HEIGHT-1);
+ ResetColor();
+ }
+}
+
+//*************************************************************************
+// InitPiceRunningTimer()
+//
+//*************************************************************************
+void InitPiceRunningTimer(void)
+{
+ LARGE_INTEGER Interval;
+
+ ENTER_FUNC();
+#if 0 //won't work. we have to intercept timer interrupt so dpc will never fire while we are in pice
+ KeInitializeTimer( &PiceTimer );
+ KeInitializeDpc( &PiceTimerDPC, PiceRunningTimer, NULL );
+
+ Interval.QuadPart=-1000000L; // 100 millisec. (unit is 100 nanosec.)
+
+ KeSetTimerEx(&PiceTimer,
+ Interval, 1000000L,
+ &PiceTimerDpc);
+#endif
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// RemovePiceRunningTimer()
+//
+//*************************************************************************
+void RemovePiceRunningTimer(void)
+{
+ KeCancelTimer( &PiceTimer );
+}
+
+//*************************************************************************
+// InstallPrintkHook()
+//
+//*************************************************************************
+void InstallPrintkHook(void)
+{
+
+ ENTER_FUNC();
+
+ if( bIsPrintkPatched )
+ return;
+
+ DPRINT((0,"installing PrintString hook\n"));
+ ScanExports("_KdpPrintString",(PULONG)&ulPrintk);
+
+ DPRINT((0,"_KdpPrintString @ %x\n", ulPrintk));
+ ASSERT( ulPrintk ); // temporary
+ if(ulPrintk)
+ {
+ bIsPrintkPatched = InstallSWBreakpoint(ulPrintk,TRUE,PrintkCallback);
+ DPRINT((0,"KdpPrintStringTest breakpoint installed? %d\n", bIsPrintkPatched));
+ }
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// DeInstallPrintkHook()
+//
+//*************************************************************************
+void DeInstallPrintkHook(void)
+{
+ ENTER_FUNC();
+
+ DPRINT((0,"enter DeInstallPrintkHook()\n"));
+ if(bIsPrintkPatched && ulPrintk)
+ {
+ // will be done on exit debugger
+ if (DeInstallSWBreakpoint(ulPrintk))
+ bIsPrintkPatched = FALSE;
+ }
+ LEAVE_FUNC();
+}
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ output.h
+
+Abstract:
+
+ HEADER for output.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+void InstallPrintkHook(void);
+void DeInstallPrintkHook(void);
+
+//extern ULONG ulPrintk;
+
+extern ULONG (*ulPrintk) (PANSI_STRING String);
+
+extern BOOLEAN bInPrintk;
+extern BOOLEAN bIsDebugPrint;
+
+void InitPiceRunningTimer(void);
+void RemovePiceRunningTimer(void);
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ parse.c
+
+Abstract:
+
+ execution of debugger commands
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 19-Aug-1998: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+#include "pci_ids.h"
+
+///////////////////////////////////////////////////
+// GLOBALS
+
+ULONG ValueTrue=1,ValueFalse=0;
+ULONG ulLastDisassStartAddress=0,ulLastDisassEndAddress=0,ulLastInvertedAddress=0;
+USHORT gCurrentSelector=0;
+ULONG gCurrentOffset=0;
+LONG ulCurrentlyDisplayedLineNumber=0;
+USHORT usOldDisasmSegment = 0;
+ULONG ulOldDisasmOffset = 0;
+static ULONG ulCountForWaitKey = 0;
+
+extern PDEBUG_MODULE pdebug_module_head;
+extern PDEBUG_MODULE pdebug_module_tail;
+
+//extern unsigned long sys_call_table[];
+
+BOOLEAN (*DisplayMemory)(PARGS) = DisplayMemoryDword;
+
+char szCurrentFile[256]="";
+PDEBUG_MODULE pCurrentMod=NULL;
+PICE_SYMBOLFILE_HEADER* pCurrentSymbols=NULL;
+
+// suppresses passing on of function keys while stepping code
+BOOLEAN bStepping = FALSE;
+BOOLEAN bInt3Here = TRUE;
+BOOLEAN bInt1Here = TRUE;
+
+KEYWORDS RegKeyWords[]={
+ {"eax",&CurrentEAX,sizeof(ULONG)},
+ {"ebx",&CurrentEBX,sizeof(ULONG)},
+ {"ecx",&CurrentECX,sizeof(ULONG)},
+ {"edx",&CurrentEDX,sizeof(ULONG)},
+ {"edi",&CurrentEDI,sizeof(ULONG)},
+ {"esi",&CurrentESI,sizeof(ULONG)},
+ {"ebp",&CurrentEBP,sizeof(ULONG)},
+ {"esp",&CurrentESP,sizeof(ULONG)},
+ {"eip",&CurrentEIP,sizeof(ULONG)},
+ {NULL,0,0}
+};
+
+KEYWORDS SelectorRegKeyWords[]={
+ {"cs",&CurrentCS,sizeof(USHORT)},
+ {"ds",&CurrentDS,sizeof(USHORT)},
+ {"es",&CurrentES,sizeof(USHORT)},
+ {"fs",&CurrentFS,sizeof(USHORT)},
+ {"gs",&CurrentGS,sizeof(USHORT)},
+ {"ss",&CurrentSS,sizeof(USHORT)},
+ {NULL,0,0}
+};
+
+KEYWORDS OnOffKeyWords[]={
+ {"on",&ValueTrue,sizeof(ULONG)},
+ {"off",&ValueFalse,sizeof(ULONG)},
+ {NULL,0,0}
+};
+
+KEYWORDS SpecialKeyWords[]={
+ {"process",&CurrentProcess,sizeof(ULONG)},
+ {NULL,0,0}
+};
+
+LPSTR LocalVarRegs[]=
+{
+ "EAX",
+ "ECX",
+ "EDX",
+ "EBX",
+ "ESP",
+ "EBP",
+ "ESI",
+ "EDI",
+ "EIP",
+ "EFL",
+ "CS",
+ "SS",
+ "DS",
+ "ES",
+ "FS",
+ "GS"
+};
+
+
+#define COMMAND_HAS_NO_PARAMS (0)
+#define COMMAND_HAS_PARAMS (1<<0)
+#define COMMAND_HAS_SWITCHES (1<<1)
+//
+#define PARAM_CAN_BE_SYMBOLIC (1<<0)
+#define PARAM_CAN_BE_SEG_OFFSET (1<<1)
+#define PARAM_CAN_BE_MODULE (1<<2)
+#define PARAM_CAN_BE_PRNAME (1<<3)
+#define PARAM_CAN_BE_PID (1<<4)
+#define PARAM_CAN_BE_SRC_FILE (1<<5)
+#define PARAM_CAN_BE_NUMERIC (1<<6)
+#define PARAM_CAN_BE_REG_KEYWORD (1<<7)
+#define PARAM_CAN_BE_ONOFF_KEYWORD (1<<8)
+#define PARAM_CAN_BE_SPECIAL_KEYWORD (1<<9)
+#define PARAM_CAN_BE_ASTERISK (1<<10)
+#define PARAM_CAN_BE_ONOFF (1<<11)
+#define PARAM_CAN_BE_VIRTUAL_SYMBOLIC (1<<12)
+#define PARAM_CAN_BE_SRCLINE (1<<13)
+#define PARAM_CAN_BE_PARTIAL_SYM_NAME (1<<14)
+#define PARAM_CAN_BE_ANY_STRING (1<<15)
+#define PARAM_CAN_BE_DECIMAL (1<<16)
+#define PARAM_CAN_BE_SIZE_DESC (1<<17)
+#define PARAM_CAN_BE_LETTER (1<<18)
+//
+#define COMMAND_GROUP_HELP (0)
+#define COMMAND_GROUP_FLOW (1)
+#define COMMAND_GROUP_STRUCT (2)
+#define COMMAND_GROUP_OS (3)
+#define COMMAND_GROUP_MEM (4)
+#define COMMAND_GROUP_BREAKPOINT (5)
+#define COMMAND_GROUP_WINDOW (6)
+#define COMMAND_GROUP_DEBUG (7)
+#define COMMAND_GROUP_INFO (8)
+#define COMMAND_GROUP_STATE (9)
+#define COMMAND_GROUP_HELP_ONLY (10)
+#define COMMAND_GROUP_LAST (11)
+
+LPSTR CommandGroups[]=
+{
+ "HELP",
+ "FLOW CONTROL",
+ "STRUCTURES",
+ "OS SPECIFIC",
+ "MEMORY",
+ "BREAKPOINTS",
+ "WINDOW",
+ "DEBUGGING",
+ "INFORMATION",
+ "STATE",
+ "EDITOR",
+ NULL
+};
+// table of command handlers
+CMDTABLE CmdTable[]={
+ {"gdt",ShowGdt,"display current global descriptor table" ,0,{0,0,0,0,0},"",COMMAND_GROUP_STRUCT},
+ {"idt",ShowIdt,"display current interrupt descriptor table" ,0,{0,0,0,0,0},"",COMMAND_GROUP_STRUCT},
+ {"x",LeaveIce,"return to Reactos" ,0,{0,0,0,0,0},"",COMMAND_GROUP_FLOW},
+ {"t",SingleStep,"single step one instruction" ,0,{0,0,0,0,0},"",COMMAND_GROUP_FLOW},
+ {"vma",ShowVirtualMemory,"displays VMAs" ,0,{0,0,0,0,0},"",COMMAND_GROUP_OS},
+ {"h",ShowHelp,"list help on commands" ,0,{0,0,0,0,0},"",COMMAND_GROUP_HELP},
+ {"page",ShowPageDirs,"dump page directories" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC|PARAM_CAN_BE_REG_KEYWORD,0,0,0,0},"",COMMAND_GROUP_STRUCT},
+ {"proc",ShowProcesses,"list all processes" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_PRNAME|PARAM_CAN_BE_PID,0,0,0,0},"",COMMAND_GROUP_OS},
+ {"dd",DisplayMemoryDword,"display dword memory" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC|PARAM_CAN_BE_SYMBOLIC|PARAM_CAN_BE_REG_KEYWORD,0,0,0,0},"",COMMAND_GROUP_MEM},
+ {"db",DisplayMemoryByte,"display byte memory " ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC|PARAM_CAN_BE_SYMBOLIC|PARAM_CAN_BE_REG_KEYWORD,0,0,0,0},"",COMMAND_GROUP_MEM},
+ {"dpd",DisplayPhysMemDword,"display dword physical memory" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC,0,0,0,0},"",COMMAND_GROUP_MEM},
+ {"u",Unassemble,"disassemble at address" ,COMMAND_HAS_PARAMS|COMMAND_HAS_SWITCHES,{PARAM_CAN_BE_NUMERIC|PARAM_CAN_BE_SYMBOLIC|PARAM_CAN_BE_REG_KEYWORD|PARAM_CAN_BE_SRCLINE,0,0,0,0},"f",COMMAND_GROUP_MEM},
+ {"mod",ShowModules,"displays all modules" ,0,{0,0,0,0,0},"",COMMAND_GROUP_OS},
+ {"bpx",SetBreakpoint,"set code breakpoint" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC|PARAM_CAN_BE_VIRTUAL_SYMBOLIC|PARAM_CAN_BE_SYMBOLIC|PARAM_CAN_BE_SRCLINE|PARAM_CAN_BE_REG_KEYWORD,0,0,0,0},"",COMMAND_GROUP_BREAKPOINT},
+ {"bl",ListBreakpoints,"list breakpoints" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC,0,0,0,0},"",COMMAND_GROUP_BREAKPOINT},
+ {"bc",ClearBreakpoints,"clear breakpoints" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC|PARAM_CAN_BE_ASTERISK,0,0,0,0},"",COMMAND_GROUP_BREAKPOINT},
+ {"ver",Ver,"display pICE version and state information" ,0,{0,0,0,0,0},"",COMMAND_GROUP_INFO},
+ {"hboot",Hboot,"hard boot the system" ,0,{0,0,0,0,0},"",COMMAND_GROUP_FLOW},
+ {"code",SetCodeDisplay,"toggle code display" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_ONOFF,0,0,0,0},"",COMMAND_GROUP_STATE},
+ {"cpu",ShowCPU,"display CPU special registers" ,0,{0,0,0,0,0},"",COMMAND_GROUP_STRUCT},
+ {"stack",WalkStack,"display call stack" ,0,{0,0,0,0,0},"",COMMAND_GROUP_STRUCT},
+ {"peek",PeekMemory,"peek at physical memory" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_SIZE_DESC,PARAM_CAN_BE_NUMERIC,0,0,0},"",COMMAND_GROUP_MEM},
+ {"poke",PokeMemory,"poke to physical memory" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_SIZE_DESC,PARAM_CAN_BE_NUMERIC,PARAM_CAN_BE_NUMERIC,0,0},"",COMMAND_GROUP_MEM},
+ {".",UnassembleAtCurrentEip,"unassemble at current instruction" ,0,{0,0,0,0,0},"",COMMAND_GROUP_MEM},
+ {"p",StepOver,"single step over call" ,0,{0,0,0,0,0},"",COMMAND_GROUP_FLOW},
+ {"i",StepInto,"single step into call" ,0,{0,0,0,0,0},"",COMMAND_GROUP_FLOW},
+ {"locals",ShowLocals,"display local symbols" ,0,{0,0,0,0,0},"",COMMAND_GROUP_MEM},
+ {"table",SwitchTables,"display loaded symbol tables" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_MODULE,0,0,0,0},"",COMMAND_GROUP_DEBUG},
+ {"file",SwitchFiles,"display source files in symbol table" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_SRC_FILE,0,0,0,0},"",COMMAND_GROUP_DEBUG},
+ {"sym",ShowSymbols,"list known symbol information" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_PARTIAL_SYM_NAME,0,0,0,0},"",COMMAND_GROUP_DEBUG},
+ {"?",EvaluateExpression,"evaluate an expression" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_ANY_STRING,0,0,0,0},"",COMMAND_GROUP_DEBUG},
+ {"src",SetSrcDisplay,"sets disassembly mode" ,0,{0,0,0,0,0},"",COMMAND_GROUP_DEBUG},
+ {"wc",SizeCodeWindow,"change size of code window" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_DECIMAL,0,0,0,0},"",COMMAND_GROUP_WINDOW},
+ {"wd",SizeDataWindow,"change size of data window" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_DECIMAL,0,0,0,0},"",COMMAND_GROUP_WINDOW},
+ {"r",SetGetRegisters,"sets or displays registers" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_REG_KEYWORD,PARAM_CAN_BE_NUMERIC,0,0,0},"",COMMAND_GROUP_STRUCT},
+ {"cls",ClearScreen,"clear output window" ,0,{0,0,0,0,0},"",COMMAND_GROUP_WINDOW},
+ {"phys",ShowMappings,"show all mappings for linear address" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC,0,0,0,0},"",COMMAND_GROUP_MEM},
+ {"timers",ShowTimers,"show all active timers" ,0,{0,0,0,0,0},"",COMMAND_GROUP_OS},
+ {"pci",ShowPCI,"show PCI devices" ,COMMAND_HAS_PARAMS|COMMAND_HAS_SWITCHES,{PARAM_CAN_BE_DECIMAL,PARAM_CAN_BE_DECIMAL,0,0,0},"a",COMMAND_GROUP_INFO},
+ {"next",NextInstr,"advance EIP to next instruction" ,0,{0,0,0,0,0},""},
+ {"i3here",I3here,"catch INT 3s" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_ONOFF,0,0,0,0},"",COMMAND_GROUP_FLOW},
+ {"layout",SetKeyboardLayout,"sets keyboard layout" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_ANY_STRING,0,0,0,0},"",COMMAND_GROUP_FLOW},
+ {"syscall",ShowSysCallTable,"displays syscall (table)" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_DECIMAL,0,0,0,0},"",COMMAND_GROUP_FLOW},
+ {"altkey",SetAltKey,"set alternate break key" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_LETTER,0,0,0,0},"",COMMAND_GROUP_FLOW},
+ {"addr",ShowContext,"show/set address contexts" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_PRNAME,0,0,0,0},"",COMMAND_GROUP_FLOW},
+ {"arrow up",NULL,"" ,0,{0,0,0,0,0},"",COMMAND_GROUP_HELP_ONLY},
+ {NULL,0,NULL}
+};
+
+char tempCmd[1024];
+
+char HexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+
+CPUINFO CPUInfo[]={
+ {"DR0",&CurrentDR0},
+ {"DR1",&CurrentDR1},
+ {"DR2",&CurrentDR2},
+ {"DR3",&CurrentDR3},
+ {"DR6",&CurrentDR6},
+ {"DR7",&CurrentDR7},
+ {"EFLAGS",&CurrentEFL},
+ {"CR0",&CurrentCR0},
+ {"CR2",&CurrentCR2},
+ {"CR3",&CurrentCR3},
+ {"",NULL},
+};
+
+BP Bp[4]={
+ {0,0,0,FALSE,FALSE,FALSE,"",""},
+ {0,0,0,FALSE,FALSE,FALSE,"",""},
+ {0,0,0,FALSE,FALSE,FALSE,"",""},
+ {0,0,0,FALSE,FALSE,FALSE,"",""}
+};
+
+BOOLEAN bShowSrc = TRUE;
+BOOLEAN bCodeOn = FALSE;
+BOOLEAN bNeedToFillBuffer = TRUE;
+
+char *NonSystemSegmentTypes[]=
+{
+ "Data RO",
+ "Data RO accessed",
+ "Data RW",
+ "Data RW accessed",
+ "Data RO expand-dwon",
+ "Data RO expand-down, accessed",
+ "Data RW expand-dwon",
+ "Data RW expand-down, accessed",
+ "Code EO",
+ "Code EO accessed",
+ "Code ER",
+ "Code ER accessed",
+ "Code EO conforming",
+ "Code EO conforming, accessed",
+ "Code ER conforming",
+ "Code ER conforming, accessed"
+};
+
+char *SystemSegmentTypes[]=
+{
+ "reserved0",
+ "16-bit TSS (available)",
+ "LDT",
+ "16-bit TSS (busy)",
+ "16-bit call gate",
+ "task gate",
+ "16-bit interrupt gate",
+ "16-bit trap gate",
+ "reserved1",
+ "32-bit TSS (available)",
+ "reserved2",
+ "32-bit TSS (busy)",
+ "32-bit call gate",
+ "reserved3",
+ "32-bit interrupt gate",
+ "32-bit trap gate"
+};
+
+////////////////////////////////////////////////////
+// FUNCTIONS
+////
+
+//*************************************************************************
+// RepaintSource()
+//
+//*************************************************************************
+void RepaintSource(void)
+{
+ ARGS Args;
+
+ ENTER_FUNC();
+
+ // disassembly from current address
+ PICE_memset(&Args,0,sizeof(ARGS));
+ // make unassembler refresh all again
+ ulLastDisassStartAddress=ulLastDisassEndAddress=0;
+ Args.Count=0;
+ Unassemble(&Args);
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// RepaintDesktop()
+//
+//*************************************************************************
+void RepaintDesktop(void)
+{
+ ARGS Args;
+
+ ENTER_FUNC();
+
+ PrintTemplate();
+
+ DisplayRegs();
+
+ // display data window
+ Args.Value[0]=OldSelector;
+ Args.Value[1]=OldOffset;
+ Args.Count=2;
+ DisplayMemory(&Args);
+
+ // disassembly from current address
+ PICE_memset(&Args,0,sizeof(ARGS));
+ // make unassembler refresh all again
+ ulLastDisassStartAddress=ulLastDisassEndAddress=0;
+ Args.Count=0;
+ Unassemble(&Args);
+
+ PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
+ Print(OUTPUT_WINDOW,"");
+
+ ShowStoppedMsg();
+ ShowStatusLine();
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// PutStatusText()
+//
+//*************************************************************************
+void PutStatusText(LPSTR p)
+{
+ ENTER_FUNC();
+
+ ClrLine(wWindow[OUTPUT_WINDOW].y-1);
+ PutChar(p,1,wWindow[OUTPUT_WINDOW].y-1);
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// WaitForKey()
+//
+//*************************************************************************
+BOOLEAN WaitForKey(void)
+{
+ BOOLEAN result=TRUE;
+
+ if(ulCountForWaitKey == 0)
+ SuspendPrintRingBuffer(TRUE);
+
+ ulCountForWaitKey++;
+
+ if(ulCountForWaitKey == (wWindow[OUTPUT_WINDOW].cy-1))
+ {
+ SuspendPrintRingBuffer(FALSE);
+
+ PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
+
+ ulCountForWaitKey = 0;
+
+ SetBackgroundColor(WHITE);
+ ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
+ PutChar(" Press any key to continue listing or press ESC to stop... ",1,wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
+ ucKeyPressedWhileIdle=0;
+ while(!(ucKeyPressedWhileIdle=GetKeyPolled()))
+ {
+ PrintCursor(FALSE);
+ }
+ SetBackgroundColor(BLACK);
+ // if ESCAPE then indicate retreat
+ if(ucKeyPressedWhileIdle==SCANCODE_ESC)
+ {
+ result=FALSE;
+ }
+ ucKeyPressedWhileIdle=0;
+ }
+
+
+ return result;
+}
+
+/////////////////////////////////////////////////////////////
+// command handlers
+/////////////////////////////////////////////////////////////
+
+//*************************************************************************
+// SingleStep()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(SingleStep)
+{
+ ULONG ulLineNumber;
+ LPSTR pSrcStart,pSrcEnd,pFilename;
+
+ ENTER_FUNC();
+
+ if(FindSourceLineForAddress(GetLinearAddress(CurrentCS,CurrentEIP),&ulLineNumber,&pSrcStart,&pSrcEnd,&pFilename))
+ {
+ DPRINT((0,"SingleStep(): stepping into source\n"));
+ StepInto(NULL);
+ }
+ else
+ {
+ // modify trace flag
+ CurrentEFL|=0x100; // set trace flag (TF)
+
+ bSingleStep=TRUE;
+ bNotifyToExit=TRUE;
+ }
+
+ bStepping = TRUE;
+
+ LEAVE_FUNC();
+
+ return TRUE;
+}
+
+
+//*************************************************************************
+// StepOver()
+//
+// step over calls
+//*************************************************************************
+COMMAND_PROTOTYPE(StepOver)
+{
+ char tempDisasm[256];
+ ULONG dwBreakAddress;
+ ULONG ulLineNumber;
+ LPSTR pSrcStart,pSrcEnd,pFilename;
+
+ ENTER_FUNC();
+
+ DPRINT((0,"StepOver():\n"));
+
+ // only no arguments supplied
+ // when we have source and current disassembly mod is SOURCE
+ // we have to analyse the code block for the source line
+ if(FindSourceLineForAddress(GetLinearAddress(CurrentCS,CurrentEIP),&ulLineNumber,&pSrcStart,&pSrcEnd,&pFilename))
+ {
+ DPRINT((0,"StepOver(): we have source here!\n"));
+ DPRINT((0,"StepOver(): line #%u in file = %s!\n",ulLineNumber,pFilename));
+
+ g_ulLineNumberStart = ulLineNumber;
+ bStepThroughSource = TRUE;
+
+ // deinstall the INT3 in kernel's printk()
+ DeInstallPrintkHook();
+
+ goto proceed_as_normal;
+ }
+ else
+ {
+ DPRINT((0,"StepOver(): no source here!\n"));
+
+proceed_as_normal:
+ // if there is some form of call instruction at EIP we need to find
+ // the return address
+ if(IsCallInstrAtEIP())
+ {
+ // get address of next instruction
+ dwBreakAddress=GetLinearAddress(CurrentCS,CurrentEIP);
+
+ Disasm(&dwBreakAddress,tempDisasm);
+
+ DPRINT((0,"address of break = %.4X:%.8X\n",CurrentCS,dwBreakAddress));
+
+ dwBreakAddress=GetLinearAddress(CurrentCS,dwBreakAddress);
+
+ DPRINT((0,"linear address of break = %.8X\n",dwBreakAddress));
+
+ DPRINT((0,"setting DR0=%.8X\n",dwBreakAddress));
+
+ SetHardwareBreakPoint(dwBreakAddress,0);
+
+ bSingleStep = FALSE;
+ bNotifyToExit = TRUE;
+ }
+ else
+ {
+ DPRINT((0,"no call at breakpoint\n"));
+ // modify trace flag
+ CurrentEFL|=0x100; // set trace flag (TF)
+
+ bSingleStep=TRUE;
+ bNotifyToExit=TRUE;
+ }
+ }
+
+ bStepInto = FALSE;
+
+ bStepping = TRUE;
+
+ LEAVE_FUNC();
+
+ return TRUE;
+}
+
+//*************************************************************************
+// StepInto()
+//
+// step into calls
+//*************************************************************************
+COMMAND_PROTOTYPE(StepInto)
+{
+ ULONG ulLineNumber;
+ LPSTR pSrcStart,pSrcEnd,pFilename;
+
+ ENTER_FUNC();
+
+ // only no arguments supplied
+ // when we have source and current disassembly mod is SOURCE
+ // we have to analyse the code block for the source line
+ if(FindSourceLineForAddress(GetLinearAddress(CurrentCS,CurrentEIP),&ulLineNumber,&pSrcStart,&pSrcEnd,&pFilename))
+ {
+ DPRINT((0,"StepOver(): we have source here!\n"));
+ DPRINT((0,"StepOver(): line #%u in file = %s!\n",ulLineNumber,pFilename));
+
+ g_ulLineNumberStart = ulLineNumber;
+ bStepThroughSource = TRUE;
+
+ // deinstall the INT3 in kernel's printk()
+ DeInstallPrintkHook();
+
+ goto proceed_as_normal_into;
+ }
+ else
+ {
+ DPRINT((0,"StepInto(): no source here!\n"));
+
+proceed_as_normal_into:
+
+ // modify trace flag
+ CurrentEFL|=0x100; // set trace flag (TF)
+
+ bSingleStep=TRUE;
+ bNotifyToExit=TRUE;
+ }
+
+ bStepInto = TRUE;
+
+ bStepping = TRUE;
+
+ LEAVE_FUNC();
+
+ return TRUE;
+}
+
+//*************************************************************************
+// SetBreakpoint()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(SetBreakpoint)
+{
+ ULONG addr,addrorg;
+ USHORT segment;
+
+ if(pArgs->Count<=2)
+ {
+ if(pArgs->bNotTranslated[0]==FALSE)
+ {
+ if(gCurrentSelector)
+ {
+ addr=pArgs->Value[0];
+ addrorg=gCurrentOffset;
+ segment=gCurrentSelector;
+ }
+ else
+ {
+ addrorg=addr=pArgs->Value[0];
+ segment=CurrentCS;
+ }
+
+ if(InstallSWBreakpoint(GetLinearAddress(segment,addr),FALSE,NULL) )
+ {
+ PICE_sprintf(tempCmd,"BP #%u set to %.4X:%.8X\n",0,segment,addr);
+ }
+ else
+ {
+ PICE_sprintf(tempCmd,"BP #%u NOT set (either page not valid OR already used)\n",0);
+ }
+ Print(OUTPUT_WINDOW,tempCmd);
+ }
+ else
+ {
+ if(InstallVirtualSWBreakpoint((LPSTR)pArgs->Value[0],(LPSTR)pArgs->Value[1]) )
+ {
+ PICE_sprintf(tempCmd,"BP #%u virtually set to %s!%s\n",0,(LPSTR)pArgs->Value[0],(LPSTR)pArgs->Value[1]);
+ }
+ else
+ {
+ PICE_sprintf(tempCmd,"BP #%u NOT set (maybe no symbols loaded)\n",0);
+ }
+ Print(OUTPUT_WINDOW,tempCmd);
+ }
+
+ RepaintSource();
+
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// ListBreakpoints()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ListBreakpoints)
+{
+ ULONG i;
+
+ ListSWBreakpoints();
+
+ for(i=0;i<4;i++)
+ {
+ if(Bp[i].Used)
+ {
+ PICE_sprintf(tempCmd,"(%u) %s %.4X:%.8X(linear %.8X)\n",i,Bp[i].Active?"*":" ",Bp[i].Segment,Bp[i].Offset,Bp[i].LinearAddress);
+ Print(OUTPUT_WINDOW,tempCmd);
+ }
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// ClearBreakpoints()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ClearBreakpoints)
+{
+ if(pArgs->Count)
+ {
+ if(pArgs->Value[0]<4)
+ {
+ Bp[pArgs->Value[0]].Used=Bp[pArgs->Value[0]].Active=FALSE;
+ }
+ RepaintSource();
+ }
+ else
+ {
+ ULONG i;
+
+ RemoveAllSWBreakpoints(FALSE);
+
+ for(i=0;i<4;i++)Bp[i].Used=Bp[i].Active=FALSE;
+ RepaintSource();
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// LeaveIce()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(LeaveIce)
+{
+ // SetHardwareBreakPoints();
+
+ bSingleStep=FALSE;
+ bNotifyToExit=TRUE;
+ return TRUE;
+}
+
+//*************************************************************************
+// ShowGdt()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowGdt)
+{
+ ULONG gdtr[2];
+ USHORT i;
+ PGDT pGdt;
+ static ULONG addr=0;
+ LPSTR pVerbose;
+
+ // get GDT register
+ __asm__ ("sgdt %0\n"
+ :"=m" (gdtr));
+
+ // info out
+ PICE_sprintf(tempCmd,"Address=%.8X Limit=%.4X\n",(gdtr[1]<<16)|(gdtr[0]>>16),gdtr[0]&0xFFFF);
+ Print(OUTPUT_WINDOW,tempCmd);
+ WaitForKey();
+
+ // make pointer to GDT
+ pGdt=(PGDT)(((ULONG)(gdtr[1]<<16))|((ULONG)(gdtr[0]>>16)));
+ if(pArgs->Count==1)
+ {
+ ULONG limit=((pGdt[addr].Limit_19_16<<16)|pGdt[addr].Limit_15_0);
+
+ addr=pArgs->Value[0];
+ addr&=(~0x7);
+ if(pGdt[addr>>3].Gran)limit=(limit*4096)|0xfff;
+
+ if(!pGdt[addr>>3].DescType)
+ pVerbose = SystemSegmentTypes[pGdt[addr>>3].SegType];
+ else
+ pVerbose = NonSystemSegmentTypes[pGdt[addr>>3].SegType];
+
+ PICE_sprintf(tempCmd,"%.4X %.8X %.8X %s %u %s\n",
+ addr,
+ (pGdt[addr>>3].Base_31_24<<24)|(pGdt[addr>>3].Base_23_16<<16)|(pGdt[addr>>3].Base_15_0),
+ limit,
+ pGdt[addr>>3].Present?" P":"NP",
+ pGdt[addr>>3].Dpl,
+ pVerbose);
+ Print(OUTPUT_WINDOW,tempCmd);
+ }
+ else if(pArgs->Count==0)
+ {
+ for(i=0;i<((gdtr[0]&0xFFFF)>>3);i++)
+ {
+ ULONG limit=((pGdt[i].Limit_19_16<<16)|pGdt[i].Limit_15_0);
+
+ if(!pGdt[i].DescType)
+ pVerbose = SystemSegmentTypes[pGdt[i].SegType];
+ else
+ pVerbose = NonSystemSegmentTypes[pGdt[i].SegType];
+
+ if(pGdt[i].Gran)limit=(limit*4096)|0xfff;
+
+ PICE_sprintf(tempCmd,"%.4X %.8X %.8X %s %u %s\n",
+ i<<3,
+ (pGdt[i].Base_31_24<<24)|(pGdt[i].Base_23_16<<16)|(pGdt[i].Base_15_0),
+ limit,
+ pGdt[i].Present?" P":"NP",
+ pGdt[i].Dpl,
+ pVerbose);
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)break;
+ }
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// OutputIdtEntry()
+//
+//*************************************************************************
+void OutputIdtEntry(PIDT pIdt,ULONG i)
+{
+ USHORT seg;
+ ULONG offset;
+ LPSTR pSym;
+
+ seg = (USHORT)pIdt[i].Selector;
+ offset = (pIdt[i].Offset_31_16<<16)|(pIdt[i].Offset_15_0);
+
+ switch(pIdt[i].DescType)
+ {
+ // task gate
+ case 0x5:
+ PICE_sprintf(tempCmd,"(%0.4X) %0.4X:%0.8X %u [task]\n",i,
+ seg,
+ GetLinearAddress((USHORT)seg,0),
+ pIdt[i].Dpl);
+ break;
+ // interrupt gate
+ case 0x6:
+ case 0xE:
+ if(ScanExportsByAddress(&pSym,GetLinearAddress((USHORT)seg,offset)))
+ {
+ PICE_sprintf(tempCmd,"(%0.4X) %0.4X:%0.8X %u [int] (%s)\n",i,
+ seg,
+ offset,
+ pIdt[i].Dpl,
+ pSym);
+ }
+ else
+ {
+ PICE_sprintf(tempCmd,"(%0.4X) %0.4X:%0.8X %u [int]\n",i,
+ seg,
+ offset,
+ pIdt[i].Dpl);
+ }
+ break;
+ // trap gate
+ case 0x7:
+ case 0xF:
+ if(ScanExportsByAddress(&pSym,GetLinearAddress((USHORT)seg,offset)))
+ {
+ PICE_sprintf(tempCmd,"(%0.4X) %0.4X:%0.8X %u [trap] (%s)\n",i,
+ seg,
+ offset,
+ pIdt[i].Dpl,
+ pSym);
+ }
+ else
+ {
+ PICE_sprintf(tempCmd,"(%0.4X) %0.4X:%0.8X %u [trap]\n",i,
+ seg,
+ offset,
+ pIdt[i].Dpl);
+ }
+ break;
+ default:
+ PICE_sprintf(tempCmd,"(%0.4X) INVALID\n",i);
+ break;
+ }
+ Print(OUTPUT_WINDOW,tempCmd);
+}
+
+//*************************************************************************
+// ShowIdt()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowIdt)
+{
+ ULONG idtr[2];
+ USHORT i;
+ PIDT pIdt;
+ ULONG addr=0;
+
+ ENTER_FUNC();
+
+ // get GDT register
+ __asm__ ("sidt %0\n"
+ :"=m" (idtr));
+ // info out
+ PICE_sprintf(tempCmd,"Address=%.8X Limit=%.4X\n",(idtr[1]<<16)|(idtr[0]>>16),idtr[0]&0xFFFF);
+ Print(OUTPUT_WINDOW,tempCmd);
+ WaitForKey();
+ // make pointer to GDT
+ pIdt=(PIDT)(((ULONG)(idtr[1]<<16))|((ULONG)(idtr[0]>>16)));
+ if(pArgs->Count==1)
+ {
+ addr=pArgs->Value[0];
+ addr&=(~0x7);
+
+ }
+ else if(pArgs->Count==0)
+ {
+ for(i=0;i<((idtr[0]&0xFFFF)>>3);i++)
+ {
+ OutputIdtEntry(pIdt,i);
+ if(WaitForKey()==FALSE)break;
+ }
+ }
+ LEAVE_FUNC();
+ return TRUE;
+}
+
+//*************************************************************************
+// ShowHelp()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowHelp)
+{
+ ULONG i,j;
+
+ PutStatusText("COMMAND KEYWORD DESCRIPTION");
+ for(j=0;j<COMMAND_GROUP_LAST;j++)
+ {
+ PICE_sprintf(tempCmd,"= %-20s =====================================\n",CommandGroups[j]);
+ Print(OUTPUT_WINDOW,tempCmd);
+ WaitForKey();
+
+ for(i=0;CmdTable[i].Cmd!=NULL;i++)
+ {
+ if(CmdTable[i].CommandGroup == j)
+ {
+ PICE_sprintf(tempCmd,"%-20s %s\n",CmdTable[i].Cmd,CmdTable[i].Help);
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)return TRUE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// ShowPageDirs()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowPageDirs)
+{
+ ULONG i;
+ PPAGEDIR pPageDir;
+ PULONG pPGD;
+ PULONG pPTE;
+ PEPROCESS my_current = IoGetCurrentProcess();
+
+ ENTER_FUNC();
+
+ DPRINT((0,"ShowPageDirs(): my_current = %.8X\n",(ULONG)my_current));
+
+ // don't touch if not valid process
+ if(my_current)
+ {
+ // no arguments supplied -> show all page directories
+ if(!pArgs->Count)
+ {
+ PutStatusText("Linear Physical Attributes");
+ // there are 1024 page directories each mapping 1024*4k of address space
+ for(i=0;i<1024;i++)
+ {
+ ULONG ulAddress = i<<22;
+ // from the mm_struct get pointer to page directory for this address
+ pPGD = ADDR_TO_PDE(ulAddress);
+ // create a structurized pointer from PGD
+ pPageDir = (PPAGEDIR)pPGD;
+
+ if(pPageDir->PTBase)
+ {
+
+ PICE_sprintf(tempCmd,"%.8X-%.8X %.8X %s %s %s\n",
+ ulAddress, ulAddress + 0x400000,
+ (pPageDir->PTBase<<12),
+ pPageDir->P?"P ":"NP",
+ pPageDir->RW?"RW":"R ",
+ pPageDir->US?"U":"S");
+ Print(OUTPUT_WINDOW,tempCmd);
+
+ if(WaitForKey()==FALSE)break;
+ }
+ }
+ }
+
+ // one arg supplied -> show individual page
+ else if(pArgs->Count == 1)
+ {
+ pPGD = ADDR_TO_PDE((ULONG)pArgs->Value[0]);
+
+ DPRINT((0,"ShowPageDirs(): VA = %.8X\n",pArgs->Value[0]));
+ DPRINT((0,"ShowPageDirs(): pPGD = %.8X\n",(ULONG)pPGD));
+
+ if(pPGD && ((*pPGD)&_PAGE_PRESENT))
+ {
+ // 4M page
+ if((*pPGD)&_PAGE_4M)
+ {
+ PPAGEDIR pPage = (PPAGEDIR)pPGD;
+
+ PutStatusText("Linear Physical Attributes");
+
+ PICE_sprintf(tempCmd,"%.8X %.8X %s %s %s (LARGE PAGE PTE @ %.8X)\n",
+ pArgs->Value[0],
+ (pPage->PTBase<<12)|(pArgs->Value[0]&0x7FFFFF),
+ pPage->P?"P ":"NP",
+ pPage->RW?"RW":"R ",
+ pPage->US?"U":"S",
+ (ULONG)pPGD);
+ }
+ else
+ {
+ pPTE = ADDR_TO_PTE(pArgs->Value[0]);
+ DPRINT((0,"ShowPageDirs(): pPTE = %.8X\n",(ULONG)pPTE));
+ if(pPTE)
+ {
+ PPAGEDIR pPage = (PPAGEDIR)pPTE;
+ DPRINT((0,"ShowPageDirs(): pPage->PTBase = %.8X\n",(ULONG)pPage->PTBase));
+
+ PutStatusText("Linear Physical Attributes");
+
+ PICE_sprintf(tempCmd,"%.8X %.8X %s %s %s (PTE @ %.8X)\n",
+ pArgs->Value[0],
+ (pPage->PTBase<<12)|(pArgs->Value[0]&(_PAGE_SIZE-1)),
+ (pPage->P==1)?"P ":"NP",
+ pPage->RW?"RW":"R ",
+ pPage->US?"U":"S",
+ (ULONG)pPTE);
+ }
+
+ }
+ Print(OUTPUT_WINDOW,tempCmd);
+ }
+ else
+ {
+ PICE_sprintf(tempCmd,"page at %.8X not present.\n",pArgs->Value[0]);
+ Print(OUTPUT_WINDOW,tempCmd);
+ }
+
+ }
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// ShowProcesses()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowProcesses)
+{
+ PEPROCESS my_current = IoGetCurrentProcess();
+ PLIST_ENTRY current_entry;
+ PEPROCESS currentps;
+
+ ENTER_FUNC();
+
+ current_entry = pPsProcessListHead->Flink;
+
+ if( current_entry ){
+
+ PutStatusText("NAME TASK PID");
+
+ while( current_entry != pPsProcessListHead ){
+ currentps = CONTAINING_RECORD(current_entry,
+ EPROCESS,
+ ProcessListEntry);
+ DPRINT((0,"currentps = %x\n",currentps));
+ //ei would be nice to mark current process!
+ PICE_sprintf(tempCmd,"%-16.16s %-12x %x\n",currentps->ImageFileName,
+ (ULONG)currentps,currentps->UniqueProcessId);
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)
+ break;
+ current_entry = current_entry->Flink;
+ }
+ }
+ LEAVE_FUNC();
+ return TRUE;
+}
+
+//*************************************************************************
+// DisplayMemoryDword()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(DisplayMemoryDword)
+{
+ ULONG i,j,k;
+ static ULONG addr=0,addrorg;
+ static USHORT segment;
+ char temp[8];
+ LPSTR pSymbolName;
+
+ ENTER_FUNC();
+ DPRINT((0,"DisplayMemoryDword()\n"));
+ if(pArgs->Count==2)
+ {
+ segment=(USHORT)pArgs->Value[0];
+ if(!segment)segment=GLOBAL_DATA_SEGMENT;
+ addr=pArgs->Value[1];
+ OldSelector = segment;
+ OldOffset = addr;
+ addrorg=addr;
+ addr=GetLinearAddress(segment,addr);
+ }
+ else if(pArgs->Count==1)
+ {
+ segment=CurrentDS;
+ addr=pArgs->Value[0];
+ OldOffset = addr;
+ addrorg=addr;
+ addr=GetLinearAddress(segment,addr);
+ }
+ else if(pArgs->Count==0)
+ {
+ addr += sizeof(ULONG)*4*4;
+ OldOffset = addr;
+ }
+
+ if(ScanExportsByAddress(&pSymbolName,addr))
+ {
+ PICE_sprintf(tempCmd," %s ",pSymbolName);
+ SetForegroundColor(COLOR_TEXT);
+ SetBackgroundColor(COLOR_CAPTION);
+ PutChar(tempCmd,GLOBAL_SCREEN_WIDTH-1-PICE_strlen(tempCmd),wWindow[DATA_WINDOW].y-1);
+ ResetColor();
+ }
+
+ DisableScroll(DATA_WINDOW);
+
+ if(DisplayMemory != DisplayMemoryDword)
+ {
+ Clear(DATA_WINDOW);
+ DisplayMemory = DisplayMemoryDword;
+ }
+ else
+ Home(DATA_WINDOW);
+
+ for(k=0;k<wWindow[DATA_WINDOW].cy;k++) // 4 lines
+ {
+ PICE_sprintf(tempCmd,"%.4X:%.8X: ",segment,addrorg+k*16);
+ Print(1,tempCmd);
+ for(i=0;i<4;i++) // 4 dwords
+ {
+ tempCmd[0]=0;
+ Print(1," ");
+ for(j=0;j<4;j++) // 1 dword = 4 bytes
+ {
+ if(IsAddressValid(addr+i*4+j+k*16))
+ {
+ PICE_sprintf(temp,"%.2x",*(PUCHAR)(addr+i*4+j+k*16));
+ PICE_strrev(temp);
+ PICE_strcat(tempCmd,temp);
+ }
+ else
+ {
+ PICE_strcat(tempCmd,"??");
+ }
+ }
+ PICE_strrev(tempCmd);
+ Print(1,tempCmd);
+ }
+ Print(1," ");
+ tempCmd[0]=0;
+ for(j=0;j<16;j++) // 1 dword = 4 bytes
+ {
+ wWindow[DATA_WINDOW].usCurX = GLOBAL_SCREEN_WIDTH-17;
+ if(IsAddressValid(addr+j+k*16))
+ {
+ PICE_sprintf(temp,"%c",PICE_isprint(*(PUCHAR)(addr+j+k*16))?(*(PUCHAR)(addr+j+k*16)):'.');
+ PICE_strcat(tempCmd,temp);
+ }
+ else
+ {
+ PICE_strcat(tempCmd,"?");
+ }
+ }
+ Print(1,tempCmd);
+ Print(1,"\n");
+ }
+ EnableScroll(DATA_WINDOW);
+ addr+=16*4;
+ return TRUE;
+}
+
+//*************************************************************************
+// DisplayMemoryByte()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(DisplayMemoryByte)
+{
+ ULONG j,k;
+ static ULONG addr=0,addrorg;
+ static USHORT segment;
+ char temp[8];
+ LPSTR pSymbolName;
+
+ if(pArgs->Count==2)
+ {
+ segment=(USHORT)pArgs->Value[0];
+ if(!segment)segment=GLOBAL_DATA_SEGMENT;
+ addr=pArgs->Value[1];
+ OldSelector = segment;
+ OldOffset = addr;
+ addrorg=addr;
+ addr=GetLinearAddress(segment,addr);
+ }
+ else if(pArgs->Count==1)
+ {
+ segment=CurrentDS;
+ addr=pArgs->Value[0];
+ OldOffset = addr;
+ addrorg=addr;
+ addr=GetLinearAddress(segment,addr);
+ }
+ else if(pArgs->Count==0)
+ {
+ addr += sizeof(ULONG)*4*4;
+ OldOffset = addr;
+ }
+
+ if(DisplayMemory != DisplayMemoryByte)
+ {
+ Clear(DATA_WINDOW);
+ DisplayMemory = DisplayMemoryByte;
+ }
+ else
+ Home(DATA_WINDOW);
+
+ if(ScanExportsByAddress(&pSymbolName,addr))
+ {
+ PICE_sprintf(tempCmd," %s ",pSymbolName);
+ SetForegroundColor(COLOR_TEXT);
+ SetBackgroundColor(COLOR_CAPTION);
+ PutChar(tempCmd,GLOBAL_SCREEN_WIDTH-1-PICE_strlen(tempCmd),wWindow[DATA_WINDOW].y-1);
+ ResetColor();
+ }
+
+ DisableScroll(DATA_WINDOW);
+ for(k=0;k<wWindow[DATA_WINDOW].cy;k++) // 4 lines
+ {
+ PICE_sprintf(tempCmd,"%.4X:%.8X: ",segment,addrorg+k*16);
+ Print(1,tempCmd);
+ tempCmd[0]=0;
+ Print(1," ");
+ for(j=0;j<16;j++) // 1 dword = 4 bytes
+ {
+ if(IsAddressValid(addr+j+k*16))
+ {
+ PICE_sprintf(temp,"%.2x ",*(PUCHAR)(addr+j+k*16));
+ PICE_strcat(tempCmd,temp);
+ }
+ else
+ {
+ PICE_strcat(tempCmd,"?? ");
+ }
+ }
+ Print(1,tempCmd);
+ Print(1," ");
+ tempCmd[0]=0;
+ for(j=0;j<16;j++) // 1 dword = 4 bytes
+ {
+ wWindow[DATA_WINDOW].usCurX = GLOBAL_SCREEN_WIDTH-17;
+ if(IsAddressValid(addr+j+k*16))
+ {
+ PICE_sprintf(temp,"%c",PICE_isprint(*(PUCHAR)(addr+j+k*16))?(*(PUCHAR)(addr+j+k*16)):'.');
+ PICE_strcat(tempCmd,temp);
+ }
+ else
+ {
+ PICE_strcat(tempCmd,"?");
+ }
+ }
+ Print(1,tempCmd);
+ Print(1,"\n");
+ }
+ EnableScroll(DATA_WINDOW);
+ addr+=16*4;
+ return TRUE;
+}
+
+//*************************************************************************
+// DisplayPhysMemDword()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(DisplayPhysMemDword)
+{
+ ULONG i,j,k;
+ static ULONG addr=0,addrorg;
+ static USHORT segment;
+ char temp[8];
+
+ ENTER_FUNC();
+ DPRINT((0,"DisplayPhysMemDword()\n"));
+
+ if(pArgs->Count==1)
+ {
+ segment=CurrentDS;
+ addr=pArgs->Value[0];
+ OldOffset = addr;
+ addrorg=addr;
+ addr=GetLinearAddress(segment,addr);
+ }
+ else if(pArgs->Count==0)
+ {
+ addr += sizeof(ULONG)*4*4;
+ OldOffset = addr;
+ }
+
+ DisableScroll(DATA_WINDOW);
+
+ if(DisplayMemory != DisplayPhysMemDword)
+ {
+ Clear(DATA_WINDOW);
+ DisplayMemory = DisplayPhysMemDword;
+ }
+ else
+ Home(DATA_WINDOW);
+
+ for(k=0;k<wWindow[DATA_WINDOW].cy;k++) // 4 lines
+ {
+ PICE_sprintf(tempCmd,"PHYS:%.8X: ",addrorg+k*16);
+ Print(1,tempCmd);
+ for(i=0;i<4;i++) // 4 dwords
+ {
+ tempCmd[0]=0;
+ PICE_sprintf(tempCmd," %.8X",ReadPhysMem(addr+i*4+k*16,sizeof(ULONG)));
+ Print(1,tempCmd);
+ }
+ Print(1," ");
+ tempCmd[0]=0;
+ for(j=0;j<16;j++) // 1 dword = 4 bytes
+ {
+ UCHAR ucData;
+ wWindow[DATA_WINDOW].usCurX = GLOBAL_SCREEN_WIDTH-17;
+ ucData = ReadPhysMem(addr+j+k*16,sizeof(UCHAR));
+ PICE_sprintf(temp,"%c",PICE_isprint(ucData)?ucData:'.');
+ PICE_strcat(tempCmd,temp);
+ }
+ Print(1,tempCmd);
+ Print(1,"\n");
+ }
+ EnableScroll(DATA_WINDOW);
+ addr+=16*4;
+ return TRUE;
+}
+
+
+//*************************************************************************
+// DisplaySourceFile()
+//
+//*************************************************************************
+void DisplaySourceFile(LPSTR pSrcLine,LPSTR pSrcEnd,ULONG ulLineNumber,ULONG ulLineNumberToInvert)
+{
+ ULONG i;
+ LPSTR pTemp;
+ ULONG j = ulLineNumber-1;
+
+ DPRINT((0,"DisplaySourceFile(%.8X,%u,%u)\n",pSrcLine,ulLineNumber,ulLineNumberToInvert));
+
+ // go to line
+ while(j--)
+ {
+ // goto end of current line
+ while(*pSrcLine!=0x0a && *pSrcLine!=0x0d)
+ pSrcLine++;
+
+ // skip over the line end
+ if(*pSrcLine == 0x0d)
+ pSrcLine++;
+ if(*pSrcLine == 0x0a)
+ pSrcLine++;
+ }
+
+ Clear(SOURCE_WINDOW);
+ DisableScroll(SOURCE_WINDOW);
+ for(i=0;i<wWindow[SOURCE_WINDOW].cy;i++)
+ {
+ pTemp = tempCmd;
+
+ if(pSrcLine<pSrcEnd)
+ {
+ PICE_sprintf(tempCmd,".%.5u ",ulLineNumber+i);
+ pTemp = tempCmd + PICE_strlen(tempCmd);
+
+ while(pSrcLine<pSrcEnd && *pSrcLine!=0x0a && *pSrcLine!=0x0d)
+ {
+ if(*pSrcLine==0x9) // TAB
+ {
+ *pTemp++ = 0x20;
+ *pTemp++ = 0x20;
+ *pTemp++ = 0x20;
+ *pTemp++ = 0x20;
+ pSrcLine++;
+ }
+ else
+ {
+ *pTemp++ = *pSrcLine++;
+ }
+ }
+
+ if(pSrcLine<pSrcEnd)
+ {
+ // skip over the line end
+ if(*pSrcLine == 0x0d)
+ pSrcLine++;
+ if(*pSrcLine == 0x0a)
+ pSrcLine++;
+ }
+
+ *pTemp++ = '\n';
+ *pTemp = 0;
+
+ if(PICE_strlen(tempCmd)>GLOBAL_SCREEN_WIDTH-1)
+ {
+ tempCmd[GLOBAL_SCREEN_WIDTH-2]='\n';
+ tempCmd[GLOBAL_SCREEN_WIDTH-1]=0;
+ }
+
+ if( (ulLineNumberToInvert!=-1) &&
+ ((int)(ulLineNumberToInvert-ulLineNumber)>=0) &&
+ ((ulLineNumberToInvert-ulLineNumber)<wWindow[SOURCE_WINDOW].cy) &&
+ (i==(ulLineNumberToInvert-ulLineNumber)) )
+ {
+ SetForegroundColor(COLOR_BACKGROUND);
+ SetBackgroundColor(COLOR_FOREGROUND);
+ }
+
+ Print(SOURCE_WINDOW,tempCmd);
+
+ if( (ulLineNumberToInvert!=-1) &&
+ ((int)(ulLineNumberToInvert-ulLineNumber)>=0) &&
+ ((ulLineNumberToInvert-ulLineNumber)<wWindow[SOURCE_WINDOW].cy) &&
+ (i==(ulLineNumberToInvert-ulLineNumber)) )
+ {
+ ResetColor();
+ }
+
+ }
+ else
+ {
+ Print(SOURCE_WINDOW,"---- End of source file --------------\n");
+ break;
+ }
+ }
+ EnableScroll(SOURCE_WINDOW);
+}
+
+//*************************************************************************
+// UnassembleOneLineDown()
+//
+//*************************************************************************
+void UnassembleOneLineDown(void)
+{
+ ULONG addr,addrorg;
+
+ DPRINT((0,"UnassembleOneLineDown()\n"));
+
+ addrorg = addr = GetLinearAddress(usOldDisasmSegment,ulOldDisasmOffset);
+
+ DPRINT((0,"UnassembleOneLineDown(): addr = %.8X\n",addr));
+
+ tempCmd[0]=0;
+ Disasm(&addr,tempCmd);
+
+ DPRINT((0,"UnassembleOneLineDown(): addr after = %.8X\n",addr));
+
+ ulOldDisasmOffset += (addr - addrorg);
+ RepaintSource();
+}
+
+//*************************************************************************
+// UnassembleOnePageDown()
+//
+//*************************************************************************
+void UnassembleOnePageDown(ULONG page)
+{
+ ULONG addr,addrorg,i;
+
+ DPRINT((0,"UnassembleOnePageDown()\n"));
+
+ addrorg = addr = GetLinearAddress(usOldDisasmSegment,ulOldDisasmOffset);
+
+ DPRINT((0,"UnassembleOnePageDown(): addr = %.8X\n",addr));
+
+ tempCmd[0]=0;
+ for(i=0;i<page;i++)
+ Disasm(&addr,tempCmd);
+
+ DPRINT((0,"UnassembleOnePageDown(): addr after = %.8X\n",addr));
+
+ ulOldDisasmOffset += (addr - addrorg);
+ RepaintSource();
+}
+
+//*************************************************************************
+// UnassembleOneLineUp()
+//
+//*************************************************************************
+void UnassembleOneLineUp(void)
+{
+ ULONG addr,addrorg,addrbefore,start,end,addrstart;
+ LONG offset;
+ LPSTR pSymbol;
+
+ DPRINT((0,"UnassembleOneLineUp()\n"));
+
+ addrorg = addr = GetLinearAddress(usOldDisasmSegment,ulOldDisasmOffset);
+
+ DPRINT((0,"UnassembleOneLineUp(): addrorg = %.8X\n",addr));
+
+ offset = 1;
+
+ if((pSymbol = FindFunctionByAddress(addrorg-offset,&start,&end)) )
+ {
+ offset = addrorg - start;
+ DPRINT((0,"UnassembleOneLineUp(): %s @ offset = %u\n",pSymbol,offset));
+ }
+ else
+ {
+ // max instruction length is 15 bytes
+ offset = 15;
+ }
+
+ addrstart = addrorg;
+
+ // start at current address less offset
+ addr = addrorg - offset;
+ do
+ {
+ DPRINT((0,"UnassembleOneLineUp(): offset = %u addrorg %x addr %x\n",offset,addrorg,addr));
+ // disassemble while not reaching current instruction
+ addrbefore = addr;
+ tempCmd[0]=0;
+ Disasm(&addr,tempCmd);
+ DPRINT((0,"%.8X: %s\n",addrbefore,tempCmd));
+ }while((addr != addrorg) && (addrbefore < addrorg));
+
+ if((addrorg - addrstart)<=0)
+ ulOldDisasmOffset--;
+ else
+ ulOldDisasmOffset -= (addrorg - addrbefore);
+
+ DPRINT((0,"UnassembleOneLineUp(): new addr = %.4X:%.8X\n",usOldDisasmSegment,ulOldDisasmOffset));
+
+ RepaintSource();
+}
+
+//*************************************************************************
+// UnassembleOneLineUp()
+//
+//*************************************************************************
+void UnassembleOnePageUp(ULONG page)
+{
+ ULONG addr,addrorg,addrbefore,start,end,i,addrstart;
+ LONG offset;
+ LPSTR pSymbol;
+
+ DPRINT((0,"UnassembleOnePageUp()\n"));
+
+ for(i=0;i<page;i++)
+ {
+ addrorg = addr = GetLinearAddress(usOldDisasmSegment,ulOldDisasmOffset);
+
+ DPRINT((0,"UnassembleOnePageUp(): addrorg = %.8X\n",addr));
+
+ offset = 1;
+
+ if((pSymbol = FindFunctionByAddress(addrorg-offset,&start,&end)) )
+ {
+ offset = addrorg - start;
+ DPRINT((0,"UnassembleOnePageUp(): %s @ offset = %u\n",pSymbol,offset));
+ }
+ else
+ {
+ // max instruction length is 15 bytes
+ offset = 15;
+ }
+
+ // start at current address less offset
+ addr = addrorg - offset;
+ addrstart = addrorg;
+ do
+ {
+ DPRINT((0,"UnassembleOnePageUp(): offset = %u addrorg %x addr %x\n",offset,addrorg,addr));
+ addrbefore = addr;
+ // disassemble while not reaching current instruction
+ tempCmd[0]=0;
+ Disasm(&addr,tempCmd);
+ DPRINT((0,"%.8X: %s\n",addrbefore,tempCmd));
+ }while((addr != addrorg) && (addrbefore < addrorg));
+
+ if((addrorg - addrstart)<=0)
+ ulOldDisasmOffset--;
+ else
+ ulOldDisasmOffset -= (addrorg - addrbefore);
+
+ }
+
+ DPRINT((0,"UnassembleOnePageUp(): new addr = %.4X:%.8X\n",usOldDisasmSegment,ulOldDisasmOffset));
+
+ RepaintSource();
+}
+
+//*************************************************************************
+// Unassemble()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(Unassemble)
+{
+ ULONG i;
+ ULONG addr=0,addrorg,addrstart,ulLineNumber;
+ USHORT segment=0;
+ ULONG addrbefore;
+ LPSTR pSymbolName;
+ BOOLEAN bSWBpAtAddr;
+ LPSTR pSrc,pFilename,pSrcStart,pSrcEnd;
+ BOOLEAN bForceDisassembly = FALSE;
+
+ DPRINT((0,"Unassemble: CountSwitches: %u, count: %u\n", pArgs->CountSwitches, pArgs->Count));
+ if(pArgs->CountSwitches>1)
+ return TRUE;
+
+ if(pArgs->CountSwitches==1)
+ {
+ if(pArgs->Switch[0] == 'f')
+ bForceDisassembly = TRUE;
+ }
+
+ // we have args
+ if(pArgs->Count==2)
+ {
+ addr=pArgs->Value[1];
+ segment=(USHORT)pArgs->Value[0];
+ addrorg=addrstart=addr;
+ addr=GetLinearAddress(segment,addr);
+
+ usOldDisasmSegment = segment;
+ ulOldDisasmOffset = addr;
+ }
+ else if(pArgs->Count==1)
+ {
+ addr=pArgs->Value[0];
+ segment=CurrentCS;
+ addrorg=addrstart=addr;
+ addr=GetLinearAddress(segment,addr);
+
+ usOldDisasmSegment = segment;
+ ulOldDisasmOffset = addr;
+ }
+ else if(pArgs->Count==0)
+ {
+ segment = usOldDisasmSegment;
+ addrorg=addrstart=addr;
+ addr = GetLinearAddress(usOldDisasmSegment,ulOldDisasmOffset);
+ }
+ else
+ return TRUE;
+
+
+ DPRINT((0,"Unassemble(%0.4X:%0.8X), lastst: %x, lastend:%x\n",segment,addr,ulLastDisassStartAddress,ulLastDisassEndAddress));
+
+ //
+ // unassemble
+ //
+ DisableScroll(SOURCE_WINDOW);
+
+ // if we're inside last disassembly range we only need to move to highlight
+ if(ulLastDisassStartAddress && ulLastDisassEndAddress && addr>=ulLastDisassStartAddress &&
+ addr<ulLastDisassEndAddress )
+ {
+ addr=ulLastDisassStartAddress;
+ }
+ else
+ {
+ ulLastDisassStartAddress=ulLastDisassEndAddress=0;
+ }
+
+ SetForegroundColor(COLOR_TEXT);
+ SetBackgroundColor(COLOR_CAPTION);
+
+ ClrLine(wWindow[SOURCE_WINDOW].y-1);
+
+ ResetColor();
+
+ if(ScanExportsByAddress(&pSymbolName,addr))
+ {
+ SetForegroundColor(COLOR_TEXT);
+ SetBackgroundColor(COLOR_CAPTION);
+ PICE_sprintf(tempCmd," %s ",pSymbolName);
+ PutChar(tempCmd,GLOBAL_SCREEN_WIDTH-1-PICE_strlen(tempCmd),wWindow[SOURCE_WINDOW].y-1);
+ ResetColor();
+ }
+
+ pCurrentMod = FindModuleFromAddress(addr);
+ if(pCurrentMod)
+ {
+ ULONG mod_addr;
+ DPRINT((0,"Unassemble(): pCurrentMod->name = %S\n",pCurrentMod->name));
+ mod_addr = (ULONG)pCurrentMod->BaseAddress;
+
+ pCurrentSymbols = FindModuleSymbols(mod_addr);
+ DPRINT((0,"Unassemble(): pCurrentSymbols = %x\n",(ULONG)pCurrentSymbols));
+ }
+ DPRINT((0,"Unassemble(): pCurrentMod = %x, showsrc: %d\n",pCurrentMod, bShowSrc));
+
+ ulCurrentlyDisplayedLineNumber = 0;
+
+ if(bShowSrc && bForceDisassembly == FALSE && (pSrc = FindSourceLineForAddress(addr,&ulLineNumber,&pSrcStart,&pSrcEnd,&pFilename)) )
+ {
+ DPRINT((0,"FoundSourceLineForAddress: file: %s line: %d\n", pFilename, ulLineNumber));
+ PICE_strcpy(szCurrentFile,pFilename);
+
+ ulCurrentlyDisplayedLineNumber = ulLineNumber;
+
+ Clear(SOURCE_WINDOW);
+
+ // display file name
+ SetForegroundColor(COLOR_TEXT);
+ SetBackgroundColor(COLOR_CAPTION);
+
+ if(PICE_strlen(pFilename)<GLOBAL_SCREEN_WIDTH/2)
+ {
+ PutChar(pFilename,1,wWindow[SOURCE_WINDOW].y-1);
+ }
+ else
+ {
+ LPSTR p;
+
+ p = strrchr(pFilename,'/');
+ if(!p)
+ {
+ p = pFilename;
+ }
+ else
+ {
+ p++;
+ }
+
+ PutChar(p,1,wWindow[SOURCE_WINDOW].y-1);
+ }
+
+ ResetColor();
+
+ // display the source
+ if(ulLineNumber>(wWindow[SOURCE_WINDOW].cy/2) )
+ {
+ DisplaySourceFile(pSrcStart,pSrcEnd,ulLineNumber-(wWindow[SOURCE_WINDOW].cy/2),ulLineNumber);
+ }
+ else
+ {
+ DisplaySourceFile(pSrcStart,pSrcEnd,ulLineNumber,ulLineNumber);
+ }
+ }
+ else
+ {
+ *szCurrentFile = 0;
+ DPRINT((0,"Couldn't find source for file\n"));
+ Home(SOURCE_WINDOW);
+ // for each line in the disassembly window
+ for(i=0;i<wWindow[SOURCE_WINDOW].cy;i++)
+ {
+ extern ULONG ulWindowOffset;
+
+ bSWBpAtAddr = FALSE;
+ // if there is a potential SW breakpoint at address
+ // we might have to put back the original opcode
+ // in order to disassemble correctly.
+ if(IsSwBpAtAddress(addr))
+ {
+ // if INT3 is there, remove it while disassembling
+ if((bSWBpAtAddr = IsSwBpAtAddressInstalled(addr)))
+ {
+ DeInstallSWBreakpoint(addr);
+ }
+ }
+
+ ClrLine(wWindow[SOURCE_WINDOW].y+i);
+
+ // invert the line that we're about to execute
+ if(addr==CurrentEIP)
+ {
+ SetForegroundColor(COLOR_BACKGROUND);
+ SetBackgroundColor(COLOR_FOREGROUND);
+ ulLastInvertedAddress = CurrentEIP;
+ }
+
+ // output segment:offset address
+ PICE_sprintf(tempCmd,"%0.4X:%0.8X ",segment,addr);
+ Print(SOURCE_WINDOW,tempCmd);
+
+ // disassemble a line
+ addrbefore=addr;
+ if(bCodeOn)
+ {
+ tempCmd[30]=0;
+ Disasm(&addr,&tempCmd[30]);
+ }
+ else
+ {
+ tempCmd[0]=0;
+ Disasm(&addr,tempCmd);
+ }
+ addrorg+=(addr-addrbefore);
+
+ // want to display opcode bytes
+ if(bCodeOn)
+ {
+ ULONG j;
+
+ for(j=0;j<15;j++)
+ {
+ if(j<addr-addrbefore)
+ {
+ if(IsAddressValid(addrbefore+j))
+ {
+ tempCmd[j*2]=HexDigit[((*(PUCHAR)(addrbefore+j)&0xF0)>>4)];
+ tempCmd[j*2+1]=HexDigit[((*(PUCHAR)(addrbefore+j)&0xF))];
+ }
+ else
+ {
+ tempCmd[j*2]='?';
+ tempCmd[j*2+1]='?';
+ }
+ }
+ else
+ {
+ tempCmd[j*2]=' ';
+ tempCmd[j*2+1]=' ';
+ }
+ }
+ }
+ PICE_strcat(tempCmd,"\n");
+
+ if(ulWindowOffset)
+ {
+ LONG len = PICE_strlen(tempCmd);
+ if(ulWindowOffset < len)
+ PICE_memcpy(tempCmd,&tempCmd[ulWindowOffset],len-ulWindowOffset);
+ else
+ tempCmd[0]='\n';
+ }
+
+ Print(SOURCE_WINDOW,tempCmd);
+
+ if(addrbefore==CurrentEIP)
+ {
+ ResetColor();
+ }
+
+ // if potential SW breakpoint, undo marked text
+ if(IsSwBpAtAddress(addrbefore))
+ {
+ HatchLine(wWindow[SOURCE_WINDOW].y+i);
+ }
+
+ // if breakpoint was installed before disassembly, put it back
+ if(bSWBpAtAddr)
+ {
+ ReInstallSWBreakpoint(addrbefore);
+ }
+
+ }
+
+ if(ulLastDisassStartAddress==0 && ulLastDisassEndAddress==0)
+ {
+ ulLastDisassStartAddress=addrstart;
+ ulLastDisassEndAddress=addr;
+ }
+
+ if(!IsAddressValid(addrstart))
+ {
+ ulLastDisassStartAddress=0;
+ ulLastDisassEndAddress=0;
+ }
+
+ }
+
+ EnableScroll(SOURCE_WINDOW);
+
+ return TRUE;
+}
+
+//*************************************************************************
+// ShowModules()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowModules)
+{
+ PDEBUG_MODULE pMod;
+ DPRINT((0,"ShowModules()\n"));
+
+ if(BuildModuleList())
+ {
+ pMod = pdebug_module_head;
+ do
+ {
+ if(pMod->size)
+ {
+ if(pMod == pCurrentMod)
+ {
+ PICE_sprintf(tempCmd,"%.8X - %.8X *%-32S\n",
+ (unsigned int)pMod->BaseAddress,
+ (unsigned int) ((unsigned int)pMod->BaseAddress+pMod->size),pMod->name);
+ }
+ else
+ {
+ PICE_sprintf(tempCmd,"%.8X - %.8X %-32S\n",
+ (unsigned int)pMod->BaseAddress,
+ (unsigned int) ((unsigned int)pMod->BaseAddress+pMod->size),
+ pMod->name);
+ }
+ }
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)
+ break;
+ }while((pMod = pMod->next)!=pdebug_module_tail);
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// DecodeVmFlags()
+//
+//*************************************************************************
+//ei FIX THIS!!!!!!!!!!!!!!!!!!
+LPSTR DecodeVmFlags(ULONG flags)
+{
+ ULONG i;
+/*
+#define VM_READ 0x0001
+#define VM_WRITE 0x0002
+#define VM_EXEC 0x0004
+#define VM_SHARED 0x0008
+
+#define VM_MAYREAD 0x0010
+#define VM_MAYWRITE 0x0020
+#define VM_MAYEXEC 0x0040
+#define VM_MAYSHARE 0x0080
+
+#define VM_GROWSDOWN 0x0100
+#define VM_GROWSUP 0x0200
+#define VM_SHM 0x0400
+#define VM_DENYWRITE 0x0800
+
+#define VM_EXECUTABLE 0x1000
+#define VM_LOCKED 0x2000
+#define VM_IO 0x4000
+
+#define VM_STACK_FLAGS 0x0177
+*/
+ static LPSTR flags_syms_on[]={"R","W","X","S","MR","MW","MX","MS","GD","GU","SHM","exe","LOCK","IO",""};
+ static char temp[256];
+
+ // terminate string
+ *temp = 0;
+//ei fix fix fix
+#if 0
+
+ if(flags == VM_STACK_FLAGS)
+ {
+ PICE_strcpy(temp," (STACK)");
+ }
+ else
+ {
+ for(i=0;i<15;i++)
+ {
+ if(flags&0x1)
+ {
+ PICE_strcat(temp," ");
+ PICE_strcat(temp,flags_syms_on[i]);
+ }
+ flags >>= 1;
+ }
+ }
+#endif
+ return temp;
+}
+
+//*************************************************************************
+// ShowVirtualMemory()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowVirtualMemory)
+{
+ PEPROCESS my_current = IoGetCurrentProcess();
+ PLIST_ENTRY current_entry;
+ PMADDRESS_SPACE vma = NULL;
+ MEMORY_AREA* current;
+ char filename[64];
+
+ DPRINT((0,"ShowVirtualMemory()\n"));
+ if( my_current )
+ vma = &(my_current->AddressSpace);
+ if( !vma )
+ vma = my_init_mm;
+ while( vma )
+ {
+ if(pArgs->Count == 0)
+ {
+ PutStatusText("START END LENGTH VMA TYPE ATTR");
+ current_entry = vma->MAreaListHead.Flink;
+ while (current_entry != &vma->MAreaListHead)
+ {
+ *filename = 0;
+
+ current = CONTAINING_RECORD(current_entry,
+ MEMORY_AREA,
+ Entry);
+ // find the filename
+ if(((current->Type == MEMORY_AREA_SECTION_VIEW) ) &&
+ current->Data.SectionData.Section->FileObject)
+ {
+ if(IsAddressValid((ULONG)current->Data.SectionData.Section->FileObject->FileName.Buffer) )
+ PICE_sprintf(filename,"%.64S",current->Data.SectionData.Section->FileObject->FileName.Buffer);
+ }
+
+ PICE_sprintf(tempCmd,"%.8X %.8X %.8X %.8X %x %x %s\n",
+ (ULONG)current->BaseAddress,
+ (ULONG)current->BaseAddress+current->Length,
+ current->Length,
+ (ULONG)current,
+ current->Type, current->Attributes,//DecodeVmFlags(current->Type, current->Attributes),
+ filename);
+ Print(OUTPUT_WINDOW,tempCmd);
+
+ if(WaitForKey()==FALSE)
+ break;
+ current_entry = current_entry->Flink;
+ }
+ }
+ if( vma == &(my_current->AddressSpace) )
+ vma = my_init_mm; // switch to kernel memory area
+ else vma = 0; // if we already did kernel, end loop
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// Ver()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(Ver)
+{
+ //ei add kernel version info??!!
+ PICE_sprintf(tempCmd,"pICE: version %u.%u (build %u) for Reactos\n",
+ PICE_MAJOR_VERSION,
+ PICE_MINOR_VERSION,
+ PICE_BUILD);
+
+ Print(OUTPUT_WINDOW,tempCmd);
+
+/* PICE_sprintf(tempCmd,"pICE: loaded on %s kernel release %s\n",
+ system_utsname.sysname,
+ system_utsname.release);
+ */
+ Print(OUTPUT_WINDOW,tempCmd);
+ Print(OUTPUT_WINDOW,"pICE: written by Klaus P. Gerlicher and Goran Devic.\n");
+ Print(OUTPUT_WINDOW,"pICE: ported to Reactos by Eugene Ingerman.\n");
+
+ return TRUE;
+}
+
+//*************************************************************************
+// Hboot()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(Hboot)
+{
+ // nudge the reset line through keyboard controller
+ __asm__("\n\t \
+ movb $0xFE,%al\n\t \
+ outb %al,$0x64");
+ // never gets here
+ return TRUE;
+}
+
+//*************************************************************************
+// SetSrcDisplay()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(SetSrcDisplay)
+{
+ ARGS Args;
+
+ if(pArgs->Count==0)
+ {
+ bShowSrc=bShowSrc?FALSE:TRUE;
+ PICE_memset(&Args,0,sizeof(ARGS));
+ // make unassembler refresh all again
+ ulLastDisassStartAddress=ulLastDisassEndAddress=0;
+ Args.Count=0;
+ Unassemble(&Args);
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// I3here()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(I3here)
+{
+ if(pArgs->Count==1)
+ {
+ if(pArgs->Value[0]==1)
+ {
+ if(!bInt3Here)
+ {
+ bInt3Here=TRUE;
+ Print(OUTPUT_WINDOW,"I3HERE is now ON\n");
+ }
+ else
+ Print(OUTPUT_WINDOW,"I3HERE is already ON\n");
+ }
+ else if(pArgs->Value[0]==0)
+ {
+ if(bInt3Here)
+ {
+ bInt3Here=FALSE;
+ Print(OUTPUT_WINDOW,"I3HERE is now OFF\n");
+ }
+ else
+ Print(OUTPUT_WINDOW,"I3HERE is already OFF\n");
+ }
+ }
+ else if(pArgs->Count==0)
+ {
+ if(bInt3Here)
+ {
+ Print(OUTPUT_WINDOW,"I3HERE is ON\n");
+ }
+ else
+ {
+ Print(OUTPUT_WINDOW,"I3HERE is OFF\n");
+ }
+ }
+ // never gets here
+ return TRUE;
+}
+
+COMMAND_PROTOTYPE(I1here)
+{
+ if(pArgs->Count==1)
+ {
+ if(pArgs->Value[0]==1)
+ {
+ if(!bInt1Here)
+ {
+ bInt1Here=TRUE;
+ Print(OUTPUT_WINDOW,"I1HERE is now ON\n");
+ }
+ else
+ Print(OUTPUT_WINDOW,"I1HERE is already ON\n");
+ }
+ else if(pArgs->Value[0]==0)
+ {
+ if(bInt1Here)
+ {
+ bInt1Here=FALSE;
+ Print(OUTPUT_WINDOW,"I1HERE is now OFF\n");
+ }
+ else
+ Print(OUTPUT_WINDOW,"I1HERE is already OFF\n");
+ }
+ }
+ else if(pArgs->Count==0)
+ {
+ if(bInt1Here)
+ {
+ Print(OUTPUT_WINDOW,"I1HERE is ON\n");
+ }
+ else
+ {
+ Print(OUTPUT_WINDOW,"I1HERE is OFF\n");
+ }
+ }
+ // never gets here
+ return TRUE;
+}
+
+COMMAND_PROTOTYPE(NextInstr)
+{
+ static char tempDisasm[256];
+ ULONG addr,addrbefore;
+
+ bNeedToFillBuffer=FALSE;
+
+ if(!pArgs->Count)
+ {
+ addr=addrbefore=GetLinearAddress(CurrentCS,CurrentEIP);
+ DPRINT((0,"addr before %.8X\n",addrbefore));
+ Disasm(&addr,tempDisasm);
+ DPRINT((0,"addr after %.8X\n",addr));
+ CurrentEIP=CurrentEIP+(addr-addrbefore);
+ // display register contents
+ DisplayRegs();
+ // unassemble
+ DPRINT((0,"new CS:EIP %04.x:%.8X\n",CurrentCS,CurrentEIP));
+ PICE_memset(pArgs,0,sizeof(ARGS));
+ // make unassembler refresh all again
+ ulLastDisassStartAddress=ulLastDisassEndAddress=0;
+ pArgs->Count=2;
+ pArgs->Value[0]=(ULONG)CurrentCS;
+ pArgs->Value[1]=CurrentEIP;
+ Unassemble(pArgs);
+ }
+ bNeedToFillBuffer=TRUE;
+ return TRUE;
+}
+
+COMMAND_PROTOTYPE(SetGetRegisters)
+{
+ ULONG i;
+
+ if(pArgs->Count==0)
+ {
+ // display whole set
+ for(i=0;RegKeyWords[i].pValue!=0;i++)
+ {
+ switch(RegKeyWords[i].ulSize)
+ {
+ case 1:
+ PICE_sprintf(tempCmd,"%s = %.8X\n",RegKeyWords[i].KeyWord,*(PUCHAR)(RegKeyWords[i].pValue));
+ break;
+ case 2:
+ PICE_sprintf(tempCmd,"%s = %.8X\n",RegKeyWords[i].KeyWord,*(PUSHORT)(RegKeyWords[i].pValue));
+ break;
+ case 4:
+ PICE_sprintf(tempCmd,"%s = %.8X\n",RegKeyWords[i].KeyWord,*(PULONG)(RegKeyWords[i].pValue));
+ break;
+ }
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)break;
+ }
+ }
+ else if(pArgs->Count==1)
+ {
+ // display selected register
+ for(i=0;RegKeyWords[i].pValue!=0;i++)
+ {
+ if(PICE_strcmpi(pArgs->pToken[0],RegKeyWords[i].KeyWord)==0)
+ {
+ switch(RegKeyWords[i].ulSize)
+ {
+ case 1:
+ PICE_sprintf(tempCmd,"%s = %.2X\n",RegKeyWords[i].KeyWord,*(PUCHAR)(RegKeyWords[i].pValue));
+ break;
+ case 2:
+ PICE_sprintf(tempCmd,"%s = %.4X\n",RegKeyWords[i].KeyWord,*(PUSHORT)(RegKeyWords[i].pValue));
+ break;
+ case 4:
+ PICE_sprintf(tempCmd,"%s = %.8X\n",RegKeyWords[i].KeyWord,*(PULONG)(RegKeyWords[i].pValue));
+ break;
+ }
+ Print(OUTPUT_WINDOW,tempCmd);
+ break;
+ }
+ }
+ }
+ else if(pArgs->Count==2)
+ {
+ // set selected register to value
+ for(i=0;RegKeyWords[i].pValue!=0;i++)
+ {
+ if(PICE_strcmpi(pArgs->pToken[0],RegKeyWords[i].KeyWord)==0)
+ {
+ switch(RegKeyWords[i].ulSize)
+ {
+ case 1:
+ *(PUCHAR)(RegKeyWords[i].pValue)=(UCHAR)pArgs->Value[1];
+ break;
+ case 2:
+ *(PUSHORT)(RegKeyWords[i].pValue)=(USHORT)pArgs->Value[1];
+ break;
+ case 4:
+ *(PULONG)(RegKeyWords[i].pValue)=(ULONG)pArgs->Value[1];
+ break;
+ }
+ DisplayRegs();
+ RepaintSource();
+ break;
+ }
+ }
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// SetCodeDisplay()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(SetCodeDisplay)
+{
+ ARGS Args;
+
+ if(pArgs->Count==0)
+ {
+ bCodeOn=bCodeOn?FALSE:TRUE;
+
+ PICE_memset(&Args,0,sizeof(ARGS));
+ Args.Count=0;
+ // make unassembler refresh all again
+ ulLastDisassStartAddress=ulLastDisassEndAddress=0;
+ Unassemble(&Args);
+ }
+ else if(pArgs->Count==1)
+ {
+ bCodeOn=(pArgs->Value[0]==0)?FALSE:TRUE;
+
+ PICE_memset(&Args,0,sizeof(ARGS));
+ Args.Count=0;
+ // make unassembler refresh all again
+ ulLastDisassStartAddress=ulLastDisassEndAddress=0;
+ Unassemble(&Args);
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// ShowCPU()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowCPU)
+{
+ULONG i;
+
+ for(i=0;CPUInfo[i].pValue!=NULL;i++)
+ {
+ PICE_sprintf(tempCmd,"%s = %.8X\n",CPUInfo[i].Name,*(CPUInfo[i].pValue));
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)break;
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// WalkStack()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(WalkStack)
+{
+ if(!pArgs->Count)
+ {
+ IntelStackWalk(CurrentEIP,CurrentEBP,CurrentESP);
+ }
+
+ return TRUE;
+}
+
+//*************************************************************************
+// PokeDword()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(PokeDword)
+{
+ ULONG ulData;
+
+ // read old data
+ ulData = ReadPhysMem(pArgs->Value[1],sizeof(ULONG));
+ PICE_sprintf(tempCmd,"value @ %.8X was %.8X\n",pArgs->Value[1],ulData);
+ Print(OUTPUT_WINDOW,tempCmd);
+
+ // write new data
+ WritePhysMem(pArgs->Value[1],pArgs->Value[2],sizeof(ULONG));
+
+ // read check
+ ulData = ReadPhysMem(pArgs->Value[1],sizeof(ULONG));
+ PICE_sprintf(tempCmd,"value @ %.8X = %.8X\n",pArgs->Value[1],ulData);
+ Print(OUTPUT_WINDOW,tempCmd);
+
+ return TRUE;
+}
+
+//*************************************************************************
+// PokeMemory()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(PokeMemory)
+{
+ DPRINT((0,"PokeMemory()\n"));
+ DPRINT((0,"PokeMemory(): value[0] = %.8X value[1] = %.8X value[3] = %.8X count = %.8X\n",pArgs->Value[0],pArgs->Value[1],pArgs->Value[2],pArgs->Count));
+
+ // must be three parameters
+ if(pArgs->Count == 3)
+ {
+ switch(pArgs->Value[0])
+ {
+ case 4:
+ return PokeDword(pArgs);
+ default:
+ case 1:
+ case 2:
+ break;
+ }
+ }
+ else
+ {
+ Print(OUTPUT_WINDOW,"you need to supply a physical address and datum to write!\n");
+ }
+
+ return TRUE;
+}
+
+
+//*************************************************************************
+// PeekDword()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(PeekDword)
+{
+ ULONG ulData;
+
+ ulData = ReadPhysMem(pArgs->Value[1],sizeof(ULONG));
+ PICE_sprintf(tempCmd,"%.8X\n",ulData);
+ Print(OUTPUT_WINDOW,tempCmd);
+
+ return TRUE;
+}
+
+//*************************************************************************
+// PeekWord()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(PeekWord)
+{
+ USHORT usData;
+
+ usData = (USHORT)ReadPhysMem(pArgs->Value[1],sizeof(USHORT));
+ PICE_sprintf(tempCmd,"%.4X\n",usData);
+ Print(OUTPUT_WINDOW,tempCmd);
+
+ return TRUE;
+}
+
+//*************************************************************************
+// PeekByte()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(PeekByte)
+{
+ UCHAR ucData;
+
+ ucData = (UCHAR)ReadPhysMem(pArgs->Value[1],sizeof(UCHAR));
+ PICE_sprintf(tempCmd,"%.2X\n",ucData);
+ Print(OUTPUT_WINDOW,tempCmd);
+
+ return TRUE;
+}
+
+//*************************************************************************
+// PeekMemory()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(PeekMemory)
+{
+ DPRINT((0,"PeekMemory()\n"));
+ DPRINT((0,"PeekMemory(): value[0] = %.8X value[1] = %.8X count = %.8X\n",pArgs->Value[0],pArgs->Value[1],pArgs->Count));
+
+ if(pArgs->Count == 2)
+ {
+ switch(pArgs->Value[0])
+ {
+ case 1:
+ return PeekByte(pArgs);
+ case 2:
+ return PeekWord(pArgs);
+ case 4:
+ return PeekDword(pArgs);
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+//*************************************************************************
+// UnassembleAtCurrentEip()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(UnassembleAtCurrentEip)
+{
+ PICE_memset(pArgs,0,sizeof(ARGS));
+ pArgs->Count = 2;
+ pArgs->Value[0] = CurrentCS;
+ pArgs->Value[1] = CurrentEIP;
+ Unassemble(pArgs);
+ return TRUE;
+}
+
+//*************************************************************************
+// SwitchTables()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(SwitchTables)
+{
+ ULONG i;
+
+ DPRINT((0,"SwitchTables()\n"));
+
+ // no arguments -> display load symbol tables
+ if(!pArgs->Count)
+ {
+ for(i=0;i<DIM(apSymbols);i++)
+ {
+ if(apSymbols[i])
+ {
+ if(apSymbols[i] == pCurrentSymbols)
+ PICE_sprintf(tempCmd,"*%-32S @ %.8X (%5u source files)\n",apSymbols[i]->name,(ULONG)apSymbols[i],apSymbols[i]->ulNumberOfSrcFiles);
+ else
+ PICE_sprintf(tempCmd," %-32S @ %.8X (%5u source files)\n",apSymbols[i]->name,(ULONG)apSymbols[i],apSymbols[i]->ulNumberOfSrcFiles);
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)break;
+ }
+ }
+ }
+ // 1 argument -> set new current symbols
+ else if(pArgs->Count == 1)
+ {
+ PDEBUG_MODULE pTempMod;
+ char temp[DEBUG_MODULE_NAME_LEN];
+
+ pCurrentSymbols = (PICE_SYMBOLFILE_HEADER*)pArgs->Value[0];
+ CopyWideToAnsi( temp, pCurrentSymbols->name );
+
+ DPRINT((0,"TableSwitchSym: pCurrentSymbols: %x, Name: %s\n", pCurrentSymbols, temp));
+
+ pTempMod = IsModuleLoaded(temp);
+ if( pTempMod )
+ pCurrentMod = pTempMod;
+ }
+
+ return TRUE;
+}
+
+//*************************************************************************
+// SwitchFiles()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(SwitchFiles)
+{
+ PICE_SYMBOLFILE_SOURCE* pSrc;
+ ULONG i;
+ LPSTR p;
+
+ DPRINT((0,"SwitchFiles()\n"));
+ // no arguments -> show files for current symbols
+ if(!pArgs->Count)
+ {
+ if(pCurrentSymbols && pCurrentSymbols->ulNumberOfSrcFiles)
+ {
+ LPSTR pCurrentFile=NULL;
+
+ // find out the current file name
+ if(*szCurrentFile!=0)
+ {
+ if((pCurrentFile = strrchr(szCurrentFile,'/')) )
+ {
+ pCurrentFile++;
+ }
+ else
+ {
+ pCurrentFile = szCurrentFile;
+ }
+ }
+
+ pSrc = (PICE_SYMBOLFILE_SOURCE*)((ULONG)pCurrentSymbols + pCurrentSymbols->ulOffsetToSrcFiles);
+
+ for(i=0;i<pCurrentSymbols->ulNumberOfSrcFiles;i++)
+ {
+ if(pCurrentFile)
+ {
+ if((p = strrchr(pSrc->filename,'/')) )
+ {
+ if(PICE_strcmpi(p+1,pCurrentFile)==0)
+ PICE_sprintf(tempCmd,"*%-32s @ %.8X\n",p+1,(ULONG)pSrc);
+ else
+ PICE_sprintf(tempCmd," %-32s @ %.8X\n",p+1,(ULONG)pSrc);
+ }
+ else
+ {
+ if(PICE_strcmpi(pSrc->filename,pCurrentFile)==0)
+ PICE_sprintf(tempCmd,"*%-32s @ %.8X\n",pSrc->filename,(ULONG)pSrc);
+ else
+ PICE_sprintf(tempCmd," %-32s @ %.8X\n",pSrc->filename,(ULONG)pSrc);
+ }
+ }
+ else
+ {
+ if((p = strrchr(pSrc->filename,'/')) )
+ {
+ PICE_sprintf(tempCmd,"%-32s @ %.8X\n",p+1,(ULONG)pSrc);
+ }
+ else
+ {
+ PICE_sprintf(tempCmd,"%-32s @ %.8X\n",pSrc->filename,(ULONG)pSrc);
+ }
+ }
+ Print(OUTPUT_WINDOW,tempCmd);
+
+ if(WaitForKey()==FALSE)break;
+ (LPSTR)pSrc += pSrc->ulOffsetToNext;
+ }
+ }
+ else
+ Print(OUTPUT_WINDOW,"No source files available!\n");
+ }
+ // 1 argument -> argument is pointer PICE_SYMBOLFILE_SOURCE struct ->
+ // set current file and show it
+ else if(pArgs->Count == 1)
+ {
+ PICE_SYMBOLFILE_SOURCE* pSrc = (PICE_SYMBOLFILE_SOURCE*)pArgs->Value[0];
+ LPSTR pFilename = pSrc->filename;
+
+ ClrLine(wWindow[SOURCE_WINDOW].y-1);
+
+ if(PICE_strlen(pFilename)<GLOBAL_SCREEN_WIDTH/2)
+ {
+ PutChar(pFilename,1,wWindow[SOURCE_WINDOW].y-1);
+ }
+ else
+ {
+ LPSTR p;
+
+ p = strrchr(pFilename,'/');
+ if(!p)
+ {
+ p = pFilename;
+ }
+ else
+ {
+ p++;
+ }
+
+ PutChar(p,1,wWindow[SOURCE_WINDOW].y-1);
+ }
+
+ // set new current file
+ PICE_strcpy(szCurrentFile,pFilename);
+
+ ulCurrentlyDisplayedLineNumber = 1;
+
+ DisplaySourceFile((LPSTR)pSrc+sizeof(PICE_SYMBOLFILE_SOURCE),
+ (LPSTR)pSrc+pSrc->ulOffsetToNext,
+ 1,
+ -1);
+ }
+
+ return TRUE;
+}
+
+//*************************************************************************
+// ShowLocals()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowLocals)
+{
+ PLOCAL_VARIABLE p;
+
+ if(pArgs->Count==0)
+ {
+ p = FindLocalsByAddress(GetLinearAddress(CurrentCS,CurrentEIP));
+ DPRINT((0,"ShowLocals: %x\n", p));
+ if(p)
+ {
+ DPRINT((0,"ShowLocals: name %s, type_name %s\n", p->name, p->type_name));
+ while(PICE_strlen(p->name))
+ {
+ if(!p->bRegister)
+ {
+ PICE_sprintf(tempCmd,"[EBP%.4d / #%u] %x %s %s \n",p->offset,p->line,p->value,p->type_name,p->name);
+ }
+ else
+ {
+ PICE_sprintf(tempCmd,"[%-8s / #%u] %x %s %s #%u\n",LocalVarRegs[p->offset],p->line,p->value,p->type_name,p->name);
+ }
+ Print(OUTPUT_WINDOW,tempCmd);
+ p++;
+ }
+ }
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// ShowSymbols()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowSymbols)
+{
+ PICE_SYMBOLFILE_HEADER* pSymbols;
+ ULONG index,addr;
+ LPSTR pSearchString,pName,pFind;
+
+ // no args -> list full symbols for current module
+ if(!pArgs->Count)
+ {
+ // have current module ?
+ if(pCurrentMod)
+ {
+ DPRINT((0,"ShowSymbols(): full listing of symbols for %S\n",pCurrentMod->name));
+ addr = (ULONG)pCurrentMod->BaseAddress;
+
+ if((pSymbols = FindModuleSymbols(addr)) )
+ {
+ PICE_sprintf(tempCmd,"symbols for module \"%S\"\n",pCurrentMod->name);
+ Print(OUTPUT_WINDOW,tempCmd);
+
+ index = 0;
+ while((index = ListSymbolStartingAt(pCurrentMod,pSymbols,index,tempCmd)))
+ {
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)break;
+ }
+ }
+ }
+ }
+ // partial name
+ else if(pArgs->Count == 1)
+ {
+ if(pCurrentMod)
+ {
+ addr = (ULONG)pCurrentMod->BaseAddress;
+
+ if((pSymbols = FindModuleSymbols(addr)))
+ {
+ pSearchString = (LPSTR)pArgs->Value[0];
+
+ PICE_sprintf(tempCmd,"symbols for module \"%S\" (searching for \"%s\")\n",pCurrentMod->name,pSearchString);
+ Print(OUTPUT_WINDOW,tempCmd);
+
+ if(pSearchString)
+ {
+ if(*pSearchString=='*' && pSearchString[PICE_strlen(pSearchString)-1]=='*')
+ {
+ pSearchString[PICE_strlen(pSearchString)-1] = 0;
+ pSearchString++;
+ index = 0;
+ while((index = ListSymbolStartingAt(pCurrentMod,pSymbols,index,tempCmd)))
+ {
+ pName = strrchr(tempCmd,' ');
+ pName++;
+ pFind = strstr(pName,pSearchString);
+ if(pFind)
+ {
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)break;
+ }
+ }
+ // TODO
+ }
+ else if(pSearchString[PICE_strlen(pSearchString)-1]=='*')
+ {
+ pSearchString[PICE_strlen(pSearchString)-1] = 0;
+ index = 0;
+
+ index = ListSymbolStartingAt(pCurrentMod,pSymbols,index,tempCmd);
+ if(index)
+ {
+ do
+ {
+ pName = strrchr(tempCmd,' ');
+ pName++;
+ pFind = strstr(pName,pSearchString);
+ if(pFind && (((ULONG)pName-(ULONG)pFind)==0) )
+ {
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)break;
+ }
+ }while((index = ListSymbolStartingAt(pCurrentMod,pSymbols,index,tempCmd)));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+//*************************************************************************
+// EvaluateExpression()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(EvaluateExpression)
+{
+ PICE_SYMBOLFILE_HEADER* pSymbols;
+ ULONG addr;
+
+ if(pArgs->Count == 1)
+ {
+ if(pCurrentMod)
+ {
+ addr = (ULONG)pCurrentMod->BaseAddress;
+
+ if( (pSymbols = FindModuleSymbols(addr) ) )
+ {
+ DPRINT((0,"EvaluateExpression: %s\n", (LPSTR)pArgs->Value[0]));
+ Evaluate(pSymbols,(LPSTR)pArgs->Value[0]);
+ }
+ }
+ }
+ return TRUE;
+}
+
+//*************************************************************************
+// SizeCodeWindow()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(SizeCodeWindow)
+{
+ ULONG NewHeight,TotalHeight;
+
+ if(pArgs->Count == 1)
+ {
+ NewHeight = pArgs->Value[0];
+
+ TotalHeight = wWindow[SOURCE_WINDOW].cy +
+ wWindow[OUTPUT_WINDOW].cy;
+
+ if(NewHeight < TotalHeight)
+ {
+ if(wWindow[SOURCE_WINDOW].cy != NewHeight)
+ {
+ wWindow[SOURCE_WINDOW].cy = NewHeight;
+ wWindow[OUTPUT_WINDOW].y = wWindow[SOURCE_WINDOW].y + wWindow[SOURCE_WINDOW].cy + 1;
+ wWindow[OUTPUT_WINDOW].cy = TotalHeight - NewHeight;
+
+ RepaintDesktop();
+ }
+ }
+ }
+ else
+ {
+ PICE_sprintf(tempCmd,"code window at position %u has %u lines \n",wWindow[SOURCE_WINDOW].y,wWindow[SOURCE_WINDOW].cy);
+ Print(OUTPUT_WINDOW,tempCmd);
+ }
+
+ return TRUE;
+}
+
+//*************************************************************************
+// SizeDataWindow()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(SizeDataWindow)
+{
+ ULONG NewHeight,TotalHeight;
+
+ if(pArgs->Count)
+ {
+ NewHeight = pArgs->Value[0];
+
+ TotalHeight = wWindow[DATA_WINDOW].cy +
+ wWindow[SOURCE_WINDOW].cy;
+
+ if(NewHeight < TotalHeight)
+ {
+ if(wWindow[DATA_WINDOW].cy != NewHeight)
+ {
+ wWindow[DATA_WINDOW].cy = NewHeight;
+ wWindow[SOURCE_WINDOW].y = wWindow[DATA_WINDOW].y + wWindow[DATA_WINDOW].cy + 1;
+ wWindow[SOURCE_WINDOW].cy = TotalHeight - NewHeight;
+
+ RepaintDesktop();
+ }
+ }
+ }
+ else
+ {
+ PICE_sprintf(tempCmd,"data window has %u lines \n",wWindow[DATA_WINDOW].cy);
+ Print(OUTPUT_WINDOW,tempCmd);
+ }
+
+ return TRUE;
+}
+
+//*************************************************************************
+// ClearScreen()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ClearScreen)
+{
+ EmptyRingBuffer();
+
+ Clear(OUTPUT_WINDOW);
+ CheckRingBuffer();
+
+ return TRUE;
+}
+
+//*************************************************************************
+// ShowMappings()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowMappings)
+{
+#if 0
+ ULONG ulPageDir;
+ ULONG ulPageTable;
+ ULONG address;
+ ULONG phys_addr;
+ pgd_t * pPGD;
+ pmd_t * pPMD;
+ pte_t * pPTE;
+ struct mm_struct* p = NULL;
+ struct task_struct* my_current = (struct task_struct*)0xFFFFE000;
+
+ DPRINT((0,"ShowMappings()\n"));
+
+ if(pArgs->Count == 1)
+ {
+ // We're in DebuggerShell(), so we live on a different stack
+ (ULONG)my_current &= ulRealStackPtr;
+
+ // in case we have a user context we use it's mm_struct
+ if(my_current->mm)
+ {
+ p = my_current->mm;
+ }
+ // no user context -> use kernel's context
+ else
+ {
+ p = my_init_mm;
+ }
+
+ // get the requested address from arguments
+ phys_addr = pArgs->Value[0];
+
+ DPRINT((0,"ShowMappings(): p = %X phys_addr = %X\n",(ULONG)p,phys_addr));
+
+ // for every page directory
+ for(ulPageDir=0;ulPageDir<1024;ulPageDir++)
+ {
+ address = (ulPageDir<<22);
+
+ // get the page directory for the address
+ pPGD = pgd_offset(p,address);
+ // if page dir present
+ if(pPGD && pgd_val(*pPGD)&_PAGE_PRESENT)
+ {
+ DPRINT((0,"ShowMappings(): page directory present for %x\n",address));
+ // not large page
+ if(!(pgd_val(*pPGD)&_PAGE_4M))
+ {
+ DPRINT((0,"ShowMappings(): page directory for 4k pages\n"));
+ for(ulPageTable=0;ulPageTable<1024;ulPageTable++)
+ {
+ address = (ulPageDir<<22)|(ulPageTable<<12);
+
+ pPMD = pmd_offset(pPGD,address);
+ if(pPMD)
+ {
+ pPTE = pte_offset(pPMD,address);
+ if(pPTE)
+ {
+ if(*(PULONG)pPTE & _PAGE_PRESENT)
+ {
+ ULONG ulPte = *(PULONG)pPTE & 0xFFFFF000;
+
+ if(ulPte == (phys_addr & 0xFFFFF000))
+ {
+ PICE_sprintf(tempCmd,"%.8X\n",address+(phys_addr&0xFFF));
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)return TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ // large page
+ else
+ {
+ address = (ulPageDir<<22);
+ if((pgd_val(*pPGD)&0xFFC00000) == (phys_addr & 0xFFC00000) )
+ {
+ if( ((address|(phys_addr&0x7FFFFF))&~TASK_SIZE) == phys_addr)
+ PICE_sprintf(tempCmd,"%.8X (identity map %.8X+%.8X)\n",address|(phys_addr&0x7FFFFF),TASK_SIZE,phys_addr);
+ else
+ PICE_sprintf(tempCmd,"%.8X\n",address|(phys_addr&0x7FFFFF));
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)return TRUE;
+ }
+ }
+ }
+ }
+ }
+#endif
+ PICE_sprintf(tempCmd,"Not implemented yet!\n");
+ Print(OUTPUT_WINDOW,tempCmd);
+ return TRUE;
+}
+
+//*************************************************************************
+// ShowTimers()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowTimers)
+{
+
+ return TRUE;
+}
+
+//*************************************************************************
+// FindPCIVendorName()
+//
+//*************************************************************************
+LPSTR FindPCIVendorName(USHORT vendorid)
+{
+ ULONG i;
+
+ for(i=0;i<DIM(PCIVendorIDs);i++)
+ {
+ if(vendorid == PCIVendorIDs[i].vendorid)
+ return PCIVendorIDs[i].vendor_name;
+ }
+
+ return NULL;
+}
+
+//*************************************************************************
+// ShowPCI()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowPCI)
+{
+ ULONG oldCF8,data,bus,dev,reg,i,ulNumBaseAddresses,bus_req=0,dev_req=0;
+ PCI_NUMBER pciNumber;
+ PCI_COMMON_CONFIG pciConfig,*ppciConfig;
+ PULONG p;
+ LPSTR pVendorName;
+ char temp[32];
+ BOOLEAN bShowAll = FALSE,bUseDev=TRUE,bUseBus=TRUE;
+
+
+ DPRINT((0,"ShowPCI()\n"));
+
+ if(pArgs->CountSwitches>1)
+ return TRUE;
+
+ if(pArgs->CountSwitches==1)
+ {
+ if(pArgs->Switch[0] == 'a')
+ bShowAll = TRUE;
+ }
+
+ if(pArgs->Count < 3)
+ {
+ if(pArgs->Count > 0)
+ {
+ bUseBus = FALSE;
+ bus_req = pArgs->Value[0];
+ }
+ if(pArgs->Count > 1)
+ {
+ bUseDev = FALSE;
+ dev_req = pArgs->Value[1];
+ }
+
+ // save old config space selector
+ oldCF8 = inl((PULONG)0xcf8);
+
+ for(bus=0;bus<256;bus++)
+ {
+ for(dev=0;dev<32;dev++)
+ {
+ if(!((bUseDev || dev == dev_req) &&
+ (bUseBus || bus == bus_req) ))
+ continue;
+
+ pciNumber.u.AsUlong = 0;
+ pciNumber.u.bits.dev = dev;
+ pciNumber.u.bits.bus = bus;
+ pciNumber.u.bits.func = 0;
+ pciNumber.u.bits.ce = 1;
+ outl(pciNumber.u.AsUlong,(PULONG)0xcf8);
+ data = inl((PULONG)0xcfc);
+
+ if(data != 0xFFFFFFFF) // valid device
+ {
+ if((pVendorName = FindPCIVendorName((USHORT)data)) )
+ {
+ PICE_sprintf(tempCmd,"Bus%-8uDev%-8u === %.4X %.4X %s ====\n",bus,dev,(USHORT)data,(USHORT)(data>>16),pVendorName);
+ }
+ else
+ {
+ PICE_sprintf(tempCmd,"Bus%-8uDev%-8u === %.4X %.4X N/A ====\n",bus,dev,(USHORT)data,(USHORT)(data>>16));
+ }
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)goto CommonShowPCIExit;
+
+ p = (PULONG)&pciConfig;
+ for(reg=0;reg<sizeof(PCI_COMMON_CONFIG)/sizeof(ULONG);reg++)
+ {
+ pciNumber.u.AsUlong = 0;
+ pciNumber.u.bits.dev = dev;
+ pciNumber.u.bits.bus = bus;
+ pciNumber.u.bits.func = 0;
+ pciNumber.u.bits.reg = reg;
+ pciNumber.u.bits.ce = 1;
+
+ outl(pciNumber.u.AsUlong,(PULONG)0xcf8);
+ *p++ = inl((PULONG)0xcfc);
+ }
+ PICE_sprintf(tempCmd,"SubVendorId %.4X SubSystemId %.4X\n",pciConfig.u.type0.SubVendorID,pciConfig.u.type0.SubSystemID);
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)goto CommonShowPCIExit;
+
+ if(bShowAll)
+ {
+ for(ulNumBaseAddresses=0,i=0;i<6;i++)
+ {
+ if(pciConfig.u.type0.BaseAddresses[i] != 0)
+ ulNumBaseAddresses++;
+ }
+ if(ulNumBaseAddresses)
+ {
+ Print(OUTPUT_WINDOW,"BaseAddresses:");
+ tempCmd[0] = 0;
+ for(i=0;i<6;i++)
+ {
+ if(pciConfig.u.type0.BaseAddresses[i] != 0)
+ {
+ PICE_sprintf(temp," %u:%.8X",i,pciConfig.u.type0.BaseAddresses[i]);
+ PICE_strcat(tempCmd,temp);
+ }
+ }
+ Print(OUTPUT_WINDOW,tempCmd);
+ Print(OUTPUT_WINDOW,"\n");
+ if(WaitForKey()==FALSE)goto CommonShowPCIExit;
+ }
+ ppciConfig = &pciConfig;
+ #if 0
+ // sedwards
+ SHOW_FIELD_WORD(ppciConfig,Status,TRUE);
+ SHOW_FIELD_WORD(ppciConfig,Command,TRUE);
+ SHOW_FIELD_BYTE(ppciConfig,RevisionID,TRUE);
+ SHOW_FIELD_BYTE(ppciConfig,ProgIf,TRUE);
+ SHOW_FIELD_BYTE(ppciConfig,BaseClass,TRUE);
+ SHOW_FIELD_BYTE(ppciConfig,SubClass,TRUE);
+ SHOW_FIELD_BYTE(ppciConfig,CacheLineSize,TRUE);
+ SHOW_FIELD_BYTE(ppciConfig,LatencyTimer,TRUE);
+ #endif
+ }
+ }
+ }
+ }
+
+CommonShowPCIExit:
+ // restore old config space selector
+ outl(oldCF8,(PULONG)0xcf8);
+
+ }
+ else if(pArgs->Count == 1)
+ {
+ }
+
+ return TRUE;
+}
+
+//*************************************************************************
+// SetKeyboardLayout()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(SetKeyboardLayout)
+{
+ PKEYBOARD_LAYOUT layout;
+
+ ENTER_FUNC();
+
+ layout = GetKeyboardLayout();
+
+ switch(pArgs->Count)
+ {
+ case 0:
+ PICE_sprintf(tempCmd,"current layout = %s\n", layout->name);
+ Print(OUTPUT_WINDOW,tempCmd);
+ break;
+ case 1:
+ layout = SetKeyboardLayoutByName((LPSTR)pArgs->Value[0]);
+ PICE_sprintf(tempCmd,"current layout = %s\n", layout->name);
+ Print(OUTPUT_WINDOW,tempCmd);
+ break;
+ }
+
+ LEAVE_FUNC();
+
+ return TRUE;
+}
+
+//*************************************************************************
+// ShowSysCallTable()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowSysCallTable)
+{
+#if 0
+ LPSTR pName;
+ ULONG i;
+
+ ENTER_FUNC();
+
+ if(pArgs->Count == 0)
+ {
+ PICE_sprintf(tempCmd,"%u system calls\n",190);
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()!=FALSE)
+ for(i=0;i<190;i++)
+ {
+ if((pName = FindFunctionByAddress(sys_call_table[i],NULL,NULL)) )
+ {
+ PICE_sprintf(tempCmd,"%-.3u: %.8X (%s)\n",i,sys_call_table[i],pName);
+ }
+ else
+ {
+ PICE_sprintf(tempCmd,"%-.3u: %.8X (%s)\n",i,sys_call_table[i],pName);
+ }
+ Print(OUTPUT_WINDOW,tempCmd);
+ if(WaitForKey()==FALSE)
+ break;
+ }
+ }
+ else if(pArgs->Count == 1)
+ {
+ i = pArgs->Value[0];
+ if(i<190)
+ {
+ if((pName = FindFunctionByAddress(sys_call_table[i],NULL,NULL)) )
+ {
+ PICE_sprintf(tempCmd,"%-.3u: %.8X (%s)\n",i,sys_call_table[i],pName);
+ }
+ else
+ {
+ PICE_sprintf(tempCmd,"%-.3u: %.8X (%s)\n",i,sys_call_table[i],pName);
+ }
+ Print(OUTPUT_WINDOW,tempCmd);
+ }
+ }
+
+ LEAVE_FUNC();
+#endif
+ PICE_sprintf(tempCmd,"Not implemented yet!\n");
+ Print(OUTPUT_WINDOW,tempCmd);
+ return TRUE;
+}
+
+//*************************************************************************
+// SetAltKey()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(SetAltKey)
+{
+ if(pArgs->Count == 1)
+ {
+ ucBreakKey = (UCHAR)pArgs->Value[0];
+
+ PICE_sprintf(tempCmd,"new break key is CTRL-%c\n",ucBreakKey);
+ Print(OUTPUT_WINDOW,tempCmd);
+ }
+ else if(pArgs->Count == 0)
+ {
+ PICE_sprintf(tempCmd,"current break key is CTRL-%c\n",ucBreakKey);
+ Print(OUTPUT_WINDOW,tempCmd);
+ }
+
+
+ COMMAND_RET;
+}
+
+//*************************************************************************
+// ShowContext()
+//
+//*************************************************************************
+COMMAND_PROTOTYPE(ShowContext)
+{
+ COMMAND_RET;
+}
+
+//*************************************************************************
+//
+// utility functions for parsing
+//
+//*************************************************************************
+
+
+//*************************************************************************
+// FindCommand()
+//
+//*************************************************************************
+LPSTR FindCommand(LPSTR p)
+{
+ ULONG i,j,k=0;
+ LPSTR result=NULL;
+
+ tempCmd[0]=0;
+ for(j=0,i=0;CmdTable[i].Cmd!=NULL;i++)
+ {
+ if(PICE_strncmpi(CmdTable[i].Cmd,p,PICE_strlen(p)) == 0 &&
+ CmdTable[i].CommandGroup != COMMAND_GROUP_HELP_ONLY)
+ {
+ if(PICE_strlen(tempCmd))
+ PICE_strcat(tempCmd,", ");
+ PICE_strcat(tempCmd,CmdTable[i].Cmd);
+ j++;
+ k=i;
+ }
+ }
+ if(PICE_strlen(tempCmd))
+ {
+ SetBackgroundColor(COLOR_CAPTION);
+ SetForegroundColor(COLOR_TEXT);
+ ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
+ PutChar(tempCmd,1,wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
+ if(j==1)
+ {
+ PICE_sprintf(tempCmd,"%s",CmdTable[k].Help);
+ PutChar(tempCmd,40,wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
+ result=CmdTable[k].Cmd;
+ }
+ ResetColor();
+ }
+ return result;
+}
+
+
+//*************************************************************************
+// CompactString()
+//
+//*************************************************************************
+void CompactString(LPSTR p)
+{
+ULONG i;
+
+ for(i=1;i<PICE_strlen(p);i++)
+ {
+ if(p[i]==' ' && p[i-1]==' ')
+ {
+ PICE_strcpy(&p[i-1],&p[i]);
+ i=1;
+ }
+ }
+}
+
+//*************************************************************************
+// PICE_strtok()
+//
+//*************************************************************************
+char* PICE_strtok(char *szInputString)
+{
+static char* szCurrString;
+char *szTempString;
+ULONG currlength;
+ULONG i;
+
+ if(szInputString)
+ {
+ szCurrString=szInputString;
+ CompactString(szCurrString);
+ }
+
+ currlength=PICE_strlen(szCurrString);
+ if(!currlength)
+ {
+ szCurrString=0;
+ return NULL;
+ }
+ for(i=0;i<currlength;i++)
+ {
+ if(szCurrString[i]==' ')
+ {
+ szCurrString[i]=0;
+ break;
+ }
+ }
+ szTempString=szCurrString;
+ szCurrString=szCurrString+i+1;
+ return szTempString;
+}
+
+//*************************************************************************
+// ConvertTokenToHex()
+//
+//*************************************************************************
+BOOLEAN ConvertTokenToHex(LPSTR p,PULONG pValue)
+{
+ULONG result=0,i;
+
+ gCurrentSelector=0;
+ gCurrentOffset=0;
+ for(i=0;i<8 && p[i]!=0 && p[i]!=' ' && p[i]!=':';i++)
+ {
+ if(p[i]>='0' && p[i]<='9')
+ {
+ result<<=4;
+ result|=(ULONG)(UCHAR)(p[i]-'0');
+ }
+ else if(p[i]>='A' && p[i]<='F')
+ {
+ result<<=4;
+ result|=(ULONG)(UCHAR)(p[i]-'A'+10);
+ }
+ else if(p[i]>='a' && p[i]<='f')
+ {
+ result<<=4;
+ result|=(ULONG)(UCHAR)(p[i]-'a'+10);
+ }
+ else
+ return FALSE;
+ }
+ p+=(i+1);
+ if(p[i]==':')
+ {
+ ULONG ulSelector=result;
+ if(ulSelector>0xFFFF)
+ return FALSE;
+ for(i=0;i<8 && p[i]!=0 && p[i]!=' ' && p[i]!=':';i++)
+ {
+ if(p[i]>='0' && p[i]<='9')
+ {
+ result<<=4;
+ result|=(ULONG)(UCHAR)(p[i]-'0');
+ }
+ else if(p[i]>='A' && p[i]<='F')
+ {
+ result<<=4;
+ result|=(ULONG)(UCHAR)(p[i]-'A'+10);
+ }
+ else if(p[i]>='a' && p[i]<='f')
+ {
+ result<<=4;
+ result|=(ULONG)(UCHAR)(p[i]-'a'+10);
+ }
+ else
+ return FALSE;
+ }
+ gCurrentSelector=(USHORT)ulSelector;
+ gCurrentOffset=result;
+ result = GetLinearAddress((USHORT)ulSelector,result);
+ }
+ *pValue=result;
+ return TRUE;
+}
+
+//*************************************************************************
+// ConvertTokenToDec()
+//
+//*************************************************************************
+BOOLEAN ConvertTokenToDec(LPSTR p,PULONG pValue)
+{
+ ULONG result=0;
+ char c;
+
+ while((c = *p))
+ {
+ if(c >= '0' && c <= '9')
+ {
+ result *= 10;
+ result += (ULONG)(c - '0');
+ }
+ else
+ return FALSE;
+
+ p++;
+ }
+ *pValue = result;
+ return TRUE;
+}
+
+//*************************************************************************
+// ConvertTokenToSymbol()
+//
+//*************************************************************************
+BOOLEAN ConvertTokenToSymbol(LPSTR pToken,PULONG pValue)
+{
+ LPSTR pEx;
+ char temp[64];
+ LPSTR p;
+ PDEBUG_MODULE pModFound;
+
+ DPRINT((0,"ConvertTokenToSymbol()\n"));
+
+ PICE_strcpy(temp,pToken);
+ p = temp;
+
+ // test for module!symbol string
+ pEx = PICE_strchr(p,'!');
+ if(pEx)
+ {
+ DPRINT((0,"ConvertTokenToSymbol(): module!symbol syntax detected\n"));
+ // terminate module name
+ *pEx = 0;
+ // now we have two pointers
+ pEx++;
+ DPRINT((0,"ConvertTokenToSymbol(): module = %s symbol = %s\n",p,pEx));
+
+ if( pModFound=IsModuleLoaded(p) )
+ {
+ if((*pValue = FindFunctionInModuleByName(pEx,pModFound)))
+ return TRUE;
+ }
+ }
+ else
+ {
+ if(pCurrentMod)
+ {
+ if((*pValue = FindFunctionInModuleByName(p,pCurrentMod)))
+ return TRUE;
+ }
+ return ScanExports(p,pValue);
+ }
+ return FALSE;
+}
+
+//*************************************************************************
+// ConvertTokenToModuleAndName()
+//
+//*************************************************************************
+BOOLEAN ConvertTokenToModuleAndName(LPSTR pToken,PULONG pulModuleName,PULONG pulFunctionName)
+{
+ LPSTR pEx;
+ char temp[64];
+ LPSTR p;
+ static char module_name[128];
+ static char function_name[128];
+
+ // test for module!symbol string
+ PICE_strcpy(temp,pToken);
+ p = temp;
+
+ DPRINT((0,"ConvertTokenToModuleAndName(%s)\n",p));
+
+ pEx = PICE_strchr(p,'!');
+ if(pEx)
+ {
+ DPRINT((0,"ConvertTokenToModuleAndName(): module!symbol syntax detected\n"));
+ // terminate module name
+ *pEx = 0;
+ // now we have two pointers
+ pEx++;
+ DPRINT((0,"ConvertTokenToModuleAndName(): module = %s symbol = %s\n",p,pEx));
+ PICE_strcpy(module_name,p);
+ PICE_strcpy(function_name,pEx);
+ *pulModuleName = (ULONG)module_name;
+ *pulFunctionName = (ULONG)function_name;
+ return TRUE;
+
+ }
+ return FALSE;
+}
+
+//*************************************************************************
+// ConvertTokenToModule()
+//
+// convert an argument module name to a pointer to the module's symbols
+//*************************************************************************
+BOOLEAN ConvertTokenToModule(LPSTR p,PULONG pValue)
+{
+ ULONG i;
+ char temp[DEBUG_MODULE_NAME_LEN];
+
+ for(i=0;i<DIM(apSymbols);i++)
+ {
+ if(apSymbols[i])
+ {
+ CopyWideToAnsi(temp,apSymbols[i]->name);
+ if(PICE_strcmpi(p,temp)==0)
+ {
+ *pValue = (ULONG)apSymbols[i];
+ return TRUE;
+ }
+ }
+ }
+
+ for(i=0;i<DIM(apSymbols);i++)
+ {
+ if(apSymbols[i])
+ {
+ CopyWideToAnsi(temp,apSymbols[i]->name);
+ if(PICE_strncmpi(temp,p,PICE_strlen(p))==0)
+ {
+ *pValue = (ULONG)apSymbols[i];
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+//*************************************************************************
+// ConvertTokenToProcess()
+//
+//*************************************************************************
+BOOLEAN ConvertTokenToProcess(LPSTR p,PULONG pValue)
+{
+ return FALSE;
+}
+
+//*************************************************************************
+// ReplaceKeywordWithValue()
+//
+//*************************************************************************
+BOOLEAN ReplaceKeywordWithValue(LPSTR p,PULONG pValue,KEYWORDS* pKeyWords)
+{
+ ULONG i;
+
+ for(i=0;pKeyWords[i].KeyWord!=NULL;i++)
+ {
+ if(PICE_strcmpi(p,pKeyWords[i].KeyWord)==0)
+ {
+ switch(pKeyWords[i].ulSize)
+ {
+ case sizeof(USHORT):
+ *pValue=(ULONG)*(PUSHORT)(pKeyWords[i].pValue);
+ break;
+ case sizeof(ULONG):
+ *pValue=*(PULONG)(pKeyWords[i].pValue);
+ break;
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+//*************************************************************************
+// ConvertTokenToKeyword()
+//
+//*************************************************************************
+BOOLEAN ConvertTokenToKeyword(LPSTR p,PULONG pValue)
+{
+ char Name[256];
+ ULONG count;
+
+ DPRINT((0,"ConvertTokenToKeyword()\n"));
+ count=StrLenUpToWhiteChar(p," ");
+ PICE_strncpy(Name,p,count);
+ Name[count]=0;
+ if(ReplaceKeywordWithValue(Name,pValue,RegKeyWords))
+ {
+ DPRINT((0,"ConvertTokenToKeyword(): success\n"));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//*************************************************************************
+// ConvertTokenToSpecialKeyword()
+//
+//*************************************************************************
+BOOLEAN ConvertTokenToSpecialKeyword(LPSTR p,PULONG pValue)
+{
+ char Name[256];
+ ULONG count;
+
+ count=StrLenUpToWhiteChar(p," ");
+ PICE_strncpy(Name,p,count);
+ Name[count]=0;
+ if(ReplaceKeywordWithValue(Name,pValue,SpecialKeyWords))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//*************************************************************************
+// ConvertTokenToOnOff()
+//
+//*************************************************************************
+BOOLEAN ConvertTokenToOnOff(LPSTR p,PULONG pValue)
+{
+ char Name[256];
+ ULONG count;
+
+ count=StrLenUpToWhiteChar(p," ");
+ PICE_strncpy(Name,p,count);
+ Name[count]=0;
+ if(ReplaceKeywordWithValue(Name,pValue,OnOffKeyWords))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//*************************************************************************
+// ConvertSizeToKeyword()
+//
+//*************************************************************************
+BOOLEAN ConvertSizeToKeyword(LPSTR p,PULONG pValue)
+{
+ ULONG count;
+
+ count=StrLenUpToWhiteChar(p," ");
+ if(count > 1)
+ return FALSE;
+
+ switch(*p)
+ {
+ // BYTE
+ case 'b':
+ case 'B':
+ *pValue = 1;
+ break;
+ // WORD
+ case 'w':
+ case 'W':
+ *pValue = 2;
+ break;
+ // DWORD
+ case 'd':
+ case 'D':
+ *pValue = 4;
+ break;
+ // QWORD
+ case 'q':
+ case 'Q':
+ *pValue = 4;
+ break;
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+//*************************************************************************
+// ConvertTokenToSrcFile()
+//
+//*************************************************************************
+BOOLEAN ConvertTokenToSrcFile(LPSTR p,PULONG pValue)
+{
+ PICE_SYMBOLFILE_SOURCE* pSrc;
+ LPSTR pFilename,pFilenameSrc;
+ ULONG i;
+
+ DPRINT((0,"ConvertTokenToSrcFile(%s)\n",p));
+
+ if(pCurrentSymbols && pCurrentSymbols->ulNumberOfSrcFiles)
+ {
+ DPRINT((0,"ConvertTokenToSrcFile(): current symbols for %S\n",pCurrentSymbols->name));
+
+ pSrc = (PICE_SYMBOLFILE_SOURCE*)((ULONG)pCurrentSymbols + pCurrentSymbols->ulOffsetToSrcFiles);
+
+ for(i=0;i<pCurrentSymbols->ulNumberOfSrcFiles;i++)
+ {
+ pFilename = strrchr(pSrc->filename,'/');
+ if(!pFilename)
+ pFilename = pSrc->filename;
+ else
+ pFilename++;
+
+ pFilenameSrc = strrchr(p,'/');
+ if(!pFilenameSrc )
+ pFilenameSrc = p;
+ else
+ pFilenameSrc++;
+
+ DPRINT((0,"ConvertTokenToSrcFile(): %s\n",pFilename));
+
+ if(PICE_strcmpi(pFilename,pFilenameSrc) == 0)
+ {
+ DPRINT((0,"ConvertTokenToSrcFile(): found %s\n",pFilename));
+
+ *pValue = (ULONG)pSrc;
+ return TRUE;
+ }
+
+ // go to next file
+ (LPSTR)pSrc += pSrc->ulOffsetToNext;
+ }
+
+ pSrc = (PICE_SYMBOLFILE_SOURCE*)((ULONG)pCurrentSymbols + pCurrentSymbols->ulOffsetToSrcFiles);
+
+ // if not found now do a lookup for partials
+ for(i=0;i<pCurrentSymbols->ulNumberOfSrcFiles;i++)
+ {
+ pFilename = strrchr(pSrc->filename,'/');
+ if(!pFilename)
+ pFilename = pSrc->filename;
+ else
+ pFilename++;
+
+ DPRINT((0,"ConvertTokenToSrcFile(): %s\n",pFilename));
+
+ if(PICE_strncmpi(pFilename,p,PICE_strlen(p)) == 0)
+ {
+ DPRINT((0,"ConvertTokenToSrcFile(): found %s\n",pFilename));
+
+ *pValue = (ULONG)pSrc;
+ return TRUE;
+ }
+
+ // go to next file
+ (LPSTR)pSrc += pSrc->ulOffsetToNext;
+ }
+
+ }
+ return FALSE;
+}
+
+//*************************************************************************
+// ConvertTokenToLineNumber()
+//
+//*************************************************************************
+BOOLEAN ConvertTokenToLineNumber(LPSTR p,PULONG pValue)
+{
+ ULONG ulDecimal;
+
+ DPRINT((0,"ConvertTokenToLineNumber()\n"));
+ if(*p++ == '.')
+ {
+ ulDecimal = ExtractNumber(p);
+ DPRINT((0,"ConvertTokenToLineNumber(): ulDecimal = %u\n",ulDecimal));
+ if(ulDecimal)
+ {
+ DPRINT((0,"ConvertTokenToLineNumber(): current file = %s\n",szCurrentFile));
+ if(pCurrentMod && PICE_strlen(szCurrentFile))
+ {
+ DPRINT((0,"ConvertTokenToLineNumber(): current file %S\n",pCurrentMod->name));
+ if(FindAddressForSourceLine(ulDecimal,szCurrentFile,pCurrentMod,pValue))
+ {
+ DPRINT((0,"ConvertTokenToLineNumber(): value = %x\n",*pValue));
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+//*************************************************************************
+// IsWhiteChar()
+//
+//*************************************************************************
+BOOLEAN IsWhiteChar(char c,LPSTR WhiteChars)
+{
+ USHORT lenWhiteChar = PICE_strlen(WhiteChars);
+ USHORT i;
+ for(i=0;i<lenWhiteChar;i++)
+ {
+ if(c == WhiteChars[i])
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//*************************************************************************
+// StrLenUpToWhiteChar()
+//
+//*************************************************************************
+ULONG StrLenUpToWhiteChar(LPSTR p,LPSTR WhiteChars)
+{
+ ULONG i;
+
+ for(i=0;p[i]!=0 && !IsWhiteChar(p[i],WhiteChars);i++);
+
+ return i;
+}
+
+//
+// command line parser
+//
+void Parse(LPSTR pCmdLine,BOOLEAN bInvokedByFkey)
+{
+ ULONG i,j;
+ BOOLEAN result=FALSE;
+ char *pToken;
+ ARGS Arguments;
+ CMDTABLE *pCurrentCommand=NULL;
+
+ ulCountForWaitKey = 0;
+
+ if(!bInvokedByFkey)
+ {
+ ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].usCurY);
+ }
+
+ PICE_memset(&Arguments,0,sizeof(ARGS));
+
+ for(j=0,i=0;CmdTable[i].Cmd!=NULL;i++)
+ {
+ if(PICE_strncmpi(CmdTable[i].Cmd,pCmdLine,PICE_strlen(CmdTable[i].Cmd))==0 &&
+ PICE_strlen(CmdTable[i].Cmd)==StrLenUpToWhiteChar(pCmdLine," ") &&
+ CmdTable[i].CommandGroup != COMMAND_GROUP_HELP_ONLY)
+ {
+ pCurrentCommand=&CmdTable[i];
+ break;
+ }
+ }
+ if(pCurrentCommand==NULL)
+ {
+ Print(OUTPUT_WINDOW," <-- command not found\n");
+ Print(OUTPUT_WINDOW,":");
+ goto CommonParseReturnPoint;
+ }
+
+ pToken = PICE_strtok( pCmdLine);
+ // get the args and convert them into numbers
+ i=0;
+ j=0;
+ do
+ {
+ pToken=PICE_strtok( NULL);
+ DPRINT((0,"pToken = %s\n",pToken));
+ if(pToken)
+ {
+ if(*pToken == '-' && PICE_strlen(pToken)==2)
+ {
+ DPRINT((0,"might be a switch\n"));
+ if(pCurrentCommand->Flags & COMMAND_HAS_SWITCHES)
+ {
+ // token starts with '-' and is 2 chars long
+ // must be a switch
+ if(PICE_strchr(pCurrentCommand->pszRecognizedSwitches,*(pToken+1)) )
+ {
+ DPRINT((0,"is a switch!\n"));
+ Arguments.Switch[j++]=*(pToken+1);
+ continue;
+ }
+ // not a valid switch
+ else
+ {
+ PICE_sprintf(tempCmd," <-- %s is not a valid switch\n",pToken);
+ Print(OUTPUT_WINDOW,tempCmd);
+ Print(OUTPUT_WINDOW,":");
+ goto CommonParseReturnPoint;
+ }
+ }
+ else
+ {
+ PICE_sprintf(tempCmd," <-- %s can't have any switches\n",pCurrentCommand->Cmd);
+ Print(OUTPUT_WINDOW,tempCmd);
+ Print(OUTPUT_WINDOW,":");
+ goto CommonParseReturnPoint;
+ }
+ }
+
+ if(pCurrentCommand->Flags & COMMAND_HAS_PARAMS)
+ {
+ if(!pCurrentCommand->ParamFlags[i])
+ {
+ PICE_sprintf(tempCmd," <-- %s can't have more than %u parameters\n",pCurrentCommand->Cmd,i);
+ Print(OUTPUT_WINDOW,tempCmd);
+ Print(OUTPUT_WINDOW,":");
+ goto CommonParseReturnPoint;
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_SRCLINE\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_SRCLINE)
+ {
+ if(ConvertTokenToLineNumber(pToken,&Arguments.Value[i]))
+ {
+ i++;
+ continue;
+ }
+ if(*pToken == '.')
+ {
+ PICE_sprintf(tempCmd," <-- no line number %s found\n",pToken);
+ Print(OUTPUT_WINDOW,tempCmd);
+ Print(OUTPUT_WINDOW,":");
+ goto CommonParseReturnPoint;
+ }
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_NUMERIC\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_NUMERIC)
+ {
+ if(ConvertTokenToHex(pToken,&Arguments.Value[i]))
+ {
+ i++;
+ continue;
+ }
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_DECIMAL\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_DECIMAL)
+ {
+ if(ConvertTokenToDec(pToken,&Arguments.Value[i]))
+ {
+ i++;
+ continue;
+ }
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_REG_KEYWORD\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_REG_KEYWORD)
+ {
+ if(ConvertTokenToKeyword(pToken,&Arguments.Value[i]))
+ {
+ Arguments.pToken[i] = pToken;
+ i++;
+ continue;
+ }
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_SYMBOLIC\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_SYMBOLIC)
+ {
+ if(ConvertTokenToSymbol(pToken,&Arguments.Value[i]))
+ {
+ i++;
+ continue;
+ }
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_VIRTUAL_SYMBOLIC\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_VIRTUAL_SYMBOLIC)
+ {
+ DPRINT((0,"might be a virtual modname!symbol syntax!\n"));
+ if(ConvertTokenToModuleAndName(pToken,&Arguments.Value[i],&Arguments.Value[i+1]))
+ {
+ Arguments.bNotTranslated[i]=TRUE;
+ Arguments.bNotTranslated[i+1]=TRUE;
+ i+=2;
+ continue;
+ }
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_MODULE\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_MODULE)
+ {
+ if(ConvertTokenToModule(pToken,&Arguments.Value[i]))
+ {
+ i++;
+ continue;
+ }
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_PRNAME\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_PRNAME)
+ {
+ if(ConvertTokenToProcess(pToken,&Arguments.Value[i]))
+ {
+ i++;
+ continue;
+ }
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_SRC_FILE\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_SRC_FILE)
+ {
+ if(ConvertTokenToSrcFile(pToken,&Arguments.Value[i]))
+ {
+ i++;
+ continue;
+ }
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_ASTERISK\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_ASTERISK)
+ {
+ if(PICE_strlen(pToken)==1 && pToken[0]=='*')
+ {
+ Arguments.Value[i]=-1;
+ i++;
+ continue;
+ }
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_LETTER\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_LETTER)
+ {
+ if(PICE_strlen(pToken)==1 && PICE_isprint(pToken[0]))
+ {
+ Arguments.Value[i]=(ULONG)pToken[0];
+ i++;
+ continue;
+ }
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_ONOFF\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_ONOFF)
+ {
+ if(ConvertTokenToOnOff(pToken,&Arguments.Value[i]))
+ {
+ i++;
+ continue;
+ }
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_PARTIAL_SYM_NAME\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_PARTIAL_SYM_NAME)
+ {
+ Arguments.Value[i] = (ULONG)pToken;
+ i++;
+ continue;
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_ANY_STRING\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_ANY_STRING)
+ {
+ Arguments.Value[i] = (ULONG)pToken;
+ i++;
+ continue;
+ }
+ DPRINT((0,"Parse(): PARAM_CAN_BE_SIZE_DESC\n"));
+ if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_SIZE_DESC)
+ {
+ if(ConvertSizeToKeyword(pToken,&Arguments.Value[i]))
+ {
+ Arguments.pToken[i] = pToken;
+ i++;
+ continue;
+ }
+ }
+ PICE_sprintf(tempCmd," <-- syntax error in parameter %u!\n",i);
+ Print(OUTPUT_WINDOW,tempCmd);
+ Print(OUTPUT_WINDOW,":");
+ goto CommonParseReturnPoint;
+ }
+ else
+ {
+ PICE_sprintf(tempCmd," <-- %s has no parameters\n",pCurrentCommand->Cmd);
+ Print(OUTPUT_WINDOW,tempCmd);
+ Print(OUTPUT_WINDOW,":");
+ goto CommonParseReturnPoint;
+ }
+ // next token
+ i++;
+ }
+ }while(pToken && i<MAX_ARGS);
+
+ Arguments.Count=i;
+ Arguments.CountSwitches=j;
+
+ if(pCurrentCommand)
+ {
+ DPRINT((0,"Parse(): command %s switches %u\n",pCurrentCommand->Cmd,Arguments.CountSwitches));
+
+ if(!bInvokedByFkey)
+ {
+ DPRINT((0,"Parse(): adding new line\n"));
+ Print(OUTPUT_WINDOW,"\n");
+ }
+
+ // call the command handler
+ result=pCurrentCommand->Handler(&Arguments);
+
+ if(result && !bInvokedByFkey && pCurrentCommand->Handler!=LeaveIce && pCurrentCommand->Handler!=SingleStep )
+ {
+ DPRINT((0,"Parse(): adding colon\n"));
+ Print(OUTPUT_WINDOW,":");
+ }
+ }
+
+CommonParseReturnPoint:
+ SuspendPrintRingBuffer(FALSE);
+ PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
+
+ ShowStatusLine();
+}
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ parse.h
+
+Abstract:
+
+ HEADER for parse.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+typedef struct TagArgs
+{
+ ULONG Value[16];
+ ULONG Count;
+ UCHAR Switch[16];
+ ULONG CountSwitches;
+ BOOLEAN bNotTranslated[16];
+ LPSTR pToken[16];
+}ARGS,*PARGS;
+
+typedef struct tagCPUInfo
+{
+ char *Name;
+ PULONG pValue;
+}CPUINFO;
+
+typedef BOOLEAN (*PFN)(PARGS);
+
+#define MAX_ARGS (5)
+
+typedef struct _CMDTABLE
+{
+ char * Cmd;
+ PFN Handler;
+ char * Help;
+ ULONG Flags;
+ ULONG ParamFlags[MAX_ARGS];
+ LPSTR pszRecognizedSwitches;
+ ULONG CommandGroup;
+}CMDTABLE,*PCMDTABLE;
+
+typedef struct tagKeyWords
+{
+ char* KeyWord;
+ PVOID pValue;
+ ULONG ulSize;
+}KEYWORDS;
+
+typedef struct tagSETGETREGS
+{
+ char *RegName;
+ PULONG RegAddr;
+}SETGETREGS;
+
+typedef struct tag_BP
+{
+ ULONG LinearAddress;
+ ULONG Segment,Offset;
+ BOOLEAN Used;
+ BOOLEAN Active;
+ BOOLEAN Virtual;
+ char ModName[256];
+ char SymName[256];
+}BP;
+
+extern BOOLEAN bNeedToFillBuffer;
+
+extern BOOLEAN bCodeOn;
+extern BOOLEAN bShowSrc;
+extern BP Bp[];
+extern BOOLEAN bInt3Here;
+extern BOOLEAN bInt1Here;
+
+extern BOOLEAN bStepping;
+
+extern char szCurrentFile[256];
+extern PDEBUG_MODULE pCurrentMod;
+extern PICE_SYMBOLFILE_HEADER* pCurrentSymbols;
+extern LONG ulCurrentlyDisplayedLineNumber;
+extern LIST_ENTRY* pPsProcessListHead;
+
+BOOLEAN AsciiToHex(LPSTR p,PULONG pValue);
+void Parse(LPSTR pCmdLine,BOOLEAN bInvokedByFkey);
+LPSTR FindCommand(LPSTR p);
+ULONG StrLenUpToWhiteChar(LPSTR p,LPSTR lpszWhiteChars);
+BOOLEAN WaitForKey(void);
+BOOLEAN ConvertTokenToHex(LPSTR p,PULONG pValue);
+void DisplaySourceFile(LPSTR pSrcLine,LPSTR pSrcEnd,ULONG ulLineNumber,ULONG ulLineNumberToInvert);
+BOOLEAN ConvertTokenToSrcFile(LPSTR p,PULONG pValue);
+void RepaintDesktop(void);
+void PutStatusText(LPSTR p);
+void UnassembleOneLineDown(void);
+void UnassembleOnePageDown(ULONG page);
+void UnassembleOneLineUp(void);
+void UnassembleOnePageUp(ULONG page);
+
+extern BOOLEAN (*DisplayMemory)(PARGS pArgs);
+
+#define COMMAND_PROTOTYPE(arg) BOOLEAN arg(PARGS pArgs)
+#define COMMAND_RET return TRUE
+
+// available commands
+COMMAND_PROTOTYPE(ShowGdt);
+COMMAND_PROTOTYPE(LeaveIce);
+COMMAND_PROTOTYPE(SingleStep);
+COMMAND_PROTOTYPE(ShowHelp);
+COMMAND_PROTOTYPE(ShowPageDirs);
+COMMAND_PROTOTYPE(ShowProcesses);
+COMMAND_PROTOTYPE(DisplayMemoryDword);
+COMMAND_PROTOTYPE(DisplayMemoryByte);
+COMMAND_PROTOTYPE(DisplayPhysMemDword);
+COMMAND_PROTOTYPE(Unassemble);
+COMMAND_PROTOTYPE(ShowSymbols);
+COMMAND_PROTOTYPE(ShowModules);
+COMMAND_PROTOTYPE(SetBreakpoint);
+COMMAND_PROTOTYPE(ListBreakpoints);
+COMMAND_PROTOTYPE(ClearBreakpoints);
+COMMAND_PROTOTYPE(Ver);
+COMMAND_PROTOTYPE(Hboot);
+COMMAND_PROTOTYPE(I3here);
+COMMAND_PROTOTYPE(I1here);
+COMMAND_PROTOTYPE(SetSrcDisplay);
+COMMAND_PROTOTYPE(ShowIdt);
+COMMAND_PROTOTYPE(StepOver);
+COMMAND_PROTOTYPE(StepInto);
+COMMAND_PROTOTYPE(SetGetRegisters);
+COMMAND_PROTOTYPE(SetCodeDisplay);
+COMMAND_PROTOTYPE(NextInstr);
+COMMAND_PROTOTYPE(ShowCPU);
+COMMAND_PROTOTYPE(ShowTables);
+COMMAND_PROTOTYPE(WalkStack);
+COMMAND_PROTOTYPE(ShowVirtualMemory);
+COMMAND_PROTOTYPE(UnassembleAtCurrentEip);
+COMMAND_PROTOTYPE(PokeMemory);
+COMMAND_PROTOTYPE(PeekMemory);
+COMMAND_PROTOTYPE(ShowLocals);
+COMMAND_PROTOTYPE(SwitchTables);
+COMMAND_PROTOTYPE(SwitchFiles);
+COMMAND_PROTOTYPE(EvaluateExpression);
+COMMAND_PROTOTYPE(SizeCodeWindow);
+COMMAND_PROTOTYPE(SizeDataWindow);
+COMMAND_PROTOTYPE(ClearScreen);
+COMMAND_PROTOTYPE(ShowMappings);
+COMMAND_PROTOTYPE(ShowTimers);
+COMMAND_PROTOTYPE(ShowPCI);
+COMMAND_PROTOTYPE(SetKeyboardLayout);
+COMMAND_PROTOTYPE(ShowSysCallTable);
+COMMAND_PROTOTYPE(SetAltKey);
+COMMAND_PROTOTYPE(ShowContext);
+
+//ei - make sure the following correspond to ntoskrnl/mm/i386/page.c
+//sedwards - Dont use them if you dont need them. Use DDK headers instead.
+#define PAGETABLE_MAP (0xf0000000)
+#define PAGEDIRECTORY_MAP (0xf0000000 + (PAGETABLE_MAP / (1024)))
+//#define PAGE_SHIFT 12
+#define PTRS_PER_PTE 1024
+//#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (4 * 1024 * 1024))
+#define ADDR_TO_PDE(v) (PULONG)(PAGEDIRECTORY_MAP + \
+ (((ULONG)v / (1024 * 1024))&(~0x3)))
+#define ADDR_TO_PTE(v) (PULONG)(PAGETABLE_MAP + ((((ULONG)v / 1024))&(~0x3)))
+#define ADDR_TO_PDE_OFFSET(v) (((ULONG)v / (4 * 1024 * 1024)))
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ patch.c
+
+Abstract:
+
+ hooking of kernel internal keyboard interrupt handler
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+ Reactos Port: Eugene Ingerman
+
+Revision History:
+
+ 10-Jul-1999: created
+ 15-Nov-2000: general cleanup of source files
+ 12/1/2001 reactos port
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+
+//#include <asm/system.h>
+
+#include <ntddkbd.h>
+#include <ntdd8042.h>
+#include <rosrtl/string.h>
+
+////////////////////////////////////////////////////
+// GLOBALS
+////
+
+static PUCHAR pPatchAddress;
+static ULONG ulOldOffset = 0;
+static ULONG ulKeyPatchFlags;
+
+void (*old_handle_scancode)(UCHAR,int);
+char tempPatch[256];
+UCHAR ucBreakKey = 'd'; // key that will break into debugger in combination with CTRL
+
+////////////////////////////////////////////////////
+// FUNCTIONS
+////
+
+//***********************************************************************************
+// PiceKbdIsr - keyboard isr hook routine.
+// IsrContext - context that we passed to keyboard driver in internal iocontrol
+// pCurrentInput, pCurrentOutput - not implemented yet
+// StatusByte - keyboard status register
+// pByte - pointer to the byte read from keyboard data port. can be changed.
+// pContinueProcessing - should keyboard driver continue processing this byte.
+//***********************************************************************************
+BOOLEAN PiceKbdIsr (
+ PVOID IsrContext,
+ PKEYBOARD_INPUT_DATA pCurrentInput,
+ POUTPUT_PACKET pCurrentOutput,
+ UCHAR StatusByte,
+ PUCHAR pByte,
+ PBOOLEAN pContinueProcessing,
+ PKEYBOARD_SCAN_STATE pScanState
+ )
+{
+ static BOOLEAN bControl = FALSE;
+ BOOLEAN bForward=TRUE; // should we let keyboard driver process this keystroke
+ BOOLEAN isDown=!(*pByte & 0x80);
+ UCHAR ucKey = *pByte & 0x7f;
+
+ ENTER_FUNC();
+
+ // BUG?? should protect with spinlock since bControl is static.
+ DPRINT((0,"PiceKbdIsr(pByte: %x, val: %x,%u)\n",pByte,*pByte,isDown));
+ DPRINT((0,"PiceKbdIsr(1): bControl = %u bForward = %u bEnterNow = %u\n",bControl,bForward,bEnterNow));
+
+ if(isDown)
+ {
+ DPRINT((0,"bControl: %x, ucKey: %x, breakkey: %x\n", bControl, ucKey, AsciiToScan(ucBreakKey)));
+ // CTRL pressed
+ if(ucKey==0x1d)
+ {
+ bControl=TRUE;
+ }
+ else if(bControl==TRUE && ucKey==AsciiToScan(ucBreakKey)) // CTRL-D
+ {
+ // fake a CTRL-D release call
+ bEnterNow=TRUE;
+ bControl=FALSE;
+ // simulate an initial break
+ __asm__("\n\t \
+ pushfl\n\t \
+ pushl %cs\n\t \
+ pushl $returnpoint\n\t \
+ pushl $" STR(REASON_CTRLF) "\n\t \
+ jmp NewInt31Handler\n\t \
+ returnpoint:");
+ *pByte = 0x1d | 0x80 | 0x7f;
+ bForward=TRUE;
+ }
+ else if((ucKey == 66|| ucKey == 68) && bStepping)
+ {
+ bForward=FALSE;
+ }
+
+ }
+ else
+ {
+ // CTRL released
+ if(ucKey==0x1d)
+ {
+ bControl=FALSE;
+ }
+ else if((ucKey == 66|| ucKey == 68) && bStepping)
+ {
+ bForward=FALSE;
+ }
+ }
+ *pContinueProcessing = bForward;
+ DPRINT((5,"*pContinueProcessing: %d\n", *pContinueProcessing));
+ LEAVE_FUNC();
+ return TRUE;
+}
+
+//***********************************************************************************
+// PiceSendIoctl - send internal_io_control to the driver
+// Target - Device Object that receives control request
+// Ioctl - request
+// InputBuffer - Type3Buffer will be pointing here
+// InputBufferLength - length of inputbuffer
+//***********************************************************************************
+NTSTATUS PiceSendIoctl(PDEVICE_OBJECT Target, ULONG Ioctl,
+ PVOID InputBuffer, ULONG InputBufferLength)
+{
+ KEVENT event;
+ NTSTATUS status = STATUS_SUCCESS;
+ IO_STATUS_BLOCK iosb;
+ PIRP irp;
+
+ KeInitializeEvent(&event,
+ NotificationEvent,
+ FALSE
+ );
+
+ if (NULL == (irp = IoBuildDeviceIoControlRequest(Ioctl,
+ Target,
+ InputBuffer,
+ InputBufferLength,
+ 0,
+ 0,
+ TRUE,
+ &event,
+ &iosb))) {
+ DPRINT((0,"PiceSendIoctl: STATUS_INSUFFICIENT_RESOURCES\n"));
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ status = IoCallDriver(Target, irp);
+
+ if (STATUS_PENDING == status) {
+
+ status = KeWaitForSingleObject(&event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+
+ ASSERT(STATUS_SUCCESS == status);
+ status = iosb.Status;
+ }
+ DPRINT((0,"PiceSendIoctl: status: %d\n",NT_SUCCESS(status)));
+ return status;
+}
+
+//**************************************************
+// PatchKeyboardDriver - set keyboard driver hook.
+// We use interface supported by standard keyboard drivers.
+//**************************************************
+BOOLEAN PatchKeyboardDriver(void)
+{
+ PINTERNAL_I8042_HOOK_KEYBOARD phkData;
+ //When we have i8042 driver this should be changed!!!!!!!
+ UNICODE_STRING DevName = ROS_STRING_INITIALIZER(L"\\Device\\Keyboard");
+ PDEVICE_OBJECT kbdDevice = NULL;
+ PFILE_OBJECT FO = NULL;
+ NTSTATUS status;
+
+ ENTER_FUNC();
+
+ //Get pointer to keyboard device
+ if( !NT_SUCCESS( status = IoGetDeviceObjectPointer( &DevName, FILE_READ_ACCESS, &FO, &kbdDevice ) ) )
+ {
+ DPRINT((0,"PatchKeyboardDriver: IoGetDeviceObjectPointer status: %x\n", status));
+ return FALSE;
+ }
+ phkData = ExAllocatePool( PagedPool, sizeof( INTERNAL_I8042_HOOK_KEYBOARD ) );
+ RtlZeroMemory( phkData, sizeof( INTERNAL_I8042_HOOK_KEYBOARD ) );
+
+ phkData->IsrRoutine = (PI8042_KEYBOARD_ISR) PiceKbdIsr;
+ phkData->Context = (PVOID) NULL; //DeviceObject;
+
+ //call keyboard device internal io control to hook keyboard input stream
+ status = PiceSendIoctl( kbdDevice, IOCTL_INTERNAL_I8042_HOOK_KEYBOARD,
+ phkData, sizeof( INTERNAL_I8042_HOOK_KEYBOARD ) );
+ DPRINT((0,"PatchKeyboardDriver: PiceSendIoctl status: %x\n", status));
+
+
+ ObDereferenceObject(FO);
+ ExFreePool(phkData);
+
+ LEAVE_FUNC();
+
+ return NT_SUCCESS(status);
+}
+
+void RestoreKeyboardDriver(void)
+{
+ ENTER_FUNC();
+ DbgPrint("RestoreKeyboardDriver: Not Implemented yet!!!\n");
+ LEAVE_FUNC();
+}
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ patch.h
+
+Abstract:
+
+ HEADER for patch.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+BOOLEAN PatchKeyboardDriver(void);
+void RestoreKeyboardDriver(void);
+
+extern UCHAR ucBreakKey;
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ pci_ids.h
+
+Abstract:
+
+ HEADER, PCI vendor IDs
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+struct _PCI_VENDOR_IDS
+{
+ USHORT vendorid;
+ char* vendor_name;
+}PCIVendorIDs[]=
+{
+ {0x0033 ,"PARADYNE CORP."},
+ {0x003D ,"REAL 3D"},
+ {0x0100 ,"NCIPHER CORP. LTD"},
+ {0x0A89 ,"BREA TECHNOLOGIES INC"},
+ {0x0E11 ,"COMPAQ COMPUTER CORP."},
+ {0x1000 ,"SYMBIOS LOGIC INC/LSI LOGIC"},
+ {0x1001 ,"KOLTER ELECTRONIC"},
+ {0x1002 ,"ATI TECHNOLOGIES INC"},
+ {0x1004 ,"VLSI TECHNOLOGY INC"},
+ {0x100B ,"NATIONAL SEMICONDUCTOR CORPORATION"},
+ {0x1010 ,"VIDEO LOGIC LTD"},
+ {0x1014 ,"IBM"},
+ {0x1018 ,"UNISYS CORPORATION"},
+ {0x1019 ,"ELITEGROUP COMPUTER SYS"},
+ {0x101A ,"NCR"},
+ {0x101E ,"AMERICAN MEGATRENDS"},
+ {0x1020 ,"HITACHI COMPUTER PRODUCTS"},
+ {0x1021 ,"OKI ELECTRIC INDUSTRY CO. LTD."},
+ {0x1022 ,"ADVANCED MICRO DEVICES"},
+ {0x1023 ,"TRIDENT MICROSYSTEMS"},
+ {0x1028 ,"DELL COMPUTER CORPORATION"},
+ {0x102A ,"LSI LOGIC CORPORATION"},
+ {0x102B ,"MATROX GRAPHICS, INC."},
+ {0x102F ,"TOSHIBA AMERICA, ELEC. COMPANY"},
+ {0x1033 ,"NEC CORPORATION"},
+ {0x1038 ,"AMP, INC"},
+ {0x1039 ,"SILICON INTEGRATED SYSTEMS"},
+ {0x103C ,"HEWLETT PACKARD"},
+ {0x103F ,"SYNOPSYS/LOGIC MODELING GROUP"},
+ {0x1042 ,"MICRON ELECTRONICS, INC."},
+ {0x1043 ,"ASUSTEK COMPUTER, INC."},
+ {0x1044 ,"DISTRIBUTED PROCESSING TECHNOLOGY"},
+ {0x1045 ,"OPTI INC."},
+ {0x1048 ,"ELSA AG"},
+ {0x1049 ,"FOUNTAIN TECHNOLOGIES, INC."},
+ {0x104C ,"TEXAS INSTRUMENTS"},
+ {0x104D ,"SONY CORPORATION"},
+ {0x1050 ,"WINBOND ELECTRONICS CORP"},
+ {0x1054 ,"HITACHI, LTD"},
+ {0x1055 ,"STANDARD MICROSYSTEMS CORP."},
+ {0x1057 ,"MOTOROLA"},
+ {0x1058 ,"ETRI"},
+ {0x1059 ,"TEKNOR INDUSTRIAL COMPUTERS INC"},
+ {0x105A ,"PROMISE TECHNOLOGY, INC."},
+ {0x105B ,"FOXCONN INTERNATIONAL INC"},
+ {0x105D ,"NUMBER 9 VISUAL TECHNOLOGY"},
+ {0x105F ,"INFOTRONIC AMERICA INC"},
+ {0x1063 ,"OCEAN MANUFACTURING LTD"},
+ {0x1064 ,"ALCATEL"},
+ {0x1067 ,"MITSUBISHI ELECTRIC AMERICA"},
+ {0x1068 ,"DIVERSIFIED TECHNOLOGY"},
+ {0x1069 ,"MYLEX CORPORATION"},
+ {0x106B ,"APPLE COMPUTER INC."},
+ {0x106D ,"SEQUENT COMPUTER SYSTEMS"},
+ {0x1070 ,"DAEWOO TELECOM LTD"},
+ {0x1071 ,"MITAC"},
+ {0x1073 ,"YAMAHA CORPORATION"},
+ {0x1077 ,"QLOGIC"},
+ {0x1079 ,"I-BUS"},
+ {0x107B ,"GATEWAY 2000"},
+ {0x107E ,"INTERPHASE CORPORATION"},
+ {0x108D ,"OLICOM"},
+ {0x1095 ,"CMD TECHNOLOGY INC"},
+ {0x1096 ,"ALACRON"},
+ {0x1097 ,"APPIAN/ETMA"},
+ {0x109A ,"PACKARD BELL NEC"},
+ {0x109E ,"BROOKTREE CORPORATION"},
+ {0x109F ,"TRIGEM COMPUTER INC."},
+ {0x10A0 ,"MEIDENSHA CORPORATION"},
+ {0x10A2 ,"QUANTUM EFFECT DESIGN"},
+ {0x10A9 ,"SILICON GRAPHICS"},
+ {0x10AC ,"HONEYWELL IAC"},
+ {0x10AF ,"MICRO COMPUTER SYSTEMS INC"},
+ {0x10B5 ,"PLX TECHNOLOGY, INC."},
+ {0x10B6 ,"MADGE NETWORKS"},
+ {0x10B7 ,"3COM CORPORATION"},
+ {0x10B9 ,"ACER LABS INC."},
+ {0x10BA ,"MITSUBISHI ELECTRIC CORP."},
+ {0x10C2 ,"AUSPEX SYSTEMS INC."},
+ {0x10C8 ,"NEOMAGIC CORPORATION"},
+ {0x10CA ,"FUJITSU MICROELECTRONIC., INC."},
+ {0x10CB ,"OMRON CORPORATION"},
+ {0x10CD ,"ADVANCED SYSTEM PRODUCTS, INC"},
+ {0x10CF ,"FUJITSU LIMITED"},
+ {0x10D1 ,"FUTUREPLUS SYSTEMS CORP."},
+ {0x10D2 ,"MOLEX INCORPORATED"},
+ {0x10DB ,"ROHM LSI SYSTEMS"},
+ {0x10DD ,"EVANS & SUTHERLAND"},
+ {0x10DE ,"NVIDIA CORPORATION"},
+ {0x10DF ,"EMULEX CORPORATION"},
+ {0x10E1 ,"TEKRAM TECHNOLOGY CO.,LTD."},
+ {0x10E3 ,"TUNDRA SEMICONDUCTOR CORP."},
+ {0x10E5 ,"MICRO INDUSTRIES CORPORATION"},
+ {0x10EC ,"REALTEK SEMICONDUCTOR CORP."},
+ {0x10EE ,"XILINX, INC."},
+ {0x10F1 ,"TYAN COMPUTER"},
+ {0x10F5 ,"NKK CORPORATION"},
+ {0x10F6 ,"CREATIVE ELECTRONIC SYSTEMS SA"},
+ {0x10FC ,"I-O DATA DEVICE, INC."},
+ {0x10FE ,"FAST MULTIMEDIA AG"},
+ {0x1101 ,"INITIO CORPORATION"},
+ {0x1102 ,"CREATIVE LABS"},
+ {0x1105 ,"SIGMA DESIGNS, INC"},
+ {0x1106 ,"VIA TECHNOLOGIES, INC."},
+ {0x1107 ,"ASCEND COMMUNICATIONS, INC."},
+ {0x1109 ,"ADAPTEC/COGENT DATA TECHNOLOGIES INC"},
+ {0x110A ,"SIEMENS PC SYSTEME GMBH"},
+ {0x1111 ,"SANTA CRUZ OPERATION"},
+ {0x1113 ,"ACCTON TECHNOLOGY CORPORATION"},
+ {0x1116 ,"MEDIA 100, INC"},
+ {0x1117 ,"DATACUBE, INC"},
+ {0x1118 ,"FCI ELECTRONICS"},
+ {0x1119 ,"ICP-VORTEX COMPUTERSYSTEM GMBH"},
+ {0x111A ,"EFFICIENT NETWORKS, INC"},
+ {0x111D ,"INTEGRATED DEVICE TECH"},
+ {0x1120 ,"EMC CORPORATION"},
+ {0x1127 ,"FORE SYSTEMS INC"},
+ {0x112A ,"HERMES ELECTRONICS COMPANY, LTD."},
+ {0x112F ,"IMAGING TECHNOLOGY, INC"},
+ {0x1131 ,"PHILIPS SEMICONDUCTORS"},
+ {0x1132 ,"MITEL CORP."},
+ {0x1133 ,"EICON TECHNOLOGY CORPORATION"},
+ {0x1134 ,"MERCURY COMPUTER SYSTEMS"},
+ {0x1135 ,"FUJI XEROX CO LTD"},
+ {0x1136 ,"MOMENTUM DATA SYSTEMS"},
+ {0x1137 ,"CISCO SYSTEMS INC"},
+ {0x1138 ,"ZIATECH CORPORATION"},
+ {0x113C ,"CYCLONE MICROSYSTEMS, INC."},
+ {0x113E ,"SANYO ELECTRIC CO - INFORMATION SYSTEMS DIVISION"},
+ {0x1141 ,"CREST MICROSYSTEM INC."},
+ {0x1145 ,"WORKBIT CORPORATION"},
+ {0x1146 ,"FORCE COMPUTERS GMBH"},
+ {0x1148 ,"SYSKONNECT"},
+ {0x114C ,"ANNABOOKS"},
+ {0x114F ,"DIGI INTERNATIONAL"},
+ {0x1154 ,"MELCO INC"},
+ {0x115C ,"PHOTRON LTD."},
+ {0x115D ,"XIRCOM"},
+ {0x1161 ,"PFU LIMITED"},
+ {0x1163 ,"RENDITION, A DIVISION OF MICRON"},
+ {0x1166 ,"RELIANCE COMPUTER"},
+ {0x116E ,"ELECTRONICS FOR IMAGING"},
+ {0x1170 ,"INVENTEC CORPORATION"},
+ {0x1171 ,"BLUE WAVE SYSTEMS"},
+ {0x1172 ,"ALTERA CORPORATION"},
+ {0x1179 ,"TOSHIBA AMERICA INFO SYSTEMS"},
+ {0x1180 ,"RICOH CO LTD"},
+ {0x1186 ,"D-LINK SYSTEM INC"},
+ {0x1187 ,"ADVANCED TECHNOLOGY LABORATORIES, INC."},
+ {0x1189 ,"MATSUSHITA ELECTIC INDUSTRIAL CO LTD"},
+ {0x118B ,"PLATYPUS TECHNOLOGY PTY LTD"},
+ {0x118C ,"COROLLARY, INC"},
+ {0x1191 ,"ACARD TECHNOLOGY CORP"},
+ {0x1195 ,"RATOC SYSTEMS INC"},
+ {0x119A ,"MINDSHARE, INC."},
+ {0x119D ,"BUG, INC."},
+ {0x119E ,"FUJITSU MICROELECTRONICS LTD."},
+ {0x119F ,"BULL HN INFORMATION SYSTEMS"},
+ {0x11A1 ,"HAMAMATSU PHOTONICS K.K."},
+ {0x11A9 ,"INNOSYS"},
+ {0x11AA ,"ACTEL"},
+ {0x11AB ,"GALILEO TECHNOLOGY LTD."},
+ {0x11AD ,"LITE-ON COMMUNICATIONS INC"},
+ {0x11AE ,"SCITEX CORPORATION"},
+ {0x11AF ,"AVID TECHNOLOGY INC"},
+ {0x11B0 ,"V3 SEMICONDUCTOR INC."},
+ {0x11B2 ,"EASTMAN KODAK"},
+ {0x11B3 ,"BARR SYSTEMS INC."},
+ {0x11BF ,"ASTRODESIGN, INC."},
+ {0x11C6 ,"DAINIPPON SCREEN MFG. CO. LTD"},
+ {0x11C8 ,"DOLPHIN INTERCONNECT SOLUTIONS AS"},
+ {0x11C9 ,"MAGMA"},
+ {0x11CA ,"LSI SYSTEMS, INC"},
+ {0x11CB ,"SPECIALIX INTERNATIONAL LTD"},
+ {0x11CE ,"NETACCESS"},
+ {0x11D0 ,"LOCKHEED MARTIN - ELECTRONISS & COMMUNICATIONS"},
+ {0x11D1 ,"AURAVISION"},
+ {0x11D2 ,"INTERCOM INC."},
+ {0x11D4 ,"ANALOG DEVICES"},
+ {0x11D5 ,"IKON CORPORATION"},
+ {0x11D9 ,"TOSHIBA TEC CORPORATION"},
+ {0x11DA ,"NOVELL"},
+ {0x11DF ,"NEW WAVE PDG"},
+ {0x11E3 ,"QUICKLOGIC CORPORATION"},
+ {0x11EC ,"CORECO INC"},
+ {0x11EE ,"DOME IMAGING SYSTEMS INC"},
+ {0x11F8 ,"PMC-SIERRA INC"},
+ {0x1203 ,"AGFA CORPORATION"},
+ {0x1206 ,"AMDAHL CORPORATION"},
+ {0x120F ,"ESSENTIAL COMMUNICATIONS"},
+ {0x1214 ,"PERFORMANCE TECHNOLOGIES, INC."},
+ {0x1216 ,"PURUP - ESKOFOT A/S"},
+ {0x1217 ,"O2MICRO, INC."},
+ {0x121A ,"3DFX INTERACTIVE, INC."},
+ {0x121B ,"VIRATA LTD"},
+ {0x1221 ,"CONTEC CO., LTD"},
+ {0x1223 ,"ARTESYN COMMUNICATIONS PRODUCTS INC"},
+ {0x1227 ,"TECH-SOURCE"},
+ {0x122C ,"SICAN GMBH"},
+ {0x1232 ,"MARCONI COMMUNICATIONS LTD"},
+ {0x123C ,"CENTURY SYSTEMS, INC."},
+ {0x123D ,"ENGINEERING DESIGN TEAM, INC."},
+ {0x123F ,"C-CUBE MICROSYSTEMS"},
+ {0x1242 ,"JAYCOR NETWORKS INC."},
+ {0x1244 ,"AVM AUDIOVISUELLES MKTG & COMPUTER SYSTEM GMBH"},
+ {0x124B ,"SBS TECHNOLOGIES"},
+ {0x1250 ,"HITACHI ULSI SYSTEMS CO LTD"},
+ {0x1253 ,"GUZIK TECHNICAL ENTERPRISES"},
+ {0x1255 ,"OPTIBASE LTD"},
+ {0x1259 ,"ALLIED TELESYN INTERNATIONAL"},
+ {0x125C ,"AURORA TECHNOLOGIES, INC."},
+ {0x125F ,"CONCURRENT TECHNOLOGIES"},
+ {0x1260 ,"INTERSIL CORP"},
+ {0x1261 ,"MATSUSHITA-KOTOBUKI ELECTRONICS INDUSTRIES, LTD."},
+ {0x1264 ,"AVAL NAGASAKI CORPORATION"},
+ {0x1268 ,"TEKTRONIX"},
+ {0x126C ,"NORTEL NETWORKS"},
+ {0x126D ,"SPLASH TECHNOLOGY, INC."},
+ {0x126E ,"SUMITOMO METAL INDUSTRIES, LTD."},
+ {0x126F ,"SILICON MOTION, INC."},
+ {0x1270 ,"OLYMPUS OPTICAL CO., LTD."},
+ {0x1274 ,"CREATIVE LABS, INC. MALVERN"},
+ {0x1275 ,"NETWORK APPLIANCE CORPORATION"},
+ {0x1278 ,"TRANSTECH DSP LTD"},
+ {0x1279 ,"TRANSMETA CORPORATION"},
+ {0x127D ,"VELA RESEARCH LP"},
+ {0x127F ,"FUJIFILM"},
+ {0x1281 ,"YOKOGAWA ELECTRIC CORPORATION"},
+ {0x1283 ,"INTEGRATED TECHNOLOGY EXPRESS, INC."},
+ {0x1286 ,"MAZET GMBH"},
+ {0x128B ,"TRANSWITCH CORPORATION"},
+ {0x128D ,"G2 NETWORKS, INC."},
+ {0x128F ,"TATENO DENNOU, INC."},
+ {0x1290 ,"TOSHIBA PERSONAL COMPUTER SYSTEM CORP."},
+ {0x1291 ,"NCS COMPUTER ITALIA SRL"},
+ {0x1292 ,"TRITECH MICROELECTRONICS INC"},
+ {0x1297 ,"SHUTTLE COMPUTER"},
+ {0x1299 ,"KNOWLEDGE TECHNOLOGY LAB."},
+ {0x129A ,"VMETRO, INC."},
+ {0x129E ,"VICTOR COMPANY OF JAPAN, LTD."},
+ {0x12A0 ,"ALLEN- BRADLEY COMPANY"},
+ {0x12A3 ,"LUCENT TECHNOLOGIES"},
+ {0x12A7 ,"AMO GMBH"},
+ {0x12A9 ,"XIOTECH CORPORATION"},
+ {0x12AB ,"YUAN YUAN ENTERPRISE CO., LTD."},
+ {0x12AE ,"ALTEON WEBSYSTEMS INC"},
+ {0x12B6 ,"NATURAL MICROSYSTEMS"},
+ {0x12B7 ,"COGNEX MODULAR VISION SYSTEMS DIV. - ACUMEN INC."},
+ {0x12B9 ,"3COM CORP."},
+ {0x12BC ,"ARRAY MICROSYSTEMS"},
+ {0x12BE ,"ANCHOR CHIPS INC."},
+ {0x12BF ,"FUJIFILM MICRODEVICES"},
+ {0x12C0 ,"INFIMED"},
+ {0x12C3 ,"HOLTEK SEMICONDUCTOR INC"},
+ {0x12C4 ,"CONNECT TECH INC"},
+ {0x12C6 ,"MITAN CORPORATION"},
+ {0x12C7 ,"DIALOGIC CORP"},
+ {0x12CA ,"INTEGRATED COMPUTING ENGINES"},
+ {0x12CD ,"AIMS LAB"},
+ {0x12D3 ,"GE VINGMED ULTRASOUND AS"},
+ {0x12D4 ,"COMVERSE NETWORKS SYSTEM & ULTICOM, INC."},
+ {0x12D5 ,"EQUATOR TECHNOLOGIES"},
+ {0x12D6 ,"ANALOGIC CORP"},
+ {0x12D8 ,"PERICOM SEMICONDUCTOR"},
+ {0x12D9 ,"ACULAB PLC"},
+ {0x12DA ,"TRUE TIME INC."},
+ {0x12DE ,"RAINBOW TECHNOLOGIES"},
+ {0x12DF ,"SBS TECHNOLOGIES INC"},
+ {0x12E0 ,"CHASE RESEARCH"},
+ {0x12E2 ,"DATUM INC. BANCOMM-TIMING DIVISION"},
+ {0x12E4 ,"BROOKTROUT TECHNOLOGY INC"},
+ {0x12E7 ,"SEBRING SYSTEMS, INC"},
+ {0x12EA ,"REAL VISION, INC"},
+ {0x12EB ,"AUREAL INC."},
+ {0x12EC ,"3A INTERNATIONAL, INC."},
+ {0x12F0 ,"PENTEK"},
+ {0x12F7 ,"COGNEX INC."},
+ {0x12FB ,"SPECTRUM SIGNAL PROCESSING"},
+ {0x12FC ,"CAPITAL EQUIPMENT CORP"},
+ {0x12FE ,"ESD ELECTRONIC SYSTEM DESIGN GMBH"},
+ {0x1304 ,"JUNIPER NETWORKS INC."},
+ {0x1307 ,"COMPUTER BOARDS"},
+ {0x1308 ,"LEVEL ONE COMMUNICATIONS INC"},
+ {0x130A ,"MITSUBISHI ELECTRIC MICROCOMPUTER"},
+ {0x130B ,"COLORGRAPHIC COMMUNICATIONS CORP"},
+ {0x130F ,"ADVANET INC"},
+ {0x1310 ,"GESPAC"},
+ {0x1313 ,"YASKAWA ELECTRIC CO."},
+ {0x1316 ,"TERADYNE INC."},
+ {0x1317 ,"ADMTEK INC"},
+ {0x1318 ,"PACKET ENGINES INC."},
+ {0x1319 ,"FORTEMEDIA, INC"},
+ {0x131F ,"SIIG INC"},
+ {0x1325 ,"SALIX TECHNOLOGIES INC"},
+ {0x1326 ,"SEACHANGE INTERNATIONAL"},
+ {0x1331 ,"RADISYS CORP."},
+ {0x133D ,"PRISA NETWORKS"},
+ {0x133F ,"SCM MICROSYSTEMS"},
+ {0x1342 ,"PROMAX SYSTEMS INC"},
+ {0x1344 ,"MICRON TECHNOLOGY INC"},
+ {0x134B ,"ARK RESEARCH CORP."},
+ {0x134C ,"CHORI JOHO SYSTEM CO. LTD"},
+ {0x134D ,"PC-TEL INC"},
+ {0x135A ,"BRAIN BOXES LIMITED"},
+ {0x135C ,"QUATECH INC"},
+ {0x135E ,"SEALEVEL SYSTEMS INC"},
+ {0x135F ,"I-DATA INTERNATIONAL A-S"},
+ {0x1360 ,"MEINBERG FUNKUHREN"},
+ {0x1361 ,"SOLITON SYSTEMS K.K."},
+ {0x1363 ,"PHOENIX TECHNOLOGIES LTD"},
+ {0x1367 ,"HITACHI ZOSEN CORPORATION"},
+ {0x1368 ,"SKYWARE CORPORATION"},
+ {0x1369 ,"DIGIGRAM"},
+ {0x136B ,"KAWASAKI STEEL CORPORATION"},
+ {0x136C ,"ADTEK SYSTEM SCIENCE CO LTD"},
+ {0x1375 ,"BOEING - SUNNYVALE"},
+ {0x1377 ,"ELECTRONIC EQUIPMENT PRODUUTION & DISTRIBUTION GMBH"},
+ {0x137A ,"MARK OF THE UNICORN INC"},
+ {0x137B ,"PPT VISION"},
+ {0x137C ,"IWATSU ELECTRIC CO LTD"},
+ {0x137D ,"DYNACHIP CORPORATION"},
+ {0x1380 ,"SANRITZ AUTOMATION CO LTC"},
+ {0x1381 ,"BRAINS CO. LTD"},
+ {0x1383 ,"CONTROLNET INC"},
+ {0x1384 ,"STELLAR SEMICONDUCTOR INC"},
+ {0x1385 ,"NETGEAR"},
+ {0x1387 ,"SYSTRAN CORP"},
+ {0x1388 ,"HITACHI INFORMATION TECHNOLOGY CO LTD"},
+ {0x1389 ,"APPLICOM INTERNATIONAL"},
+ {0x138A ,"SITERA"},
+ {0x138B ,"TOKIMEC INC"},
+ {0x138E ,"BASLER GMBH"},
+ {0x138F ,"PATAPSCO DESIGNS INC"},
+ {0x1393 ,"MOXA TECHNOLOGIES CO LTD"},
+ {0x1394 ,"LEVEL ONE COMMUNICATIONS"},
+ {0x1395 ,"AMBICOM INC"},
+ {0x1396 ,"CIPHER SYSTEMS INC"},
+ {0x1397 ,"COLOGNE CHIP DESIGNS GMBH"},
+ {0x1398 ,"CLARION CO. LTD"},
+ {0x1399 ,"RIOS SYSTEMS CO LTD"},
+ {0x139A ,"ALACRITECH INC"},
+ {0x139C ,"QUANTUM 3D INC"},
+ {0x139D ,"XSTREAMS PLC/ EPL LIMITED"},
+ {0x139E ,"ECHOSTAR DATA NETWORKS"},
+ {0x139F ,"AETHRA S.R.L."},
+ {0x13A0 ,"CRYSTAL GROUP INC"},
+ {0x13A1 ,"KAWASAKI HEAVY INDUSTRIES LTD"},
+ {0x13A2 ,"OSITECH COMMUNICATIONS INC"},
+ {0x13A4 ,"RASCOM INC"},
+ {0x13A7 ,"TELES AG"},
+ {0x13A8 ,"EXAR CORP."},
+ {0x13A9 ,"SIEMENS MEDICAL SYSTEMS, ULTRASOUND GROUP"},
+ {0x13AA ,"NORTEL NETWORKS - BWA DIVISION"},
+ {0x13AF ,"T.SQWARE"},
+ {0x13B1 ,"TAMURA CORPORATION"},
+ {0x13B4 ,"WELLBEAN CO INC"},
+ {0x13B5 ,"ARM LTD"},
+ {0x13B6 ,"DLOG GMBH"},
+ {0x13B8 ,"NOKIA TELECOMMUNICATIONS OY"},
+ {0x13BD ,"SHARP CORPORATION"},
+ {0x13BF ,"SHAREWAVE INC"},
+ {0x13C1 ,"3WARE INC"},
+ {0x13C2 ,"TECHNOTREND SYSTEMTECHNIK GMBH"},
+ {0x13C3 ,"JANZ COMPUTER AG"},
+ {0x13C6 ,"CONDOR ENGINEERING INC"},
+ {0x13C7 ,"BLUE CHIP TECHNOLOGY LTD"},
+ {0x13CA ,"IOMEGA CORPORATION"},
+ {0x13CC ,"METHEUS CORPORATION"},
+ {0x13CF ,"STUDIO AUDIO & VIDEO LTD"},
+ {0x13D0 ,"B2C2, INC"},
+ {0x13D1 ,"ABOCOM SYSTEMS INC"},
+ {0x13D2 ,"SHARK MULTIMEDIA INC"},
+ {0x13D3 ,"IMC NETWORKS"},
+ {0x13D4 ,"GRAPHICS MICROSYSTEMS INC"},
+ {0x13D6 ,"K.I. TECHNOLOGY CO LTD"},
+ {0x13D7 ,"TOSHIBA ENGINEERING CORPORATION"},
+ {0x13D8 ,"PHOBOS CORPORATION"},
+ {0x13D9 ,"APEX INC"},
+ {0x13DC ,"NETBOOST CORPORATION"},
+ {0x13DE ,"ABB ROBOTICS PRODUCTS AB"},
+ {0x13DF ,"E-TECH INC"},
+ {0x13E0 ,"GVC CORPORATION"},
+ {0x13E3 ,"NEST INC"},
+ {0x13E4 ,"CALCULEX INC"},
+ {0x13E5 ,"TELESOFT DESIGN LTD"},
+ {0x13E9 ,"INTRASERVER TECHNOLOGY INC"},
+ {0x13EA ,"DALLAS SEMICONDUCTOR"},
+ {0x13F0 ,"SUNDANCE TECHNOLOGY INC"},
+ {0x13F1 ,"OCE' - TECHNOLOGIES B.V."},
+ {0x13F2 ,"FORD MICROELECTRONICS INC"},
+ {0x13F4 ,"TROIKA NETWORKS INC"},
+ {0x13F6 ,"C-MEDIA ELECTRONICS INC"},
+ {0x13F9 ,"NTT ADVANCED TECHNOLOGY CORP."},
+ {0x13FB ,"AYDIN CORP"},
+ {0x13FD ,"MICRO SCIENCE INC"},
+ {0x1400 ,"ARTX INC"},
+ {0x1402 ,"MEILHAUS ELECTRONIC GMBH"},
+ {0x1404 ,"FUNDAMENTAL SOFTWARE INC"},
+ {0x1406 ,"OCE' PRINTING SYSTEMS GMBH"},
+ {0x1407 ,"LAVA COMPUTER MFG INC"},
+ {0x1408 ,"ALOKA CO. LTD"},
+ {0x140A ,"DSP RESEARCH INC"},
+ {0x140B ,"RAMIX INC"},
+ {0x140D ,"MATSUSHITA ELECTRIC WORKS LTD"},
+ {0x1413 ,"ADDONICS"},
+ {0x1415 ,"OXFORD SEMICONDUCTOR LTD"},
+ {0x1418 ,"KYUSHU ELECTRONICS SYSTEMS INC"},
+ {0x1419 ,"EXCEL SWITCHING CORP"},
+ {0x141B ,"ZOOM TELEPHONICS INC"},
+ {0x141E ,"FANUC LTD"},
+ {0x1420 ,"PSION DACOM PLC"},
+ {0x1428 ,"EDEC CO LTD"},
+ {0x1429 ,"UNEX TECHNOLOGY CORP."},
+ {0x142A ,"KINGMAX TECHNOLOGY INC"},
+ {0x142B ,"RADIOLAN"},
+ {0x142C ,"MINTON OPTIC INDUSTRY CO LTD"},
+ {0x142D ,"PIXSTREAM INC"},
+ {0x1430 ,"ITT AEROSPACE/COMMUNICATIONS DIVISION"},
+ {0x1433 ,"ELTEC ELEKTRONIK GMBH"},
+ {0x1436 ,"CIS TECHNOLOGY INC"},
+ {0x1437 ,"NISSIN INC CO"},
+ {0x1438 ,"ATMEL-DREAM"},
+ {0x143F ,"LIGHTWELL CO LTD - ZAX DIVISION"},
+ {0x1441 ,"AGIE SA."},
+ {0x1445 ,"LOGICAL CO LTD"},
+ {0x1446 ,"GRAPHIN CO. LTD"},
+ {0x1447 ,"AIM GMBH"},
+ {0x144A ,"ADLINK TECHNOLOGY"},
+ {0x144B ,"LORONIX INFORMATION SYSTEMS INC"},
+ {0x144D ,"SAMSUNG ELECTRONICS CO LTD"},
+ {0x1450 ,"OCTAVE COMMUNICATIONS IND."},
+ {0x1451 ,"SP3D CHIP DESIGN GMBH"},
+ {0x1453 ,"MYCOM INC"},
+ {0x1455 ,"LOGIC PLUS PLUS INC"},
+ {0x1458 ,"GIGA-BYTE TECHNOLOGY"},
+ {0x145C ,"CRYPTEK"},
+ {0x145F ,"BALDOR ELECTRIC COMPANY"},
+ {0x1460 ,"DYNARC INC"},
+ {0x1462 ,"MICRO-STAR INTERNATIONAL CO LTD"},
+ {0x1463 ,"FAST CORPORATION"},
+ {0x1464 ,"INTERACTIVE CIRCUITS & SYSTEMS LTD"},
+ {0x1465 ,"GN NETTEST TELECOM DIV."},
+ {0x1468 ,"AMBIT MICROSYSTEMS CORP."},
+ {0x1469 ,"CLEVELAND MOTION CONTROLS"},
+ {0x146C ,"RUBY TECH CORP."},
+ {0x146D ,"TACHYON, INC."},
+ {0x146E ,"WILLIAMS ELECTRONICS GAMES, INC."},
+ {0x1471 ,"INTEGRATED TELECOM EXPRESS INC"},
+ {0x1473 ,"ZAPEX TECHNOLOGIES INC"},
+ {0x1474 ,"DOUG CARSON & ASSOCIATES"},
+ {0x1477 ,"NET INSIGHT"},
+ {0x1478 ,"DIATREND CORPORATION"},
+ {0x147B ,"ABIT COMPUTER CORP."},
+ {0x147F ,"NIHON UNISYS, LTD."},
+ {0x1482 ,"ISYTEC - INTEGRIERTE SYSTEMTECHNIK GMBH"},
+ {0x1483 ,"LABWAY COPORATION"},
+ {0x1485 ,"ERMA - ELECTRONIC GMBH"},
+ {0x1489 ,"KYE SYSTEMS CORPORATION"},
+ {0x148A ,"OPTO 22"},
+ {0x148B ,"INNOMEDIALOGIC INC."},
+ {0x148E ,"OSI PLUS CORPORATION"},
+ {0x148F ,"PLANT EQUIPMENT, INC."},
+ {0x1490 ,"TC LABS PTY LTD."},
+ {0x1493 ,"MAKER COMMUNICATIONS"},
+ {0x1495 ,"TOKAI COMMUNICATIONS INDUSTRY CO. LTD"},
+ {0x1496 ,"JOYTECH COMPUTER CO., LTD."},
+ {0x1497 ,"SMA REGELSYSTEME GMBH"},
+ {0x1499 ,"EMTEC CO., LTD"},
+ {0x149A ,"ANDOR TECHNOLOGY LTD"},
+ {0x149B ,"SEIKO INSTRUMENTS INC"},
+ {0x149C ,"OVISLINK CORP."},
+ {0x149D ,"NEWTEK INC"},
+ {0x149E ,"MAPLETREE NETWORKS INC."},
+ {0x149F ,"LECTRON CO LTD"},
+ {0x14A0 ,"SOFTING GMBH"},
+ {0x14A1 ,"SYSTEMBASE CO LTD"},
+ {0x14A2 ,"MILLENNIUM ENGINEERING INC"},
+ {0x14A3 ,"MAVERICK NETWORKS"},
+ {0x14A4 ,"GVC/BCM ADVANCED RESEARCH"},
+ {0x14A5 ,"XIONICS DOCUMENT TECHNOLOGIES INC."},
+ {0x14A6 ,"INOVA COMPUTERS GMBH & CO KG"},
+ {0x14A8 ,"FEATRON TECHNOLOGIES CORPORATION"},
+ {0x14A9 ,"HIVERTEC INC."},
+ {0x14AB ,"MENTOR GRAPHICS CORP."},
+ {0x14AC ,"NOVAWEB TECHNOLOGIES INC"},
+ {0x14AD ,"TIME SPACE RADIO AB"},
+ {0x14AE ,"CTI PET SYSTEMS, INC"},
+ {0x14AF ,"GUILLEMOT CORPORATION"},
+ {0x14B0 ,"BST COMMUNICATION TECHNOLOGY LTD"},
+ {0x14B1 ,"NEXTCOM K.K."},
+ {0x14B2 ,"ENNOVATE NETWORKS INC"},
+ {0x14B3 ,"XPEED INC."},
+ {0x14B4 ,"PHILIPS BUSINESS ELECTRONICS B.V."},
+ {0x14B5 ,"CREAMWARE GMBH"},
+ {0x14B6 ,"QUANTUM DATA CORP."},
+ {0x14B7 ,"PROXIM INC"},
+ {0x14B8 ,"TECHSOFT TECHNOLOGY CO LTD"},
+ {0x14B9 ,"AIRONET WIRELESS COMMUNICATIONS"},
+ {0x14BA ,"INTERNIX INC."},
+ {0x14BB ,"SEMTECH CORPORATION"},
+ {0x14BC ,"GLOBESPAN SEMICONDUCTOR INC."},
+ {0x14BD ,"CARDIO CONTROL N.V."},
+ {0x14BE ,"L3 COMMUNICATIONS"},
+ {0x14BF ,"SPIDER COMMUNICATIONS INC."},
+ {0x14C0 ,"COMPAL ELECTRONICS INC"},
+ {0x14C1 ,"MYRICOM INC."},
+ {0x14C2 ,"DTK COMPUTER"},
+ {0x14C3 ,"MEDIATEK CORP."},
+ {0x14C4 ,"IWASAKI INFORMATION SYSTEMS CO LTD"},
+ {0x14C5 ,"ABB AUTOMATION PRODUCTS AB"},
+ {0x14C6 ,"DATA RACE INC"},
+ {0x14C7 ,"MODULAR TECHNOLOY HOLDINGS LTD"},
+ {0x14C8 ,"TURBOCOMM TECH. INC."},
+ {0x14C9 ,"ODIN TELESYSTEMS INC"},
+ {0x14CA ,"PE LOGIC CORP."},
+ {0x14CB ,"BILLIONTON SYSTEMS INC./CADMUS MICRO INC."},
+ {0x14CC ,"NAKAYO TELECOMMUNICATIONS INC"},
+ {0x14CD ,"UNIVERSAL SCIENTIFIC IND."},
+ {0x14CE ,"WHISTLE COMMUNICATIONS"},
+ {0x14CF ,"TEK MICROSYSTEMS INC."},
+ {0x14D0 ,"ERICSSON AXE R & D"},
+ {0x14D1 ,"COMPUTER HI-TECH CO LTD"},
+ {0x14D2 ,"TITAN ELECTRONICS INC"},
+ {0x14D3 ,"CIRTECH (UK) LTD"},
+ {0x14D4 ,"PANACOM TECHNOLOGY CORP"},
+ {0x14D5 ,"NITSUKO CORPORATION"},
+ {0x14D6 ,"ACCUSYS INC"},
+ {0x14D7 ,"HIRAKAWA HEWTECH CORP"},
+ {0x14D8 ,"HOPF ELEKTRONIK GMBH"},
+ {0x14D9 ,"ALPHA PROCESSOR INC"},
+ {0x14DA ,"NATIONAL AEROSPACE LABORATORIES"},
+ {0x14DB ,"AVLAB TECHNOLOGY INC"},
+ {0x14DC ,"AMPLICON LIVELINE LTD"},
+ {0x14DD ,"IMODL INC."},
+ {0x14DE ,"APPLIED INTEGRATION CORPORATION"},
+ {0x14DF ,"BASIS COMMUNICATIONS CORP"},
+ {0x14E1 ,"INVERTEX"},
+ {0x14E2 ,"INFOLIBRIA"},
+ {0x14E3 ,"AMTELCO"},
+ {0x14E4 ,"BROADCOM CORPORATION"},
+ {0x14E5 ,"PIXELFUSION LTD"},
+ {0x14E6 ,"SHINING TECHNOLOGY INC"},
+ {0x14E7 ,"3CX"},
+ {0x14E8 ,"RAYCER INC"},
+ {0x14E9 ,"GARNETS SYSTEM CO LTD"},
+ {0x14EA ,"PLANEX COMMUNICATIONS INC"},
+ {0x14EB ,"SEIKO EPSON CORPORATION"},
+ {0x14EC ,"ACQIRIS"},
+ {0x14ED ,"DATAKINETICS LTD"},
+ {0x14EE ,"MASPRO KENKOH CORP"},
+ {0x14EF ,"CARRY COMPUTER ENG. CO LTD"},
+ {0x14F0 ,"CANON RESEACH CENTRE FRANCE"},
+ {0x14F1 ,"CONEXANT"},
+ {0x14F2 ,"MOBILITY ELECTRONICS"},
+ {0x14F3 ,"BROADLOGIC"},
+ {0x14F4 ,"TOKYO ELECTRONIC INDUSTRY CO LTD"},
+ {0x14F5 ,"SOPAC LTD"},
+ {0x14F6 ,"COYOTE TECHNOLOGIES LLC"},
+ {0x14F7 ,"WOLF TECHNOLOGY INC"},
+ {0x14F8 ,"AUDIOCODES INC"},
+ {0x14F9 ,"AG COMMUNICATIONS"},
+ {0x14FA ,"WAVETEK WANDEL & GOLTERMANN"},
+ {0x14FB ,"TRANSAS MARINE (UK) LTD"},
+ {0x14FC ,"QUADRICS SUPERCOMPUTERS WORLD"},
+ {0x14FD ,"JAPAN COMPUTER INDUSTRY INC."},
+ {0x14FE ,"ARCHTEK TELECOM CORP."},
+ {0x14FF ,"TWINHEAD INTERNATIONAL CORP."},
+ {0x1500 ,"LANTECH COMPUTER COMPANY"},
+ {0x1501 ,"BANKSOFT CANADA LTD"},
+ {0x1502 ,"MITSUBISHI ELECTRIC LOGISTICS SUPPORT CO LTD"},
+ {0x1503 ,"KAWASAKI LSI USA INC"},
+ {0x1504 ,"KAISER ELECTRONICS"},
+ {0x1505 ,"ITA INGENIEURBURO FUR TESTAUFGABEN GMBH"},
+ {0x1506 ,"CHAMELEON SYSTEMS INC"},
+ {0x1507 ,"HTEC LTD"},
+ {0x1508 ,"HONDA CONNECTORS/MHOTRONICS INC"},
+ {0x1509 ,"FIRST INTERNATIONAL COMPUTER INC"},
+ {0x150A ,"FORVUS RESEARCH INC"},
+ {0x150B ,"YAMASHITA SYSTEMS CORP"},
+ {0x150C ,"KYOPAL CO LTD"},
+ {0x150D ,"WARPSPPED INC"},
+ {0x150E ,"C-PORT CORPORATION"},
+ {0x150F ,"INTEC GMBH"},
+ {0x1510 ,"BEHAVIOR TECH COMPUTER CORP"},
+ {0x1511 ,"CENTILLIUM TECHNOLOGY CORP"},
+ {0x1512 ,"ROSUN TECHNOLOGIES INC"},
+ {0x1513 ,"RAYCHEM"},
+ {0x1514 ,"TFL LAN INC"},
+ {0x1515 ,"ICS ADVENT"},
+ {0x1516 ,"MYSON TECHNOLOGY INC"},
+ {0x1517 ,"ECHOTEK CORPORATION"},
+ {0x1518 ,"PEP MODULAR COMPUTERS GMBH"},
+ {0x1519 ,"TELEFON AKTIEBOLAGET LM ERICSSON"},
+ {0x151A ,"GLOBETEK INC"},
+ {0x151B ,"COMBOX LTD"},
+ {0x151C ,"DIGITAL AUDIO LABS INC"},
+ {0x151D ,"FUJITSU COMPUTER PRODUCTS OF AMERICA"},
+ {0x151E ,"MATRIX CORP."},
+ {0x151F ,"TOPIC SEMICONDUCTOR CORP"},
+ {0x1520 ,"CHAPLET SYSTEM INC"},
+ {0x1521 ,"BELL CORPORATION"},
+ {0x1522 ,"MAINPINE LIMITED"},
+ {0x1523 ,"MUSIC SEMICONDUCTORS"},
+ {0x1524 ,"ENE TECHNOLOGY INC"},
+ {0x1525 ,"IMPACT TECHNOLOGIES"},
+ {0x1526 ,"ISS, INC"},
+ {0x1527 ,"SOLECTRON"},
+ {0x1528 ,"ACKSYS"},
+ {0x1529 ,"AMERICAN MICROSYSTEMS INC"},
+ {0x152A ,"QUICKTURN DESIGN SYSTEMS"},
+ {0x152B ,"FLYTECH TECHNOLOGY CO LTD"},
+ {0x152C ,"MACRAIGOR SYSTEMS LLC"},
+ {0x152D ,"QUANTA COMPUTER INC"},
+ {0x152E ,"MELEC INC"},
+ {0x152F ,"PHILIPS - CRYPTO"},
+ {0x1530 ,"ACQIS TECHNOLOGY INC"},
+ {0x1531 ,"CHRYON CORP."},
+ {0x1532 ,"ECHELON CORPORATION"},
+ {0x1533 ,"BALTIMORE"},
+ {0x1534 ,"ROAD CORPORATION"},
+ {0x1535 ,"EVERGREEN TECHNOLOGIES INC"},
+ {0x1537 ,"DATALEX COMMUNCATIONS"},
+ {0x1538 ,"ARALION INC."},
+ {0x1539 ,"ATELIER INFORMATIQUES ET ELECTRONIQUE ETUDES S.A."},
+ {0x153A ,"ONO SOKKI"},
+ {0x153B ,"TERRATEC ELECTRONIC GMBH"},
+ {0x153C ,"ANTAL ELECTRONIC"},
+ {0x153D ,"FILANET CORPORATION"},
+ {0x153E ,"TECHWELL INC"},
+ {0x153F ,"MIPS DENMARK"},
+ {0x1540 ,"PROVIDEO MULTIMEDIA CO LTD"},
+ {0x1541 ,"TELOSITY INC."},
+ {0x1542 ,"VIVID TECHNOLOGY INC"},
+ {0x1543 ,"SILICON LABORATORIES"},
+ {0x1544 ,"DCM DATA SYSTEMS"},
+ {0x1545 ,"VISIONTEK"},
+ {0x1546 ,"IOI TECHNOLOGY CORP."},
+ {0x1547 ,"MITUTOYO CORPORATION"},
+ {0x1548 ,"JET PROPULSION LABORATORY"},
+ {0x1549 ,"INTERCONNECT SYSTEMS SOLUTIONS"},
+ {0x154A ,"MAX TECHNOLOGIES INC."},
+ {0x154B ,"COMPUTEX CO LTD"},
+ {0x154C ,"VISUAL TECHNOLOGY INC."},
+ {0x154D ,"PAN INTERNATIONAL INDUSTRIAL CORP"},
+ {0x154E ,"SERVOTEST LTD"},
+ {0x154F ,"STRATABEAM TECHNOLOGY"},
+ {0x1550 ,"OPEN NETWORK CO LTD"},
+ {0x1551 ,"SMART ELECTRONIC DEVELOPMENT GMBH"},
+ {0x1552 ,"RACAL AIRTECH LTD"},
+ {0x1553 ,"CHICONY ELECTRONICS CO LTD"},
+ {0x1554 ,"PROLINK MICROSYSTEMS CORP."},
+ {0x1555 ,"GESYTEC GMBH"},
+ {0x1556 ,"PLD APPLICATIONS"},
+ {0x1557 ,"MEDIASTAR CO. LTD"},
+ {0x1558 ,"CLEVO/KAPOK COMPUTER"},
+ {0x1559 ,"SI LOGIC LTD"},
+ {0x155A ,"INNOMEDIA INC"},
+ {0x155B ,"PROTAC INTERNATIONAL CORP"},
+ {0x155C ,"CEMAX-ICON INC"},
+ {0x155D ,"MAC SYSTEM CO LTD"},
+ {0x155E ,"LP ELEKTRONIK GMBH"},
+ {0x155F ,"PERLE SYSTEMS LIMITED"},
+ {0x1560 ,"TERAYON COMMUNICATIONS SYSTEMS"},
+ {0x1561 ,"VIEWGRAPHICS INC"},
+ {0x1562 ,"SYMBOL TECHNOLOGIES"},
+ {0x1563 ,"A-TREND TECHNOLOGY CO LTD"},
+ {0x1564 ,"YAMAKATSU ELECTRONICS INDUSTRY CO LTD"},
+ {0x1565 ,"BIOSTAR MICROTECH INT'L CORP"},
+ {0x1566 ,"ARDENT TECHNOLOGIES INC"},
+ {0x1567 ,"JUNGSOFT"},
+ {0x1568 ,"DDK ELECTRONICS INC"},
+ {0x1569 ,"PALIT MICROSYSTEMS INC"},
+ {0x156A ,"AVTEC SYSTEMS"},
+ {0x156B ,"2WIRE, INC"},
+ {0x156C ,"VIDAC ELECTRONICS GMBH"},
+ {0x156D ,"ALPHA-TOP CORP"},
+ {0x156E ,"ALFA INC."},
+ {0x156F ,"M-SYSTEMS FLASH DISK PIONEERS LTD"},
+ {0x1570 ,"LECROY CORPORATION"},
+ {0x1571 ,"CONTEMPORARY CONTROLS"},
+ {0x1572 ,"OTIS ELEVATOR COMPANY"},
+ {0x1573 ,"LATTICE - VANTIS"},
+ {0x1574 ,"FAIRCHILD SEMICONDUCTOR"},
+ {0x1575 ,"VOLTAIRE ADVANCED DATA SECURITY LTD"},
+ {0x1576 ,"VIEWCAST COM"},
+ {0x1578 ,"HITT"},
+ {0x1579 ,"DUAL TECHNOLOGY CORPORATION"},
+ {0x157A ,"JAPAN ELECRONICS IND. INC"},
+ {0x157B ,"STAR MULTIMEDIA CORP."},
+ {0x157C ,"EUROSOFT (UK) LTD"},
+ {0x157D ,"GEMFLEX NETWORKS"},
+ {0x157E ,"TRANSITION NETWORKS"},
+ {0x157F ,"PX INSTRUMENTS TECHNOLOGY LTD"},
+ {0x1580 ,"PRIMEX AEROSPACE CO."},
+ {0x1581 ,"SEH COMPUTERTECHNIK GMBH"},
+ {0x1582 ,"CYTEC CORPORATION"},
+ {0x1583 ,"INET TECHNOLOGIES INC"},
+ {0x1584 ,"UNIWILL COMPUTER CORP."},
+ {0x1585 ,"LOGITRON"},
+ {0x1586 ,"LANCAST INC"},
+ {0x1587 ,"KONICA CORPORATION"},
+ {0x1588 ,"SOLIDUM SYSTEMS CORP"},
+ {0x1589 ,"ATLANTEK MICROSYSTEMS PTY LTD"},
+ {0x158A ,"DIGALOG SYSTEMS INC"},
+ {0x158B ,"ALLIED DATA TECHNOLOGIES"},
+ {0x158C ,"HITACHI SEMICONDUCTOR & DEVICES SALES CO LTD"},
+ {0x158D ,"POINT MULTIMEDIA SYSTEMS"},
+ {0x158E ,"LARA TECHNOLOGY INC"},
+ {0x158F ,"DITECT COOP"},
+ {0x1590 ,"3PARDATA INC."},
+ {0x1591 ,"ARN"},
+ {0x1592 ,"SYBA TECH LIMITED"},
+ {0x1593 ,"BOPS INC"},
+ {0x1594 ,"NETGAME LTD"},
+ {0x1595 ,"DIVA SYSTEMS CORP."},
+ {0x1596 ,"FOLSOM RESEARCH INC"},
+ {0x1597 ,"MEMEC DESIGN SERVICES"},
+ {0x1598 ,"GRANITE MICROSYSTEMS"},
+ {0x1599 ,"DELTA ELECTRONICS INC"},
+ {0x159A ,"GENERAL INSTRUMENT"},
+ {0x159B ,"FARADAY TECHNOLOGY CORP"},
+ {0x159C ,"STRATUS COMPUTER SYSTEMS"},
+ {0x159D ,"NINGBO HARRISON ELECTRONICS CO LTD"},
+ {0x159E ,"A-MAX TECHNOLOGY CO LTD"},
+ {0x159F ,"GALEA NETWORK SECURITY"},
+ {0x15A0 ,"COMPUMASTER SRL"},
+ {0x15A1 ,"GEOCAST NETWORK SYSTEMS INC"},
+ {0x15A2 ,"CATALYST ENTERPRISES INC"},
+ {0x15A3 ,"ITALTEL"},
+ {0x15A4 ,"X-NET OY"},
+ {0x15A5 ,"TOYOTA MACS INC"},
+ {0x15A6 ,"SUNLIGHT ULTRASOUND TECHNOLOGIES LTD"},
+ {0x15A7 ,"SSE TELECOM INC"},
+ {0x15A8 ,"SHANGHAI COMMUNICATIONS TECHNOLOGIES CENTER"},
+ {0x15AA ,"MORETON BAY"},
+ {0x15AB ,"BLUESTEEL NETWORKS INC"},
+ {0x15AC ,"NORTH ATLANTIC INSTRUMENTS"},
+ {0x15AD ,"VMWARE"},
+ {0x15AE ,"AMERSHAM PHARMACIA BIOTECH"},
+ {0x15B0 ,"ZOLTRIX INTERNATIONAL LIMITED"},
+ {0x15B1 ,"SOURCE TECHNOLOGY INC"},
+ {0x15B2 ,"MOSAID TECHNOLOGIES INC."},
+ {0x15B3 ,"MELLANOX TECHNOLOGY"},
+ {0x15B4 ,"CCI/TRIAD"},
+ {0x15B5 ,"CIMETRICS INC"},
+ {0x15B6 ,"TEXAS MEMORY SYSTEMS INC"},
+ {0x15B7 ,"SANDISK CORP."},
+ {0x15B8 ,"ADDI-DATA GMBH"},
+ {0x15B9 ,"MAESTRO DIGITAL COMMUNICATIONS"},
+ {0x15BA ,"IMPACCT TECHNOLOGY CORP"},
+ {0x15BB ,"PORTWELL INC"},
+ {0x15BC ,"AGILENT TECHNOLOGIES"},
+ {0x15BD ,"DFI INC."},
+ {0x15BE ,"SOLA ELECTRONICS"},
+ {0x15BF ,"HIGH TECH COMPUTER CORP (HTC)"},
+ {0x15C0 ,"BVM LIMITED"},
+ {0x15C1 ,"QUANTEL"},
+ {0x15C2 ,"NEWER TECHNOLOGY INC"},
+ {0x15C3 ,"TAIWAN MYCOMP CO LTD"},
+ {0x15C4 ,"EVSX, INC"},
+ {0x15C5 ,"PROCOMP INFORMATICS LTD"},
+ {0x15C6 ,"TECHNICAL UNIVERSITY OF BUDAPEST"},
+ {0x15C7 ,"TATEYAMA SYSTEM LABORATORY CO LTD"},
+ {0x15C8 ,"PENTA MEDIA CO. LTD"},
+ {0x15C9 ,"SEROME TECHNOLOGY INC"},
+ {0x15CA ,"BITBOYS OY"},
+ {0x15CB ,"AG ELECTRONICS LTD"},
+ {0x15CC ,"HOTRAIL INC."},
+ {0x15CD ,"DREAMTECH CO LTD"},
+ {0x15CE ,"GENRAD INC."},
+ {0x15CF ,"HILSCHER GMBH"},
+ {0x15D1 ,"INFINEON TECHNOLOGIES AG"},
+ {0x15D2 ,"FIC (FIRST INTERNATIONAL COMPUTER INC)"},
+ {0x15D3 ,"NDS TECHNOLOGIES ISRAEL LTD"},
+ {0x15D4 ,"IWILL CORPORATION"},
+ {0x15D5 ,"TATUNG CO."},
+ {0x15D6 ,"ENTRIDIA CORPORATION"},
+ {0x15D7 ,"ROCKWELL-COLLINS, INC"},
+ {0x15D8 ,"CYBERNETICS TECHNOLOGY CO LTD"},
+ {0x15D9 ,"SUPER MICRO COMPUTER INC"},
+ {0x15DA ,"CYBERFIRM INC."},
+ {0x15DB ,"APPLIED COMPUTING SYSTEMS INC."},
+ {0x15DC ,"LITRONIC INC"},
+ {0x15DD ,"SIGMATEL INC."},
+ {0x15DE ,"MALLEABLE TECHNOLOGIES INC"},
+ {0x15DF ,"INFINILINK CORP."},
+ {0x15E0 ,"CACHEFLOW INC"},
+ {0x15E1 ,"VOICE TECHNOLOGIES GROUP INC."},
+ {0x15E2 ,"QUICKNET TECHNOLOGIES INC"},
+ {0x15E3 ,"NETWORTH TECHNOLOGIES INC"},
+ {0x15E4 ,"VSN SYSTEMEN BV"},
+ {0x15E5 ,"VALLEY TECHNOLOGIES INC"},
+ {0x15E6 ,"AGERE INC."},
+ {0x15E7 ,"GET ENGINEERING CORP."},
+ {0x15E8 ,"NATIONAL DATACOMM CORP."},
+ {0x15E9 ,"PACIFIC DIGITAL CORP."},
+ {0x15EA ,"TOKYO DENSHI SEKEI K.K."},
+ {0x15EB ,"DRSEARCH GMBH"},
+ {0x15EC ,"BECKHOFF GMBH"},
+ {0x15ED ,"MACROLINK INC"},
+ {0x15EE ,"IN WIN DEVELOPMENT INC."},
+ {0x15EF ,"INTELLIGENT PARADIGM INC"},
+ {0x15F0 ,"B-TREE SYSTEMS INC"},
+ {0x15F1 ,"TIMES N SYSTEMS INC"},
+ {0x15F2 ,"DIAGNOSTIC INSTRUMENTS INC"},
+ {0x15F3 ,"DIGITMEDIA CORP."},
+ {0x15F4 ,"VALUESOFT"},
+ {0x15F5 ,"POWER MICRO RESEARCH"},
+ {0x15F6 ,"EXTREME PACKET DEVICE INC"},
+ {0x15F7 ,"BANCTEC"},
+ {0x15F8 ,"KOGA ELECTRONICS CO"},
+ {0x15F9 ,"ZENITH ELECTRONICS CORPORATION"},
+ {0x15FA ,"J.P. AXZAM CORPORATION"},
+ {0x15FB ,"ZILOG INC."},
+ {0x15FC ,"TECHSAN ELECTRONICS CO LTD"},
+ {0x15FD ,"N-CUBED.NET"},
+ {0x15FE ,"KINPO ELECTRONICS INC"},
+ {0x15FF ,"FASTPOINT TECHNOLOGIES INC."},
+ {0x1600 ,"NORTHROP GRUMMAN - CANADA LTD"},
+ {0x1601 ,"TENTA TECHNOLOGY"},
+ {0x1602 ,"PROSYS-TEC INC."},
+ {0x1603 ,"NOKIA WIRELESS BUSINESS COMMUNICATIONS"},
+ {0x1604 ,"CENTRAL SYSTEM RESEARCH CO LTD"},
+ {0x1605 ,"PAIRGAIN TECHNOLOGIES"},
+ {0x1606 ,"EUROPOP AG"},
+ {0x1607 ,"LAVA SEMICONDUCTOR MANUFACTURING INC."},
+ {0x1608 ,"AUTOMATED WAGERING INTERNATIONAL"},
+ {0x1609 ,"SCIEMETRIC INSTRUMENTS INC"},
+ {0x1813 ,"AMBIENT TECHNOLOGIES INC"},
+ {0x1B13 ,"JATON CORP"},
+ {0x2001 ,"TEMPORAL RESEARCH LTD"},
+ {0x270F ,"CHAINTECH COMPUTER CO. LTD"},
+ {0x3388 ,"HINT CORP"},
+ {0x3411 ,"QUANTUM DESIGNS (H.K.) INC."},
+ {0x4005 ,"AVANCE LOGIC INC"},
+ {0x4033 ,"DELTA NETWORKS INC"},
+ {0x416C ,"ALADDIN KNOWLEDGE SYSTEMS"},
+ {0x4444 ,"ICOMPRESION INC."},
+ {0x4943 ,"GROWTH NETWORKS"},
+ {0x4CA1 ,"SEANIX TECHNOLOGY INC"},
+ {0x4D51 ,"MEDIAQ INC."},
+ {0x4D54 ,"MICROTECHNICA CO LTD"},
+ {0x5136 ,"S S TECHNOLOGIES"},
+ {0x5333 ,"S3 INC."},
+ {0x544C ,"TERALOGIC INC"},
+ {0x5555 ,"GENROCO INC"},
+ {0x6409 ,"LOGITEC CORP."},
+ {0x6666 ,"DECISION COMPUTER INTERNATIONAL CO."},
+ {0x8086 ,"INTEL CORP."},
+ {0x8888 ,"SILICON MAGIC CORP."},
+ {0x8E0E ,"COMPUTONE CORPORATION"},
+ {0x9004 ,"ADAPTEC"},
+ {0x919A ,"GIGAPIXEL CORP"},
+ {0x9699 ,"OMNI MEDIA TECHNOLOGY INC."},
+ {0xA0A0 ,"AOPEN INC."},
+ {0xA0F1 ,"UNISYS CORPORATION"},
+ {0xA259 ,"HEWLETT PACKARD"},
+ {0xAC1E ,"DIGITAL RECEIVER TECHNOLOGY INC"},
+ {0xC0DE ,"MOTOROLA"},
+ {0xC0FE ,"MOTION ENGINEERING, INC."},
+ {0xCA50 ,"VARIAN AUSTRIALIA PTY LTD"},
+ {0xCAFE ,"CHRYSALIS-ITS"},
+ {0xCCCC ,"CATAPULT COMMUNICATIONS"},
+ {0xD4D4 ,"DY4 SYSTEMS INC"},
+ {0xE4BF ,"EKF ELEKTRONIK GMBH"},
+ {0xEA01 ,"EAGLE TECHNOLOGY"},
+ {0xFA57 ,"FAST SEARCH & TRANSFER ASA"},
+ {0xFEDA ,"EPIGRAM INC"}
+};
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ pgflt.c
+
+Abstract:
+
+ page fault handling on x86
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 25-Nov-1999: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+
+#include "precomp.h"
+
+////////////////////////////////////////////////////
+// GLOBALS
+////
+
+char tempPageFault[1024];
+extern void NewInt31Handler(void);
+
+ULONG OldIntEHandler=0;
+ULONG error_code;
+BOOLEAN bInPageFaultHandler = FALSE;
+static ULONG PCR_SEL = PCR_SELECTOR;
+static ULONG OLD_PCR;
+
+////////////////////////////////////////////////////
+// FUNCTIONS
+////
+
+//*************************************************************************
+// HandleInDebuggerFault()
+//
+//*************************************************************************
+ULONG HandleInDebuggerFault(FRAME* ptr,ULONG address)
+{
+ PEPROCESS tsk;
+
+ ENTER_FUNC();
+
+ DPRINT((0,"HandleInDebuggerFault(): ###### page fault @ %.8X while inside debugger, eip: %x\n",address, ptr->eip));
+
+ // fault in this page fault handler
+ if(bInPageFaultHandler)
+ {
+ DPRINT((0,"HandleInDebuggerFault(): ###### page fault @ %.8X while in page fault handler\n",address));
+
+ DPRINT((0,"!!! machine is halted !!!\n"));
+ __asm__ __volatile__ ("hlt");
+
+ LEAVE_FUNC();
+ return 0;
+ }
+
+ bInPageFaultHandler = TRUE;
+
+ // when we come here from DebuggerShell() we live on a different stack
+ // so the current task is different as well
+ tsk = IoGetCurrentProcess();
+
+ DPRINT((0,"%.8X (%.4X:%.8X %.8X %s %s %s task=%.8X )\n",
+ address,
+ ptr->cs,
+ ptr->eip,
+ ptr->eflags,
+ (ptr->error_code&1)?"PLP":"NP",
+ (ptr->error_code&2)?"WRITE":"READ",
+ (ptr->error_code&4)?"USER-MODE":"KERNEL-MODE",
+ (ULONG)tsk));
+
+ if(!bInPrintk)
+ {
+ DPRINT((0,"HandleInDebuggerFault(): unexpected pagefault in command handler!\n",address));
+ }
+ else
+ {
+ DPRINT((0,"HandleInDebuggerFault(): unexpected pagefault in command handler while in PrintkCallback()!\n",address));
+ }
+
+ if(tsk)
+ {
+ PULONG pPGD;
+ PULONG pPTE;
+
+ pPGD = ADDR_TO_PDE(address);
+
+ DPRINT((0,"PGD for %.8X @ %.8X = %.8X\n",address,(ULONG)pPGD,(ULONG)(*pPGD) ));
+
+ if(pPGD && (*pPGD)&_PAGE_PRESENT)
+ {
+ // not large page
+ if(!((*pPGD)&_PAGE_4M))
+ {
+ pPTE = ADDR_TO_PTE(address);
+ if(pPTE)
+ {
+ DPRINT((0,"PTE for %.8X @ %.8X = %.8X\n",address,(ULONG)pPTE,(ULONG)(*pPTE) ));
+ }
+ }
+ }
+ }
+
+ IntelStackWalk(ptr->eip,CurrentEBP,ulRealStackPtr);
+
+ DPRINT((0,"!!! machine is halted !!!\n"));
+ __asm__ __volatile__ ("hlt");
+
+ LEAVE_FUNC();
+
+ return 2;
+}
+
+//*************************************************************************
+// HandlePageFault()
+//
+// returns:
+// 0 = let the system handle it
+// 1 = call DebuggerShell()
+// 2 = FATAL error inside debugger
+//*************************************************************************
+ULONG HandlePageFault(FRAME* ptr)
+{
+ PVOID address;
+ PEPROCESS tsk, tsk1;
+ PMADDRESS_SPACE vma;
+ PLIST_ENTRY current_entry;
+ MEMORY_AREA* current;
+ ULONG value;
+ PKTHREAD CurrentThread;
+ PETHREAD CurrentEThread;
+
+ // get linear address of page fault
+ __asm__ __volatile__("movl %%cr2,%0"
+ :"=r" (address));
+
+ DPRINT((0,"\nPageFault: bInDebShell: %d, error: %d, addr: %x\n", bInDebuggerShell, ptr->error_code, address));
+
+ // there's something terribly wrong if we get a fault in our command handler
+ if(bInDebuggerShell)
+ {
+ DPRINT((0,"return handleindebuggerfault\n"));
+ return HandleInDebuggerFault(ptr,(ULONG)address);
+ }
+
+ ASSERT(IsAddressValid((ULONG)ptr));
+ // remember error code so we can push it back on the stack
+ error_code = ptr->error_code;
+
+ //ei Check IRQL here!!!
+/*
+ if(in_interrupt())
+ {
+ Print(OUTPUT_WINDOW,"pICE: system is currently processing an interrupt!\n");
+ return 1;
+ }
+*/
+ // current process
+ tsk = IoGetCurrentProcess();
+ DPRINT((0,"tsk: %x\t", tsk));
+ if( !tsk || !(IsAddressValid((ULONG)tsk))){
+ DPRINT((0,"tsk address not valid: tsk: %x\n", tsk));
+ return 0;
+ }
+
+ // lookup VMA for this address
+ if( (ULONG)address > KERNEL_BASE )
+ vma = my_init_mm; // use kernel mem area for kernel addresses
+ else vma = &(tsk->AddressSpace); // otherwise, use user memory area
+
+ if( !vma ){
+ DPRINT((0,"vma not valid: vma: %x\n", vma));
+ return 0;
+ }
+
+ current_entry = vma->MAreaListHead.Flink;
+ ASSERT(current_entry);
+ DPRINT((0,"vma: %x, current_entry: %x, kernel arena: %x\n", vma, current_entry, my_init_mm));
+ while(current_entry != &vma->MAreaListHead)
+ {
+ ASSERT(current_entry);
+ ASSERT(IsAddressValid((ULONG)current_entry));
+ current = CONTAINING_RECORD(current_entry,
+ MEMORY_AREA,
+ Entry);
+
+
+ if( (address >= current->BaseAddress) && (address <= current->BaseAddress + current->Length ))
+ {
+ DPRINT((0,"address: %x %x - %x Attrib: %x, Type: %x\n", address, current->BaseAddress, current->BaseAddress + current->Length, current->Attributes, current->Type));
+ //page not present
+ if( !(error_code & 1) ){
+ //check it is in pageable area
+ if( current->Type == MEMORY_AREA_SECTION_VIEW ||
+ current->Type == MEMORY_AREA_VIRTUAL_MEMORY ||
+ current->Type == MEMORY_AREA_PAGED_POOL ||
+ current->Type == MEMORY_AREA_SHARED_DATA
+ ){
+ //ei too much output Print(OUTPUT_WINDOW,"pICE: VMA Pageable Section.\n");
+ //ei DPRINT((0,"return 0 1\n"));
+ return 0; //let the system handle this
+ }
+ Print(OUTPUT_WINDOW,"pICE: VMA Page not present in non-pageable Section!\n");
+ //ei DPRINT((0,"Type: currenttype: %x return 1 2\n", current->Type));
+ return 0;
+ }
+ else{ //access violation
+
+ if( error_code & 4 )
+ { //user mode
+ if( (ULONG)address >= KERNEL_BASE )
+ {
+ Print(OUTPUT_WINDOW,"pICE: User mode program trying to access kernel memory!\n");
+ //DPRINT((0,"return 0 3\n"));
+ return 1;
+ }
+ //DPRINT((0,"return 0 4\n"));
+ return 0;
+ }
+ /*
+ if(error_code & 2)
+ {
+ //on write
+ if(!(current->Attributes & PAGE_READONLY))
+ {
+ Print(OUTPUT_WINDOW,"pICE: virtual memory arena is not writeable!\n");
+ return 1;
+ }
+ }
+ // READ ACCESS
+ else
+ {
+ // test EXT bit in error code
+ if (error_code & 1)
+ {
+ Print(OUTPUT_WINDOW,"pICE: page-level protection fault!\n");
+ return 1;
+ }
+ //
+ */
+ /*
+ if (!(current->Attributes & PAGE_EXECUTE_READ))
+ {
+ Print(OUTPUT_WINDOW,"pICE: VMA is not readable!\n");
+ return 1;
+ }
+ */
+
+ // let the system handle it
+ //DPRINT((0,"return 0 5\n"));
+ return 0;
+ }
+ }
+ current_entry = current_entry->Flink;
+ }
+
+ Print(OUTPUT_WINDOW,"pICE: no virtual memory arena at this address!\n");
+ DPRINT((0,"return 0 6\n"));
+ return 1;
+
+ // let the system handle it
+// return 0;
+}
+
+//*************************************************************************
+// NewIntEHandler()
+//
+//*************************************************************************
+__asm__ ("\n\t \
+NewIntEHandler:\n\t \
+ pushfl\n\t \
+ cli\n\t \
+ cld\n\t \
+ pushal\n\t \
+ pushl %ds\n\t \
+\n\t \
+ // setup default data selectors\n\t \
+ movw %ss,%ax\n\t \
+ movw %ax,%ds\n\t \
+\n\t \
+ /*\n\t \
+ * Load the PCR selector.\n\t \
+ */\n\t \
+ movl %fs, %eax\n\t \
+ movl %eax, _OLD_PCR\n\t \
+ movl _PCR_SEL, %eax\n\t \
+ movl %eax, %fs\n\t \
+\n\t \
+ // get frame ptr\n\t \
+ lea 40(%esp),%eax\n\t \
+ pushl %eax\n\t \
+ call _HandlePageFault\n\t \
+ addl $4,%esp\n\t \
+\n\t \
+ pushl %eax\n\t \
+ movl _OLD_PCR, %eax\n\t \
+ movl %eax, %fs\n\t \
+ popl %eax\n\t \
+\n\t \
+ cmpl $0,%eax\n\t \
+ je call_old_inte_handler\n\t \
+\n\t \
+ cmpl $2,%eax\n\t \
+ je call_handler_unknown_reason\n\t \
+\n\t \
+ popl %ds\n\t \
+ popal\n\t \
+ popfl\n\t \
+ // remove error code. will be restored later when we call\n\t \
+ // original handler again.\n\t \
+ addl $4,%esp\n\t \
+ // call debugger loop\n\t \
+ pushl $" STR(REASON_PAGEFAULT) "\n\t \
+ jmp NewInt31Handler\n\t \
+\n\t \
+call_old_inte_handler:\n\t \
+ popl %ds\n\t \
+ popal\n\t \
+ popfl\n\t \
+ // chain to old handler\n\t \
+ .byte 0x2e\n\t \
+ jmp *_OldIntEHandler\n\t \
+\n\t \
+call_handler_unknown_reason:\n\t \
+ popl %ds\n\t \
+ popal\n\t \
+ popfl\n\t \
+ // remove error code. will be restored later when we call\n\t \
+ // original handler again.\n\t \
+ addl $4,%esp\n\t \
+ // call debugger loop\n\t \
+ pushl $" STR(REASON_INTERNAL_ERROR) "\n\t \
+ jmp NewInt31Handler\n\t \
+ ");
+
+
+//*************************************************************************
+// InstallIntEHook()
+//
+//*************************************************************************
+void InstallIntEHook(void)
+{
+ ULONG LocalIntEHandler;
+
+ ENTER_FUNC();
+
+ MaskIrqs();
+ if(!OldIntEHandler)
+ {
+ __asm__ __volatile__("mov $NewIntEHandler,%0"
+ :"=r" (LocalIntEHandler)
+ :
+ :"eax");
+ OldIntEHandler=SetGlobalInt(0x0E,(ULONG)LocalIntEHandler);
+ }
+ UnmaskIrqs();
+ DPRINT((0,"OldIntE @ %x\n", OldIntEHandler));
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// DeInstallIntEHook()
+//
+//*************************************************************************
+void DeInstallIntEHook(void)
+{
+ ENTER_FUNC();
+
+ MaskIrqs();
+ if(OldIntEHandler)
+ {
+ SetGlobalInt(0x0E,(ULONG)OldIntEHandler);
+ OldIntEHandler=0;
+ }
+ UnmaskIrqs();
+
+ LEAVE_FUNC();
+}
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ pgflt.h
+
+Abstract:
+
+ HEADER for pgflt.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+void InstallIntEHook(void);
+void DeInstallIntEHook(void);
+
+extern ULONG error_code;
--- /dev/null
+/* $Id$ */
+
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "PICE Debugger\0"
+#define REACTOS_STR_INTERNAL_NAME "pice\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "pice.sys\0"
+#include <reactos/version.rc>
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ pice_ver.h
+
+Abstract:
+
+ HEADER , pICE debugger version
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+// versions below 1.0 are BETA
+#define PICE_MAJOR_VERSION (0)
+#define PICE_MINOR_VERSION (99)
+// reset this on major or minor version change
+// increment this on every release build
+#define PICE_BUILD (0007)
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ precomp.h
+
+Abstract:
+
+ precompiled headers
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+#define FRAMEBUFFER_SIZE (0x8000)
+#define LINES_IN_BUFFER (2048)
+
+#include <ntddk.h>
+#include <ntos/types.h>
+#include <types.h>
+//#include <i386/tss.h>
+#include <internal/ob.h>
+#include <internal/i386/segment.h>
+#include <defines.h>
+
+#include "retypes.h"
+//#include <asm/segment.h>
+#include "../shared/shared.h"
+#include "debug.h"
+#include "hardware.h"
+#include "utils.h"
+#include "init.h"
+#include "shell.h"
+#include "trace.h"
+#include "hooks.h"
+#include "patch.h" // patch the keyboard driver
+#include "symbols.h"
+#include "parse.h"
+#include "syscall.h"
+#include "bp.h"
+#include "scancodes.h"
+#include "output.h"
+#include "dblflt.h"
+#include "pgflt.h"
+#include "gpfault.h"
+#include "serial.h"
+#include "hercules.h"
+#include "vga.h"
+#include "pice_ver.h"
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ privateice.c
+
+Abstract:
+
+Environment:
+
+Author:
+
+ Klaus P. Gerlicher
+
+ reactos port by:
+ Eugene Ingerman
+
+Revision History:
+
+ 16-Jul-1998: created
+ 15-Nov-2000: general cleanup of source files
+ 19-Jan-2001: renamed to privateice.c
+
+ 10/20/2001: porting to reactos begins
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+/*
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <linux/fs.h>
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <asm/unistd.h>
+#include <linux/string.h>
+*/
+
+#include <ntddk.h>
+#include <debug.h>
+#include <rosrtl/string.h>
+
+#include "precomp.h"
+#include "serial.h"
+
+////////////////////////////////////////////////////
+// GLOBALS
+////
+
+BOOLEAN bDeviceAlreadyOpen = FALSE;
+
+char tempPICE[1024];
+
+////////////////////////////////////////////////////
+// FUNCTIONS
+////
+
+//*************************************************************************
+// pice_open()
+//
+//*************************************************************************
+
+NTSTATUS STDCALL pice_open(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+ DPRINT((0,"pice_open\n"));
+
+ /* We don't want to talk to two processes at the
+ * same time */
+ if (bDeviceAlreadyOpen){
+ IoCompleteRequest (Irp, IO_NO_INCREMENT);
+ return STATUS_UNSUCCESSFUL; /* is there a more descriptive status code for this case? */
+ }
+
+ bDeviceAlreadyOpen = TRUE;
+ IoCompleteRequest (Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+//*************************************************************************
+// pice_close()
+//
+//*************************************************************************
+NTSTATUS STDCALL pice_close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+ DPRINT((0,"pice_close\n"));
+
+ CleanUpPICE(); // used to be in cleanup_module
+
+ /* We're now ready for our next caller */
+ bDeviceAlreadyOpen = FALSE;
+ IoCompleteRequest (Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+
+//*************************************************************************
+// pice_ioctl()
+//
+//*************************************************************************
+
+NTSTATUS STDCALL pice_ioctl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+// char* pFilename = (char*) ioctl_param;
+
+ PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation( Irp );
+
+ ULONG Code = IoStack->Parameters.DeviceIoControl.IoControlCode;
+
+ switch(Code)
+ {
+ case PICE_IOCTL_LOAD:
+ break;
+ case PICE_IOCTL_RELOAD:
+ if(!ReloadSymbols())
+ {
+ PICE_sprintf(tempPICE,"pICE: not able to reload symbols\n");
+ Print(OUTPUT_WINDOW,tempPICE);
+ }
+ break;
+ case PICE_IOCTL_UNLOAD:
+ UnloadSymbols();
+ break;
+ case PICE_IOCTL_BREAK:
+ PICE_sprintf(tempPICE,"pICE: forcible break\n");
+ Print(OUTPUT_WINDOW,tempPICE);
+ __asm__ __volatile("int $3");
+ break;
+ case PICE_IOCTL_STATUS:
+ {
+ PDEBUGGER_STATUS_BLOCK ustatus_block_p;
+ DEBUGGER_STATUS_BLOCK kstatus_block;
+
+ ULONG OutLength = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
+ if( OutLength < sizeof( DEBUGGER_STATUS_BLOCK ) ){
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ ustatus_block_p = (PDEBUGGER_STATUS_BLOCK)Irp->AssociatedIrp.SystemBuffer;
+
+ //kstatus_block.Test = 0x12345678;
+ RtlCopyMemory(ustatus_block_p, &kstatus_block, sizeof(DEBUGGER_STATUS_BLOCK) );
+ }
+ break;
+ default:
+ IoCompleteRequest (Irp, IO_NO_INCREMENT);
+ return STATUS_INVALID_PARAMETER;
+ }
+ IoCompleteRequest (Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject,
+ PUNICODE_STRING RegistryPath)
+/*
+ * FUNCTION: Module entry point
+ */
+{
+ PDEVICE_OBJECT DeviceObject;
+ UNICODE_STRING DeviceName;
+ UNICODE_STRING SymlinkName;
+
+ DPRINT((0,"PICE Debugger\n"));
+
+#if 0 // don't enable before completely ported
+#ifdef DEBUG
+ // first we enable output of debug strings to COM port
+ DebugSetupSerial(1,115200);
+#endif // DEBUG
+#endif
+
+ if(InitPICE()){
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = pice_open;
+ //ei unimplemented DriverObject->MajorFunction[IRP_MJ_CLOSE] = pice_close;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = pice_ioctl;
+
+ RtlRosInitUnicodeStringFromLiteral(&DeviceName, L"\\Device\\Pice");
+ IoCreateDevice(DriverObject,
+ 0,
+ &DeviceName,
+ PICE_DEVICE_DEBUGGER,
+ 0,
+ TRUE,
+ &DeviceObject);
+ DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
+
+ RtlRosInitUnicodeStringFromLiteral(&SymlinkName, L"\\??\\Pice");
+ IoCreateSymbolicLink(&SymlinkName, &DeviceName);
+
+ return(STATUS_SUCCESS);
+ }
+}
+
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ regs.h
+
+Abstract:
+
+ HEADER for disasm.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+#define REGGS 0
+#define REGFS 1
+#define REGES 2
+#define REGDS 3
+#define REGEDI 4
+#define REGESI 5
+#define REGEBX 6
+#define REGEDX 7
+#define REGECX 8
+#define REGEAX 9
+#define REGEBP 10
+#define REGEIP 11
+#define REGCS 12
+#define REGEFL 13
+#define REGESP 14
+#define REGSS 15
+
+#ifdef KERNEL
+#define REGCR0 16
+#define REGCR2 17
+#define REGCR3 18
+#define REGCR4 19
+#endif
+
+#define REGDR0 20
+#define REGDR1 21
+#define REGDR2 22
+#define REGDR3 23
+#define REGDR6 24
+#define REGDR7 25
+
+#ifdef KERNEL
+#define REGGDTR 26
+#define REGGDTL 27
+#define REGIDTR 28
+#define REGIDTL 29
+#define REGTR 30
+#define REGLDTR 31
+#endif
+
+// Pseudo-registers:
+#define PREGEA 40
+#define PREGBASE PREGEA
+#define PREGEXP 41
+#define PREGRA 42
+#define PREGP 43
+#define PREGU0 44
+#define PREGU1 45
+#define PREGU2 46
+#define PREGU3 47
+#define PREGU4 48
+#define PREGU5 49
+#define PREGU6 50
+#define PREGU7 51
+#define PREGU8 52
+#define PREGU9 53
+
+#define FLAGBASE 100
+#define REGDI 100
+#define REGSI 101
+#define REGBX 102
+#define REGDX 103
+#define REGCX 104
+#define REGAX 105
+#define REGBP 106
+#define REGIP 107
+#define REGFL 108
+#define REGSP 109
+#define REGBL 110
+#define REGDL 111
+#define REGCL 112
+#define REGAL 113
+#define REGBH 114
+#define REGDH 115
+#define REGCH 116
+#define REGAH 117
+#define FLAGIOPL 118
+#define FLAGOF 119
+#define FLAGDF 120
+#define FLAGIF 121
+#define FLAGTF 122
+#define FLAGSF 123
+#define FLAGZF 124
+#define FLAGAF 125
+#define FLAGPF 126
+#define FLAGCF 127
+#define FLAGVIP 128
+#define FLAGVIF 129
+
+
+#define REGFIR REGEIP
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ remods.h
+
+Abstract:
+
+ HEADER for kernel module creation
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+
+
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ retypes.h
+
+Abstract:
+
+ HEADER for type remapping (porting from NT code)
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+//typedef unsigned int ULONG,*PULONG;
+//typedef unsigned short USHORT,*PUSHORT;
+//typedef unsigned char UCHAR,*PUCHAR,BYTE,*PBYTE;
+
+//typedef signed int LONG,*PLONG;
+//typedef signed short SHORT,*PSHORT;
+//typedef signed char CHAR,*PCHAR,*LPSTR,*PSTR;
+//typedef unsigned short WCHAR;
+
+//typedef void VOID,*PVOID;
+
+//typedef char BOOLEAN,*PBOOLEAN;
+
+//#define FALSE (0==1)
+//#define TRUE (1==1)
+#ifndef NULL
+#define NULL ((void*)0)
+#endif
+
+// dimension macro
+#define DIM(name) (sizeof(name)/sizeof(name[0]))
+
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ scancodes.h
+
+Abstract:
+
+ HEADER, scancodes of IBM keyboard
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+/*
+** Scan Code Definitions . . .
+*/
+// System Keys
+#define SCANCODE_ESC 0x01
+#define SCANCODE_BACKSPACE 0x0E
+#define SCANCODE_TAB 0x0F
+
+#define SCANCODE_ENTER 0x1C
+#define SCANCODE_L_CTRL 0x1D
+#define SCANCODE_R_CTRL 0x5A
+#define SCANCODE_L_SHIFT 0x2A
+#define SCANCODE_R_SHIFT 0x36
+#define SCANCODE_L_ALT 0x38
+#define SCANCODE_R_ALT 0x5C
+
+#define SCANCODE_SPACE 0x39
+#define SCANCODE_CAPS_LOCK 0x3A
+#define SCANCODE_NUM_LOCK 0x45
+#define SCANCODE_PRNT_SCRN 0x47
+#define SCANCODE_SCROLL_LOCK 0x57
+
+// Function Keys
+#define SCANCODE_F1 0x3b
+#define SCANCODE_F2 0x3c
+#define SCANCODE_F3 0x3d
+#define SCANCODE_F4 0x3e
+#define SCANCODE_F5 0x3f
+#define SCANCODE_F6 0x40
+#define SCANCODE_F7 0x41
+#define SCANCODE_F8 0x42
+#define SCANCODE_F9 0x43
+#define SCANCODE_F10 0x44
+#define SCANCODE_F11 0x57
+#define SCANCODE_F12 0x58
+
+// Directional Control Keys
+#define SCANCODE_HOME 0x47
+#define SCANCODE_UP 0x48
+#define SCANCODE_PGUP 0x49
+#define SCANCODE_LEFT 0x4b
+#define SCANCODE_CENTER 0x4c
+#define SCANCODE_RIGHT 0x4d
+#define SCANCODE_END 0x4f
+#define SCANCODE_DOWN 0x50
+#define SCANCODE_PGDN 0x51
+#define SCANCODE_INS 0x52
+#define SCANCODE_DEL 0x53
+
+// Cluster Directional Control Keys
+#define SCANCODE_C_ENTER 0x59
+#define SCANCODE_C_HOME 0x5d
+#define SCANCODE_C_UP 0x5e
+#define SCANCODE_C_PGUP 0x5f
+#define SCANCODE_C_LEFT 0x60
+#define SCANCODE_C_RIGHT 0x61
+#define SCANCODE_C_END 0x62
+#define SCANCODE_C_DOWN 0x63
+#define SCANCODE_C_PGDN 0x64
+#define SCANCODE_C_INS 0x65
+#define SCANCODE_C_DEL 0x66
+
+
+// Alphanumerics
+#define SCANCODE_1 0x02
+#define SCANCODE_2 0x03
+#define SCANCODE_3 0x04
+#define SCANCODE_4 0x05
+#define SCANCODE_5 0x06
+#define SCANCODE_6 0x07
+#define SCANCODE_7 0x08
+#define SCANCODE_8 0x09
+#define SCANCODE_9 0x0A
+#define SCANCODE_0 0x0B
+
+#define SCANCODE_EXTENDED 0xE0
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ serial.c
+
+Abstract:
+
+ serial debugger connection
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 19-Aug-2000: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+#include "remods.h"
+#include "precomp.h"
+#include "serial_port.h"
+
+BOOLEAN SerialReadByte(PUCHAR px);
+
+
+// used for SERIAL window creation
+// NB: at the moment the terminal is 60 lines high.
+WINDOW wWindowSerial[4]=
+{
+ {1,3,1,0,FALSE},
+ {5,8,1,0,FALSE},
+ {14,26,1,0,FALSE},
+ {41,18,1,0,FALSE}
+};
+
+PUCHAR pScreenBufferSerial;
+
+USHORT usSerialPortBase;
+
+UCHAR packet[_PAGE_SIZE];
+UCHAR assemble_packet[_PAGE_SIZE];
+
+UCHAR flush_buffer[_PAGE_SIZE],g_x,g_y;
+ULONG ulFlushBufferPos = 0;
+
+UCHAR ucLastKeyRead;
+ECOLORS eForegroundColor=WHITE,eBackgroundColor=BLACK;
+
+///************************************************************************
+// SerialSetSpeed()
+//
+///************************************************************************
+void SerialSetSpeed(ULONG baudrate)
+{
+ UCHAR c;
+ ULONG divisor;
+
+ divisor = (ULONG) (115200L/baudrate);
+
+ c = inportb((USHORT)(usSerialPortBase + LCR));
+ outportb((USHORT)(usSerialPortBase + LCR), (UCHAR)(c | 0x80)); // Set DLAB
+ outportb((USHORT)(usSerialPortBase + DLL), (UCHAR)(divisor & 0x00FF));
+ outportb((USHORT)(usSerialPortBase + DLH), (UCHAR)((divisor >> 8) & 0x00FF));
+ outportb((USHORT)(usSerialPortBase + LCR), c); // Reset DLAB
+
+}
+
+///************************************************************************
+// SerialSetOthers()
+//
+// Set other communications parameters
+//************************************************************************
+void SerialSetOthers(ULONG Parity, ULONG Bits, ULONG StopBit)
+{
+ ULONG setting;
+ UCHAR c;
+
+ if (usSerialPortBase == 0) return ;
+ if (Bits < 5 || Bits > 8) return ;
+ if (StopBit != 1 && StopBit != 2) return ;
+ if (Parity != NO_PARITY && Parity != ODD_PARITY && Parity != EVEN_PARITY)
+ return;
+
+ setting = Bits-5;
+ setting |= ((StopBit == 1) ? 0x00 : 0x04);
+ setting |= Parity;
+
+ c = inportb((USHORT)(usSerialPortBase + LCR));
+ outportb((USHORT)(usSerialPortBase + LCR), (UCHAR)(c & ~0x80)); // Reset DLAB
+
+ // no ints
+ outportb((USHORT)(usSerialPortBase + IER), (UCHAR)0);
+
+ // clear FIFO and disable them
+ outportb((USHORT)(usSerialPortBase + FCR), (UCHAR)0);
+
+ outportb((USHORT)(usSerialPortBase + LCR), (UCHAR)setting);
+
+ outportb((USHORT)(usSerialPortBase + MCR), DTR | RTS);
+
+
+ return ;
+}
+
+///************************************************************************
+// FlushSerialBuffer()
+//
+///************************************************************************
+void FlushSerialBuffer(void)
+{
+ UCHAR c;
+
+ while(SerialReadByte(&c));
+}
+
+///************************************************************************
+// SetupSerial()
+//
+///************************************************************************
+void SetupSerial(ULONG port,ULONG baudrate)
+{
+ USHORT ports[]={COM1BASE,COM2BASE,COM3BASE,COM4BASE};
+
+ usSerialPortBase = ports[port-1];
+ SerialSetOthers(NO_PARITY,8,1);
+ SerialSetSpeed(baudrate);
+
+ // clear out received bytes
+ // else we would think there's a terminal connected
+ FlushSerialBuffer();
+}
+
+
+///************************************************************************
+// SerialReadByte()
+//
+// Output a character to the serial port
+//************************************************************************
+BOOLEAN SerialReadByte(PUCHAR px)
+{
+ ULONG timeout;
+
+ timeout = 0x00FFFFL;
+
+ // Wait for transmitter to clear
+ while ((inportb((USHORT)(usSerialPortBase + LSR)) & RCVRDY) == 0)
+ if (!(--timeout))
+ {
+ return FALSE;
+ }
+
+ *px = inportb((USHORT)(usSerialPortBase + RXR));
+
+ return TRUE;
+}
+
+///************************************************************************
+// SerialSendByte()
+//
+// Output a character to the serial port
+//************************************************************************
+BOOLEAN SerialSendByte(UCHAR x)
+{
+ ULONG timeout;
+
+ timeout = 0x00FFFFL;
+
+ // Wait for transmitter to clear
+ while ((inportb((USHORT)(usSerialPortBase + LSR)) & XMTRDY) == 0)
+ if (!(--timeout))
+ {
+ return FALSE;
+ }
+
+ outportb((USHORT)(usSerialPortBase + TXR), x);
+
+ return TRUE;
+}
+
+//************************************************************************
+// CheckSum()
+//
+//************************************************************************
+UCHAR CheckSum(LPSTR p,ULONG Len)
+{
+ UCHAR ucCheckSum = 0;
+ ULONG i;
+ for(i=0;i<Len;i++)
+ {
+ ucCheckSum ^= *p++;
+ ucCheckSum += 1;
+ }
+
+ return ucCheckSum;
+}
+
+
+///************************************************************************
+// ReadPacket()
+//
+///************************************************************************
+BOOLEAN ReadPacket(PSERIAL_PACKET p)
+{
+ return TRUE;
+}
+
+
+///************************************************************************
+// SendPacket()
+//
+///************************************************************************
+BOOLEAN SendPacket(PSERIAL_PACKET p)
+{
+ PUCHAR pHeader = (PUCHAR)&p->header;
+ ULONG i;
+ UCHAR c;
+ ULONG timeout;
+
+ do
+ {
+ timeout = 10;
+ pHeader = (PUCHAR)&p->header;
+ for(i=0;i<(sizeof(SERIAL_PACKET_HEADER)+p->header.packet_size);i++)
+ {
+ if(!SerialSendByte(*pHeader++))
+ {
+ return FALSE;
+ }
+ }
+
+ do
+ {
+ c = 0;
+ SerialReadByte(&c);
+ if(c != ACK)
+ ucLastKeyRead = c;
+ }while(c != ACK && timeout--);
+
+ }while(c != ACK);
+
+ return TRUE;
+}
+
+///************************************************************************
+// SendPacketTimeout()
+//
+///************************************************************************
+BOOLEAN SendPacketTimeout(PSERIAL_PACKET p)
+{
+ PUCHAR pHeader = (PUCHAR)&p->header;
+ ULONG i;
+ UCHAR c;
+ ULONG timeout = 20;
+ BOOLEAN bResult = TRUE;
+
+ pHeader = (PUCHAR)&p->header;
+ for(i=0;i<(sizeof(SERIAL_PACKET_HEADER)+p->header.packet_size);i++)
+ {
+ if(!SerialSendByte(*pHeader++))
+ {
+ return FALSE;
+ }
+ }
+
+ do
+ {
+ c = 0xFF;
+ SerialReadByte(&c);
+ }while(c != ACK && timeout--);
+
+ if(c != ACK)
+ bResult = FALSE;
+
+ return bResult;
+}
+
+
+//************************************************************************
+// AssemblePacket()
+//
+//************************************************************************
+PSERIAL_PACKET AssemblePacket(PUCHAR pData,ULONG ulSize)
+{
+ PSERIAL_PACKET p;
+ ULONG ulCheckSum;
+
+ p = (PSERIAL_PACKET)assemble_packet;
+
+ // fill in header
+ p->header.packet_chksum = CheckSum(pData,ulSize);
+ p->header.packet_size = ulSize;
+ p->header.packet_header_chksum = 0;
+ ulCheckSum = (ULONG)CheckSum((PUCHAR)p,sizeof(SERIAL_PACKET_HEADER));
+ p->header.packet_header_chksum = ulCheckSum;
+ // attach data to packet
+ PICE_memcpy(p->data,pData,ulSize);
+
+ return p;
+}
+
+
+// OUTPUT handlers
+
+//*************************************************************************
+// SetForegroundColorVga()
+//
+//*************************************************************************
+void SetForegroundColorSerial(ECOLORS col)
+{
+ eForegroundColor = col;
+}
+
+//*************************************************************************
+// SetBackgroundColorVga()
+//
+//*************************************************************************
+void SetBackgroundColorSerial(ECOLORS col)
+{
+ eBackgroundColor = col;
+}
+
+
+//*************************************************************************
+// PrintGrafSerial()
+//
+//*************************************************************************
+void PrintGrafSerial(ULONG x,ULONG y,UCHAR c)
+{
+ // put this into memory
+ pScreenBufferSerial[y*GLOBAL_SCREEN_WIDTH + x] = c;
+
+ // put this into cache
+ if(ulFlushBufferPos == 0)
+ {
+ g_x = x;
+ g_y = y;
+ }
+
+ flush_buffer[ulFlushBufferPos++] = c;
+}
+
+//*************************************************************************
+// FlushSerial()
+//
+//*************************************************************************
+void FlushSerial(void)
+{
+ PSERIAL_DATA_PACKET_PRINT pPrint;
+ PSERIAL_PACKET p;
+
+ pPrint = (PSERIAL_DATA_PACKET_PRINT)packet;
+ pPrint->type = PACKET_TYPE_PRINT;
+ pPrint->x = g_x;
+ pPrint->y = g_y;
+ pPrint->fgcol = eForegroundColor;
+ pPrint->bkcol = eBackgroundColor;
+ flush_buffer[ulFlushBufferPos++] = 0;
+ PICE_strcpy(pPrint->string,flush_buffer);
+ ulFlushBufferPos = 0;
+
+ p = AssemblePacket((PUCHAR)pPrint,sizeof(SERIAL_DATA_PACKET_PRINT)+PICE_strlen(flush_buffer));
+ SendPacket(p);
+}
+
+//*************************************************************************
+// ShowCursorSerial()
+//
+// show hardware cursor
+//*************************************************************************
+void ShowCursorSerial(void)
+{
+ PSERIAL_DATA_PACKET_CURSOR pCursor;
+ PSERIAL_PACKET p;
+
+ ENTER_FUNC();
+
+ bCursorEnabled = TRUE;
+
+ pCursor = (PSERIAL_DATA_PACKET_CURSOR)packet;
+ pCursor->type = PACKET_TYPE_CURSOR;
+ pCursor->state = (UCHAR)TRUE;
+ pCursor->x = (UCHAR)wWindow[OUTPUT_WINDOW].usCurX;
+ pCursor->y = (UCHAR)wWindow[OUTPUT_WINDOW].usCurY;
+
+ p = AssemblePacket((PUCHAR)pCursor,sizeof(SERIAL_DATA_PACKET_CURSOR));
+ SendPacket(p);
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// HideCursorSerial()
+//
+// hide hardware cursor
+//*************************************************************************
+void HideCursorSerial(void)
+{
+ PSERIAL_DATA_PACKET_CURSOR pCursor;
+ PSERIAL_PACKET p;
+
+ ENTER_FUNC();
+
+ bCursorEnabled = FALSE;
+
+ pCursor = (PSERIAL_DATA_PACKET_CURSOR)packet;
+ pCursor->type = PACKET_TYPE_CURSOR;
+ pCursor->state = (UCHAR)TRUE;
+
+ p = AssemblePacket((PUCHAR)pCursor,sizeof(SERIAL_DATA_PACKET_CURSOR));
+ SendPacket(p);
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// CopyLineToSerial()
+//
+// copy a line from src to dest
+//*************************************************************************
+void CopyLineToSerial(USHORT dest,USHORT src)
+{
+ NOT_IMPLEMENTED();
+}
+
+//*************************************************************************
+// InvertLineSerial()
+//
+// invert a line on the screen
+//*************************************************************************
+void InvertLineSerial(ULONG line)
+{
+ PSERIAL_DATA_PACKET_INVERTLINE pInvertLine;
+ PSERIAL_PACKET p;
+
+ pInvertLine = (PSERIAL_DATA_PACKET_INVERTLINE)packet;
+ pInvertLine->type = PACKET_TYPE_INVERTLINE;
+ pInvertLine->line = line;
+
+ p = AssemblePacket((PUCHAR)pInvertLine,sizeof(SERIAL_DATA_PACKET_INVERTLINE));
+ SendPacket(p);
+}
+
+//*************************************************************************
+// HatchLineSerial()
+//
+// hatches a line on the screen
+//*************************************************************************
+void HatchLineSerial(ULONG line)
+{
+ NOT_IMPLEMENTED();
+}
+
+//*************************************************************************
+// ClrLineSerial()
+//
+// clear a line on the screen
+//*************************************************************************
+void ClrLineSerial(ULONG line)
+{
+ PSERIAL_DATA_PACKET_CLRLINE pClrLine;
+ PSERIAL_PACKET p;
+
+ pClrLine = (PSERIAL_DATA_PACKET_CLRLINE)packet;
+ pClrLine->type = PACKET_TYPE_CLRLINE;
+ pClrLine->fgcol = eForegroundColor;
+ pClrLine->bkcol = eBackgroundColor;
+ pClrLine->line = line;
+
+ p = AssemblePacket((PUCHAR)pClrLine,sizeof(SERIAL_DATA_PACKET_CLRLINE));
+ SendPacket(p);
+}
+
+//*************************************************************************
+// PrintLogoSerial()
+//
+//*************************************************************************
+void PrintLogoSerial(BOOLEAN bShow)
+{
+ NOT_IMPLEMENTED();
+}
+
+//*************************************************************************
+// PrintCursorSerial()
+//
+// emulate a blinking cursor block
+//*************************************************************************
+void PrintCursorSerial(BOOLEAN bForce)
+{
+ NOT_IMPLEMENTED();
+}
+
+//*************************************************************************
+// SaveGraphicsStateSerial()
+//
+//*************************************************************************
+void SaveGraphicsStateSerial(void)
+{
+ // not implemented
+}
+
+//*************************************************************************
+// RestoreGraphicsStateSerial()
+//
+//*************************************************************************
+void RestoreGraphicsStateSerial(void)
+{
+ // not implemented
+}
+
+// INPUT handlers
+//*************************************************************************
+// GetKeyPolledSerial()
+//
+//*************************************************************************
+UCHAR GetKeyPolledSerial(void)
+{
+ UCHAR ucResult;
+ PSERIAL_DATA_PACKET_POLL pPoll;
+ PSERIAL_PACKET p;
+
+ pPoll = (PSERIAL_DATA_PACKET_POLL)packet;
+ pPoll->type = PACKET_TYPE_POLL;
+ pPoll->major_version = PICE_MAJOR_VERSION;
+ pPoll->minor_version = PICE_MINOR_VERSION;
+ pPoll->build_number = PICE_BUILD;
+
+ p = AssemblePacket((PUCHAR)pPoll,sizeof(SERIAL_DATA_PACKET_POLL));
+ SendPacket(p);
+
+ ucResult = ucLastKeyRead;
+
+ ucLastKeyRead = 0;
+
+ return ucResult;
+}
+
+//*************************************************************************
+// FlushKeyboardQueueSerial()
+//
+//*************************************************************************
+void FlushKeyboardQueueSerial(void)
+{
+ // not implemented
+}
+
+//*************************************************************************
+// Connect()
+//
+//*************************************************************************
+BOOLEAN Connect(USHORT xSize,USHORT ySize)
+{
+ PSERIAL_DATA_PACKET_CONNECT pConnect;
+ PSERIAL_PACKET p;
+
+ pConnect = (PSERIAL_DATA_PACKET_CONNECT)packet;
+ pConnect->type = PACKET_TYPE_CONNECT;
+ pConnect->xsize = xSize;
+ pConnect->ysize = ySize;
+
+ p = AssemblePacket((PUCHAR)pConnect,sizeof(SERIAL_DATA_PACKET_CONNECT));
+ return SendPacketTimeout(p);
+}
+
+//*************************************************************************
+// ConsoleInitSerial()
+//
+// init terminal screen
+//*************************************************************************
+BOOLEAN ConsoleInitSerial(void)
+{
+ BOOLEAN bResult = FALSE;
+
+ ENTER_FUNC();
+
+ ohandlers.CopyLineTo = CopyLineToSerial;
+ ohandlers.PrintGraf = PrintGrafSerial;
+ ohandlers.Flush = FlushSerial;
+ ohandlers.ClrLine = ClrLineSerial;
+ ohandlers.InvertLine = InvertLineSerial;
+ ohandlers.HatchLine = HatchLineSerial;
+ ohandlers.PrintLogo = PrintLogoSerial;
+ ohandlers.PrintCursor = PrintCursorSerial;
+ ohandlers.SaveGraphicsState = SaveGraphicsStateSerial;
+ ohandlers.RestoreGraphicsState = RestoreGraphicsStateSerial;
+ ohandlers.ShowCursor = ShowCursorSerial;
+ ohandlers.HideCursor = HideCursorSerial;
+ ohandlers.SetForegroundColor = SetForegroundColorSerial;
+ ohandlers.SetBackgroundColor = SetBackgroundColorSerial;
+
+ ihandlers.GetKeyPolled = GetKeyPolledSerial;
+ ihandlers.FlushKeyboardQueue = FlushKeyboardQueueSerial;
+
+ SetWindowGeometry(wWindowSerial);
+
+ GLOBAL_SCREEN_WIDTH = 80;
+ GLOBAL_SCREEN_HEIGHT = 60;
+
+ pScreenBufferSerial = PICE_malloc(FRAMEBUFFER_SIZE, NONPAGEDPOOL);
+
+ if(pScreenBufferSerial)
+ {
+ bResult = TRUE;
+
+ EmptyRingBuffer();
+
+ SetupSerial(1,115200);
+
+ // connect to terminal, if none's there, we give up
+ bResult = Connect(GLOBAL_SCREEN_WIDTH,GLOBAL_SCREEN_HEIGHT);
+
+ if(bResult)
+ {
+ GetKeyPolledSerial();
+ }
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+
+//*************************************************************************
+// ConsoleShutdownSerial()
+//
+// exit terminal screen
+//*************************************************************************
+void ConsoleShutdownSerial(void)
+{
+ ENTER_FUNC();
+
+ Connect(80,25);
+
+ FlushSerialBuffer();
+
+ if(pScreenBufferSerial)
+ PICE_free(pScreenBufferSerial);
+
+ LEAVE_FUNC();
+}
+
+
+
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ serial.h
+
+Abstract:
+
+ HEADER for serial.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+void SendString(LPSTR s);
+void SetupSerial(ULONG port,ULONG baudrate);
+
+BOOLEAN ConsoleInitSerial(void);
+void ConsoleShutdownSerial(void);
+
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ serial_port.h
+
+Abstract:
+
+ HEADER for serial.c
+
+ serial port HW defines
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+#define COM1 1
+#define COM2 2
+#define COM1BASE 0x3F8 /* Base port address for COM1 */
+#define COM2BASE 0x2F8 /* Base port address for COM2 */
+
+// FIX these
+#define COM3BASE 0x3F8 /* Base port address for COM3 */
+#define COM4BASE 0x2F8 /* Base port address for COM4 */
+
+/*
+ The 8250 UART has 10 registers accessible through 7 port addresses.
+ Here are their addresses relative to COM1BASE and COM2BASE. Note
+ that the baud rate registers, (DLL) and (DLH) are active only when
+ the Divisor-Latch Access-Bit (DLAB) is on. The (DLAB) is bit 7 of
+ the (LCR).
+
+ o TXR Output data to the serial port.
+ o RXR Input data from the serial port.
+ o LCR Initialize the serial port.
+ o IER Controls interrupt generation.
+ o IIR Identifies interrupts.
+ o MCR Send contorl signals to the modem.
+ o LSR Monitor the status of the serial port.
+ o MSR Receive status of the modem.
+ o DLL Low byte of baud rate divisor.
+ o DHH High byte of baud rate divisor.
+*/
+#define TXR 0 /* Transmit register (WRITE) */
+#define RXR 0 /* Receive register (READ) */
+#define IER 1 /* Interrupt Enable */
+#define IIR 2 /* Interrupt ID */
+#define FCR 2 /* FIFO control */
+#define LCR 3 /* Line control */
+#define MCR 4 /* Modem control */
+#define LSR 5 /* Line Status */
+#define MSR 6 /* Modem Status */
+#define DLL 0 /* Divisor Latch Low */
+#define DLH 1 /* Divisor latch High */
+
+
+/*-------------------------------------------------------------------*
+ Bit values held in the Line Control Register (LCR).
+ bit meaning
+ --- -------
+ 0-1 00=5 bits, 01=6 bits, 10=7 bits, 11=8 bits.
+ 2 Stop bits.
+ 3 0=parity off, 1=parity on.
+ 4 0=parity odd, 1=parity even.
+ 5 Sticky parity.
+ 6 Set break.
+ 7 Toggle port addresses.
+ *-------------------------------------------------------------------*/
+#define NO_PARITY 0x00
+#define EVEN_PARITY 0x18
+#define ODD_PARITY 0x08
+
+
+
+/*-------------------------------------------------------------------*
+ Bit values held in the Line Status Register (LSR).
+ bit meaning
+ --- -------
+ 0 Data ready.
+ 1 Overrun error - Data register overwritten.
+ 2 Parity error - bad transmission.
+ 3 Framing error - No stop bit was found.
+ 4 Break detect - End to transmission requested.
+ 5 Transmitter holding register is empty.
+ 6 Transmitter shift register is empty.
+ 7 Time out - off line.
+ *-------------------------------------------------------------------*/
+#define RCVRDY 0x01
+#define OVRERR 0x02
+#define PRTYERR 0x04
+#define FRMERR 0x08
+#define BRKERR 0x10
+#define XMTRDY 0x20
+#define XMTRSR 0x40
+#define TIMEOUT 0x80
+
+/*-------------------------------------------------------------------*
+ Bit values held in the Modem Output Control Register (MCR).
+ bit meaning
+ --- -------
+ 0 Data Terminal Ready. Computer ready to go.
+ 1 Request To Send. Computer wants to send data.
+ 2 auxillary output #1.
+ 3 auxillary output #2.(Note: This bit must be
+ set to allow the communications card to send
+ interrupts to the system)
+ 4 UART ouput looped back as input.
+ 5-7 not used.
+ *------------------------------------------------------------------*/
+#define DTR 0x01
+#define RTS 0x02
+
+
+/*------------------------------------------------------------------*
+ Bit values held in the Modem Input Status Register (MSR).
+ bit meaning
+ --- -------
+ 0 delta Clear To Send.
+ 1 delta Data Set Ready.
+ 2 delta Ring Indicator.
+ 3 delta Data Carrier Detect.
+ 4 Clear To Send.
+ 5 Data Set Ready.
+ 6 Ring Indicator.
+ 7 Data Carrier Detect.
+ *------------------------------------------------------------------*/
+#define CTS 0x10
+#define DSR 0x20
+
+
+/*------------------------------------------------------------------*
+ Bit values held in the Interrupt Enable Register (IER).
+ bit meaning
+ --- -------
+ 0 Interrupt when data received.
+ 1 Interrupt when transmitter holding reg. empty.
+ 2 Interrupt when data reception error.
+ 3 Interrupt when change in modem status register.
+ 4-7 Not used.
+ *------------------------------------------------------------------*/
+#define RX_INT 0x01
+
+
+/*------------------------------------------------------------------*
+ Bit values held in the Interrupt Identification Register (IIR).
+ bit meaning
+ --- -------
+ 0 Interrupt pending
+ 1-2 Interrupt ID code
+ 00=Change in modem status register,
+ 01=Transmitter holding register empty,
+ 10=Data received,
+ 11=reception error, or break encountered.
+ 3-7 Not used.
+ *------------------------------------------------------------------*/
+#define RX_ID 0x04
+#define RX_MASK 0x07
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ shell.c
+
+Abstract:
+
+ user interface for debugger
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 16-Jul-1998: created
+ 22-Sep-1998: rewrite of keyboard hooking through patching the original keyboard driver
+ 29-Sep-1998: started documentation on project
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+
+
+////////////////////////////////////////////////////
+// DEFINES
+////
+#define LINES_IN_COMMAND_BUFFER (64)
+
+////////////////////////////////////////////////////
+// PROTOTYPES
+////
+
+////////////////////////////////////////////////////
+// GLOBALS
+////
+
+ULONG bPreviousCommandWasGo = FALSE;
+
+// flags to set when we need to pass things to the old INT handlers
+ULONG dwCallOldInt1Handler = 0;
+ULONG dwCallOldInt3Handler = 0;
+ULONG dwCallOldIntEHandler = 0;
+ULONG dwCallOldGPFaultHandler = 0;
+
+ULONG g_ulLineNumberStart=0;
+ULONG ulWindowOffset = 0;
+BOOLEAN bStepThroughSource=FALSE;
+BOOLEAN bStepInto = FALSE;
+
+// key handling
+UCHAR ucConverted; // key converted from scancode to ANSI
+
+volatile BOOLEAN bControl=FALSE; // TRUE when CTRL key was pressed
+volatile BOOLEAN bShift=FALSE; // TRUE when SHIFT key was pressed
+volatile BOOLEAN bAlt=FALSE; // TRUE when ALT key was pressed
+volatile ULONG OldInt31Handler; // address of old keyboard ISR
+volatile ULONG OldGlobalInt31Handler; // address of old global keyboard ISR
+volatile BOOLEAN bEnterNow=FALSE; // TRUE if already stopped
+volatile BOOLEAN bNotifyToExit=FALSE; // TRUE when debugger should leave
+volatile BOOLEAN bSkipMainLoop=FALSE; // TRUE when debugger should skip main loop
+volatile UCHAR ucKeyPressedWhileIdle=0; // key pressed when system was stopped
+volatile BOOLEAN bInDebuggerShell=FALSE; // TRUE while in DebuggerShell()
+BOOLEAN bIrqStateAtBreak;
+
+ULONG ulRealStackPtr;
+static ULONG PCR_SEL = PCR_SELECTOR;
+static ULONG OLD_PCR;
+
+char tempShell[256]; // temporary string container
+
+// old address of display memory
+USHORT OldSelector=0;
+ULONG OldOffset=0;
+
+ULONG ulLastLineDisplayedOffset = 0;
+
+// functions of function keys
+char *szFunctionKeys[10]={
+ "mod", // F1
+ "proc", // F2
+ "src", // F3
+ "code", // F4
+ "x", // F5
+ "vma", // F6
+ "", // F7
+ "t", // F8
+ "", // F9
+ "p" // F10
+};
+
+// new stack for "deep parsing"
+ULONG aulNewStack[0x20000];
+ULONG ulOldStack;
+
+// registers save area (context)
+ULONG CurrentEIP,CurrentEFL;
+ULONG CurrentEAX,CurrentEBX,CurrentECX,CurrentEDX;
+ULONG CurrentESP,CurrentEBP,CurrentESI,CurrentEDI;
+USHORT CurrentCS,CurrentDS=0,CurrentES,CurrentFS,CurrentGS,CurrentSS;
+ULONG CurrentDR0,CurrentDR1,CurrentDR2,CurrentDR3,CurrentDR6,CurrentDR7;
+ULONG CurrentCR0,CurrentCR2,CurrentCR3;
+// previous context
+ULONG OldEIP=0,OldEFL;
+ULONG OldEAX,OldEBX,OldECX,OldEDX;
+ULONG OldESP,OldEBP,OldESI,OldEDI;
+USHORT OldCS=0,OldDS,OldES,OldFS,OldGS,OldSS;
+
+ULONG CurrentProcess;
+
+UCHAR ucCommandBuffer[256];
+USHORT usCurrentPosInInputBuffer=0;
+volatile BOOLEAN bSingleStep=FALSE;
+
+// the last command lines
+char aszCommandLines[LINES_IN_COMMAND_BUFFER][sizeof(ucCommandBuffer)+2];
+ULONG ulCommandInPos=0,ulCommandLastPos=0;
+ULONG ulCommandCurrentPos=0;
+
+
+extern ULONG KeyboardIRQL;
+
+//*************************************************************************
+// GetLinesInCommandHistory()
+//
+//*************************************************************************
+ULONG GetLinesInCommandHistory(void)
+{
+ ULONG ulResult = (ulCommandInPos-ulCommandLastPos)%LINES_IN_COMMAND_BUFFER;
+
+ ENTER_FUNC();
+
+ DPRINT((0,"GetLinesInCommandHistory() returns %u (ulIn %u ulLast %u)\n",ulResult,ulCommandInPos,ulCommandLastPos));
+
+ LEAVE_FUNC();
+
+ return ulResult;
+}
+
+//*************************************************************************
+// AddToCommandLineHistory()
+//
+//*************************************************************************
+void AddToCommandLineHistory(LPSTR s)
+{
+ ULONG i;
+
+ ENTER_FUNC();
+ DPRINT((0,"AddToCommandLineHistory(%s)\n",s));
+
+ if(PICE_strlen(s))
+ {
+ for(i=0;i<LINES_IN_COMMAND_BUFFER;i++)
+ {
+ if(PICE_strcmpi(&aszCommandLines[i][1],s) == 0)
+ {
+ DPRINT((0,"AddToCommandLineHistory(): command line already exists\n"));
+ LEAVE_FUNC();
+ return;
+ }
+ }
+ aszCommandLines[ulCommandInPos][0]=':';
+ PICE_strcpy(&aszCommandLines[ulCommandInPos][1],s);
+ ulCommandCurrentPos = ulCommandInPos = (ulCommandInPos +1)%LINES_IN_COMMAND_BUFFER;
+ if(ulCommandInPos == ulCommandLastPos)
+ {
+ ulCommandLastPos = (ulCommandLastPos+1)%LINES_IN_COMMAND_BUFFER;
+ }
+ }
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// GetFromCommandLineHistory()
+//
+//*************************************************************************
+LPSTR GetFromCommandLineHistory(ULONG ulCurrentCommandPos)
+{
+ LPSTR pRet;
+
+ ENTER_FUNC();
+
+ DPRINT((0,"GetFromCommandLineHistory(): current = %u\n",ulCurrentCommandPos));
+
+ // skip leading ':'
+ pRet = aszCommandLines[ulCurrentCommandPos] + 1;
+
+ DPRINT((0,"GetFromCommandLineHistory(%s)\n",pRet));
+
+ LEAVE_FUNC();
+
+ return pRet;
+}
+
+//*************************************************************************
+// ShowStatusLine()
+//
+//*************************************************************************
+void ShowStatusLine(void)
+{
+ PEPROCESS pCurrentProcess = IoGetCurrentProcess();
+ LPSTR pProcessName;
+
+ ENTER_FUNC();
+
+ if(IsAddressValid((ULONG)pCurrentProcess))
+ {
+ SetForegroundColor(COLOR_TEXT);
+ SetBackgroundColor(COLOR_CAPTION);
+
+ ClrLine(wWindow[OUTPUT_WINDOW].y-1);
+
+ pProcessName = pCurrentProcess->ImageFileName;
+ if(IsAddressValid((ULONG)pProcessName) )
+ {
+ PICE_sprintf(tempShell,
+ " PROCESS(%.8X \"%s\") ",
+ (ULONG)pCurrentProcess,pProcessName);
+ }
+ else
+ {
+ PICE_sprintf(tempShell,
+ " PROCESS(%.8X) ",
+ (ULONG)pCurrentProcess);
+ }
+ PutChar(tempShell,1,wWindow[OUTPUT_WINDOW].y-1);
+
+ ResetColor();
+ }
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// ProcessBootParams()
+//
+//*************************************************************************
+void ProcessBootParams(void)
+{
+ LPSTR p1,p2;
+
+ ENTER_FUNC();
+ if(*szBootParams)
+ {
+ DPRINT((0,"ProcessBootParams()\n"));
+
+ p1 = szBootParams;
+
+ while(*p1)
+ {
+ p2 = ucCommandBuffer;
+ DPRINT((0,"ProcessBootParams(): boot params = %s\n",p1));
+ while(*p1 && *p1!=';')
+ {
+ *p2++ = *p1++;
+ }
+ *p2=0;
+ DPRINT((0,"ProcessBootParams(): cmd buf = %s\n",ucCommandBuffer));
+ if(*p1 != ';')
+ {
+ DPRINT((0,"ProcessBootParams(): error in cmd buf\n"));
+ break;
+ }
+ p1++;
+ DPRINT((0,"ProcessBootParams(): next cmd buf = %s\n",p1));
+
+ Parse(ucCommandBuffer,TRUE);
+ }
+ PICE_memset(ucCommandBuffer,0,sizeof(ucCommandBuffer));
+ *szBootParams = 0;
+ }
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// bNoCtrlKeys()
+//
+//*************************************************************************
+BOOLEAN __inline bNoCtrlKeys(void)
+{
+ return (!bControl && !bAlt && !bShift);
+}
+
+
+//*************************************************************************
+// DebuggerShell()
+//
+// handle user interface when stopped system
+//*************************************************************************
+void DebuggerShell(void)
+{
+ ARGS Args;
+ UCHAR speaker;
+ PEPROCESS pCurrentProcess;
+
+ ENTER_FUNC();
+
+ // save the graphics state
+ SaveGraphicsState();
+
+ // tell USER we are stopped
+ ShowStoppedMsg();
+
+ FlushKeyboardQueue();
+
+ CheckRingBuffer();
+
+ // kill the speakers annoying beep
+ speaker = inb_p((PCHAR)0x61);
+ speaker &= 0xFC;
+ outb_p(speaker,(PCHAR)0x61);
+
+ ProcessBootParams();
+
+ DPRINT((0,"DebuggerShell(): DisplayRegs()\n"));
+ // display register contents
+ DisplayRegs();
+
+ DPRINT((0,"DebuggerShell(): DisplayMemory()\n"));
+ // display data window
+ Args.Value[0]=OldSelector;
+ Args.Value[1]=OldOffset;
+ Args.Count=2;
+ DisplayMemory(&Args);
+
+ DPRINT((0,"DebuggerShell(): Unassemble()\n"));
+
+ // disassembly from current address
+ PICE_memset(&Args,0,sizeof(ARGS));
+ Args.Value[0]=CurrentCS;
+ Args.Value[1]=CurrentEIP;
+ Args.Count=2;
+ Unassemble(&Args);
+
+ // try to find current process's name
+ pCurrentProcess = IoGetCurrentProcess();
+ CurrentProcess = (ULONG)pCurrentProcess;
+
+ // display status line
+ ShowStatusLine();
+
+ // switch on cursor
+ ShowCursor();
+
+ // while we are not told to exit
+ while(bNotifyToExit==FALSE)
+ {
+ // emulate graphics cursor
+ PrintCursor(FALSE);
+
+ // we have a key press
+ if((ucKeyPressedWhileIdle = GetKeyPolled())!=0)
+ {
+ DPRINT((0,"DebuggerShell(): key = %x control = %u shift = %u\n",ucKeyPressedWhileIdle,bControl,bShift));
+
+ // if cursor reversed, normalize it again (only graphics)
+ if(bRev)
+ {
+ PrintCursor(TRUE);
+ }
+
+ // convert key to ANSI, if success add to command buffer and try to
+ // find a command that fits the already entered letters
+ ucConverted = AsciiFromScan((UCHAR)(ucKeyPressedWhileIdle&0x7f));
+
+#if 0
+ PICE_sprintf(tempShell,"%u -> %u",ucKeyPressedWhileIdle, ucConverted);
+ PutChar(tempShell,GLOBAL_SCREEN_WIDTH-32,wWindow[OUTPUT_WINDOW].y-1);
+#endif
+
+ if(!bControl && !bAlt && ucConverted)
+ {
+ DPRINT((0,"DebuggerShell(): normal key\n"));
+ if(!(usCurrentPosInInputBuffer==0 && ucConverted==' '))
+ {
+ // if we have space in the command buffer
+ // put the character there
+ if(usCurrentPosInInputBuffer<sizeof(ucCommandBuffer)-1)
+ {
+ ucCommandBuffer[usCurrentPosInInputBuffer++]=ucConverted;
+ // output the character
+ PICE_sprintf(tempShell,"%c",ucConverted);
+ wWindow[OUTPUT_WINDOW].usCurX = 1;
+ Print(OUTPUT_WINDOW,tempShell);
+ }
+ // if we have something in command buffer
+ // try to find command help that fits
+ if(usCurrentPosInInputBuffer)
+ {
+ FindCommand(ucCommandBuffer);
+ }
+ else ShowStoppedMsg();
+ }
+ }
+ // normal key while holding down CONTROL
+ else if(bControl && !bAlt && !bShift && ucConverted)
+ {
+ if(ucConverted == 'f')
+ bNotifyToExit = TRUE;
+ }
+ // normal key while holding down ALT
+ else if(!bControl && bAlt && !bShift && ucConverted)
+ {
+ }
+ // normal key while holding down ALT & CONTROL
+ else if(bControl && bAlt && !bShift && ucConverted)
+ {
+ }
+ // we didn't get a converted key
+ // so this must be a control key
+ else
+ {
+ // RETURN
+ if(bNoCtrlKeys() && ucKeyPressedWhileIdle == SCANCODE_ENTER)
+ {
+ DPRINT((0,"DebuggerShell(): RETURN\n"));
+ ucCommandBuffer[usCurrentPosInInputBuffer]=0;
+ if(ucCommandBuffer[0])
+ {
+ AddToCommandLineHistory(ucCommandBuffer);
+ ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].usCurY);
+ ulLastLineDisplayedOffset = 0;
+ PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
+ // setup a safe stack for parsing
+ __asm__ __volatile__("\n\t \
+ movl %2,%%eax\n\t \
+ movl %%esp,%%ebx\n\t \
+ mov %%ebx,%0\n\t \
+ leal _aulNewStack,%%ebx\n\t \
+ addl $0x1FFF0,%%ebx\n\t \
+ movl %%ebx,%%esp\n\t \
+ pushl $0\n\t \
+ pushl %%eax\n\t \
+ call _Parse\n\t \
+ movl %0,%%ebx\n\t \
+ movl %%ebx,%%esp"
+ :"=m" (ulOldStack)
+ :"m" (ulOldStack),"m" (ucCommandBuffer)
+ :"eax","ebx");
+
+ ShowStoppedMsg();
+ }
+ else
+ {
+ if(ulLastLineDisplayedOffset)
+ {
+ ulLastLineDisplayedOffset = 0;
+ PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
+ }
+ }
+ usCurrentPosInInputBuffer=0;
+ PICE_memset(&ucCommandBuffer,0,sizeof(ucCommandBuffer));
+ }
+ // backspace
+ else if(bNoCtrlKeys() && ucKeyPressedWhileIdle == SCANCODE_BACKSPACE)
+ {
+ DPRINT((0,"DebuggerShell(): BACKSPACE\n"));
+ if(usCurrentPosInInputBuffer)
+ {
+ if(usCurrentPosInInputBuffer)
+ FindCommand(ucCommandBuffer);
+ else
+ ShowStoppedMsg();
+
+ usCurrentPosInInputBuffer--;
+ ucCommandBuffer[usCurrentPosInInputBuffer]=0;
+ Print(OUTPUT_WINDOW,"\b");
+ }
+ }
+ // Tab
+ else if(bNoCtrlKeys() && ucKeyPressedWhileIdle==SCANCODE_TAB)
+ {
+ DPRINT((0,"DebuggerShell(): TAB\n"));
+ if(usCurrentPosInInputBuffer)
+ {
+ LPSTR pCmd;
+
+ if((pCmd=FindCommand(ucCommandBuffer)) )
+ {
+ ULONG i;
+
+ // clear the displayed command line
+ for(i=0;i<usCurrentPosInInputBuffer;i++)
+ Print(OUTPUT_WINDOW,"\b");
+ // clear command buffer
+ PICE_memset(&ucCommandBuffer,0,sizeof(ucCommandBuffer));
+ // copy the found command into command buffer
+ PICE_strcpy(ucCommandBuffer,pCmd);
+ PICE_strcat(ucCommandBuffer," ");
+ usCurrentPosInInputBuffer = PICE_strlen(ucCommandBuffer);
+ Print(OUTPUT_WINDOW,ucCommandBuffer);
+ }
+ }
+ }
+ else
+ {
+ // function keys
+ if(bNoCtrlKeys() && ucKeyPressedWhileIdle>=59 && ucKeyPressedWhileIdle<69)
+ {
+ DPRINT((0,"DebuggerShell(): FUNCTION %u\n",ucKeyPressedWhileIdle-59));
+ PICE_sprintf(tempShell,":");
+ ReplaceRingBufferCurrent(tempShell);
+ PICE_memset(&ucCommandBuffer,0,sizeof(ucCommandBuffer));
+ usCurrentPosInInputBuffer=0;
+ PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
+ PICE_strcpy(ucCommandBuffer,szFunctionKeys[ucKeyPressedWhileIdle-59]);
+ usCurrentPosInInputBuffer=PICE_strlen(ucCommandBuffer);
+ if(ucCommandBuffer[0])
+ {
+ ulLastLineDisplayedOffset = 0;
+ PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
+
+ // setup a safe stack for parsing
+ __asm__ __volatile__("\n\t \
+ movl %2,%%eax\n\t \
+ movl %%esp,%%ebx\n\t \
+ mov %%ebx,%0\n\t \
+ leal _aulNewStack,%%ebx\n\t \
+ addl $0x1FFF0,%%ebx\n\t \
+ movl %%ebx,%%esp\n\t \
+ pushl $1\n\t \
+ pushl %%eax\n\t \
+ call _Parse\n\t \
+ movl %0,%%ebx\n\t \
+ movl %%ebx,%%esp"
+ :"=m" (ulOldStack)
+ :"m" (ulOldStack),"m" (ucCommandBuffer)
+ :"eax","ebx");
+ PICE_memset(&ucCommandBuffer,0,sizeof(ucCommandBuffer));
+ usCurrentPosInInputBuffer=0;
+ }
+ }
+ else
+ {
+ switch(ucKeyPressedWhileIdle)
+ {
+ case SCANCODE_ESC:
+ if(usCurrentPosInInputBuffer)
+ {
+ PICE_sprintf(tempShell,":");
+ ReplaceRingBufferCurrent(tempShell);
+ PICE_memset(&ucCommandBuffer,0,sizeof(ucCommandBuffer));
+ usCurrentPosInInputBuffer=0;
+ Print(OUTPUT_WINDOW,"");
+ ShowStoppedMsg();
+ }
+ break;
+ case SCANCODE_HOME: // home
+ DPRINT((0,"DebuggerShell(): HOME\n"));
+ // memory window
+ if(bAlt)
+ {
+ DPRINT((0,"DebuggerShell(): data window home\n"));
+ OldOffset=0x0;
+ // display data window
+ Args.Value[0]=OldSelector;
+ Args.Value[1]=OldOffset;
+ Args.Count=2;
+ DisplayMemory(&Args);
+ }
+ // output window
+ else if(bShift)
+ {
+ DPRINT((0,"DebuggerShell(): output window home\n"));
+ if(ulLastLineDisplayedOffset != LinesInRingBuffer()-wWindow[OUTPUT_WINDOW].cy)
+ {
+ ulLastLineDisplayedOffset = LinesInRingBuffer()-wWindow[OUTPUT_WINDOW].cy+1;
+ PrintRingBufferHome(wWindow[OUTPUT_WINDOW].cy-1);
+ }
+ }
+ // source window home
+ else if(bControl)
+ {
+ if(ulCurrentlyDisplayedLineNumber>0)
+ {
+ PICE_SYMBOLFILE_SOURCE* pSrc;
+
+ if(ConvertTokenToSrcFile(szCurrentFile,(PULONG)&pSrc) )
+ {
+ ulCurrentlyDisplayedLineNumber = 1;
+
+ DisplaySourceFile((LPSTR)pSrc+sizeof(PICE_SYMBOLFILE_SOURCE),
+ (LPSTR)pSrc+pSrc->ulOffsetToNext,
+ 1,-1);
+ }
+ }
+ }
+ else if(!bShift && !bControl && !bAlt)
+ {
+ }
+ break;
+ case SCANCODE_END: // end
+ DPRINT((0,"DebuggerShell(): END\n"));
+ // memory window
+ if(bAlt)
+ {
+ DPRINT((0,"DebuggerShell(): data window end\n"));
+ OldOffset=0xFFFFFFFF-0x10*4;
+ // display data window
+ Args.Value[0]=OldSelector;
+ Args.Value[1]=OldOffset;
+ Args.Count=2;
+ DisplayMemory(&Args);
+ }
+ // output window
+ else if(bShift)
+ {
+ DPRINT((0,"DebuggerShell(): output window end\n"));
+ if(ulLastLineDisplayedOffset)
+ {
+ ulLastLineDisplayedOffset = 0;
+
+ PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
+ }
+ }
+ else if(!bShift && !bControl && !bAlt)
+ {
+ }
+ break;
+ case SCANCODE_UP: // up
+ DPRINT((0,"DebuggerShell(): UP\n"));
+ // memory window
+ if(bAlt)
+ {
+ DPRINT((0,"DebuggerShell(): data window up\n"));
+ OldOffset-=0x10;
+ // display data window
+ Args.Value[0]=OldSelector;
+ Args.Value[1]=OldOffset;
+ Args.Count=2;
+ DisplayMemory(&Args);
+ }
+ // output window
+ else if(bShift)
+ {
+ DPRINT((0,"DebuggerShell(): output window up ulLastLineDisplayedOffset = %u\n",ulLastLineDisplayedOffset));
+
+ if(ulLastLineDisplayedOffset+wWindow[OUTPUT_WINDOW].cy < LinesInRingBuffer())
+ {
+ ulLastLineDisplayedOffset += 1;
+
+ PrintRingBufferOffset(wWindow[OUTPUT_WINDOW].cy-1,ulLastLineDisplayedOffset);
+ }
+ }
+ // source window up
+ else if(bControl)
+ {
+ if((ulCurrentlyDisplayedLineNumber-1)>0 && PICE_strlen(szCurrentFile) )
+ {
+ PICE_SYMBOLFILE_SOURCE* pSrc;
+
+ if(ConvertTokenToSrcFile(szCurrentFile,(PULONG)&pSrc) )
+ {
+ ulCurrentlyDisplayedLineNumber--;
+ DisplaySourceFile((LPSTR)pSrc+sizeof(PICE_SYMBOLFILE_SOURCE),
+ (LPSTR)pSrc+pSrc->ulOffsetToNext,
+ ulCurrentlyDisplayedLineNumber,-1);
+ }
+ }
+ else
+ {
+ UnassembleOneLineUp();
+ }
+ }
+ // command line history
+ else if(!bShift && !bControl && !bAlt)
+ {
+ LPSTR pCurrentCmd;
+ ULONG len;
+
+ DPRINT((0,"DebuggerShell(): command line up\n"));
+
+ // only if anything in history
+ if(GetLinesInCommandHistory())
+ {
+ // go to next entry in history
+ if(ulCommandCurrentPos)
+ ulCommandCurrentPos = (ulCommandCurrentPos-1)%GetLinesInCommandHistory();
+ else
+ ulCommandCurrentPos = GetLinesInCommandHistory()-1;
+ DPRINT((0,"DebuggerShell(): current history pos = %u\n",ulCommandCurrentPos));
+ // get this entry
+ pCurrentCmd = GetFromCommandLineHistory(ulCommandCurrentPos);
+ // if it has a string attached
+ if((len = PICE_strlen(pCurrentCmd)))
+ {
+ // replace the current command line
+ PICE_sprintf(tempShell,":");
+ ReplaceRingBufferCurrent(tempShell);
+ PICE_memset(&ucCommandBuffer,0,sizeof(ucCommandBuffer));
+ PICE_strcpy(ucCommandBuffer,pCurrentCmd);
+ usCurrentPosInInputBuffer=len;
+ Print(OUTPUT_WINDOW,pCurrentCmd);
+ }
+ }
+ }
+ break;
+ case SCANCODE_DOWN: // down
+ DPRINT((0,"DebuggerShell(): DOWN\n"));
+ // memory window
+ if(bAlt)
+ {
+ DPRINT((0,"DebuggerShell(): data window down\n"));
+ OldOffset+=0x10;
+ // display data window
+ Args.Value[0]=OldSelector;
+ Args.Value[1]=OldOffset;
+ Args.Count=2;
+ DisplayMemory(&Args);
+ }
+ // output window
+ else if(bShift)
+ {
+ DPRINT((0,"DebuggerShell(): output window down ulLastLineDisplayedOffset = %u\n",ulLastLineDisplayedOffset));
+ if(ulLastLineDisplayedOffset)
+ {
+ ulLastLineDisplayedOffset -= 1;
+
+ if(!PrintRingBufferOffset(wWindow[OUTPUT_WINDOW].cy-1,ulLastLineDisplayedOffset))
+ {
+ ulLastLineDisplayedOffset = 0;
+ PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
+ }
+ }
+ }
+ // source window down
+ else if(bControl)
+ {
+ if(ulCurrentlyDisplayedLineNumber>0 && PICE_strlen(szCurrentFile))
+ {
+ PICE_SYMBOLFILE_SOURCE* pSrc;
+
+ if(ConvertTokenToSrcFile(szCurrentFile,(PULONG)&pSrc) )
+ {
+ ulCurrentlyDisplayedLineNumber++;
+ DisplaySourceFile((LPSTR)pSrc+sizeof(PICE_SYMBOLFILE_SOURCE),
+ (LPSTR)pSrc+pSrc->ulOffsetToNext,
+ ulCurrentlyDisplayedLineNumber,-1);
+ }
+ }
+ else
+ {
+ UnassembleOneLineDown();
+ }
+ }
+ // command line history
+ else if(!bShift && !bControl && !bAlt)
+ {
+ LPSTR pCurrentCmd;
+ ULONG len;
+
+ DPRINT((0,"DebuggerShell(): command line down\n"));
+
+ // only if anything in history
+ if(GetLinesInCommandHistory())
+ {
+ // go to next entry in history
+ ulCommandCurrentPos = (ulCommandCurrentPos+1)%(GetLinesInCommandHistory());
+ DPRINT((0,"DebuggerShell(): current history pos = %u\n",ulCommandCurrentPos));
+ // get this entry
+ pCurrentCmd = GetFromCommandLineHistory(ulCommandCurrentPos);
+ // if it has a string attached
+ if((len = PICE_strlen(pCurrentCmd)))
+ {
+ // replace the current command line
+ PICE_sprintf(tempShell,":");
+ ReplaceRingBufferCurrent(tempShell);
+ PICE_memset(&ucCommandBuffer,0,sizeof(ucCommandBuffer));
+ PICE_strcpy(ucCommandBuffer,pCurrentCmd);
+ usCurrentPosInInputBuffer=len;
+ Print(OUTPUT_WINDOW,pCurrentCmd);
+ }
+ }
+ }
+ break;
+ case SCANCODE_LEFT: // left
+ DPRINT((0,"DebuggerShell(): LEFT\n"));
+ // memory window
+ if(bAlt)
+ {
+ DPRINT((0,"DebuggerShell(): data window left\n"));
+
+ OldOffset-=0x1;
+ // display data window
+ Args.Value[0]=OldSelector;
+ Args.Value[1]=OldOffset;
+ Args.Count=2;
+ DisplayMemory(&Args);
+ }
+ else if(!bShift && !bControl && !bAlt)
+ {
+ }
+ else if(bControl)
+ {
+ if(ulWindowOffset > 0)
+ ulWindowOffset--;
+ PICE_memset(&Args,0,sizeof(ARGS));
+ Args.Count=0;
+ Unassemble(&Args);
+ }
+ break;
+ case SCANCODE_RIGHT: // right
+ // memory window
+ if(bAlt)
+ {
+ DPRINT((0,"DebuggerShell(): data window right\n"));
+
+ OldOffset+=0x1;
+ // display data window
+ Args.Value[0]=OldSelector;
+ Args.Value[1]=OldOffset;
+ Args.Count=2;
+ DisplayMemory(&Args);
+ }
+ else if(!bShift && !bControl && !bAlt)
+ {
+ }
+ else if(bControl)
+ {
+ if(ulWindowOffset < 80)
+ ulWindowOffset++;
+ PICE_memset(&Args,0,sizeof(ARGS));
+ Args.Count=0;
+ Unassemble(&Args);
+ }
+ break;
+ case SCANCODE_PGUP: // page up
+ DPRINT((0,"DebuggerShell(): PAGEUP\n"));
+ // memory window
+ if(bAlt)
+ {
+ OldOffset-=wWindow[DATA_WINDOW].cy*0x10;
+ // display data window
+ Args.Value[0]=OldSelector;
+ Args.Value[1]=OldOffset;
+ Args.Count=2;
+ DisplayMemory(&Args);
+ }
+ // output window
+ else if(bShift)
+ {
+ if(ulLastLineDisplayedOffset+2*(wWindow[OUTPUT_WINDOW].cy) < LinesInRingBuffer())
+ {
+ ulLastLineDisplayedOffset += (wWindow[OUTPUT_WINDOW].cy);
+
+ PrintRingBufferOffset(wWindow[OUTPUT_WINDOW].cy-1,ulLastLineDisplayedOffset);
+ }
+ else
+ {
+ if(ulLastLineDisplayedOffset != LinesInRingBuffer()-wWindow[OUTPUT_WINDOW].cy)
+ {
+ ulLastLineDisplayedOffset = LinesInRingBuffer()-wWindow[OUTPUT_WINDOW].cy;
+ PrintRingBufferOffset(wWindow[OUTPUT_WINDOW].cy-1,ulLastLineDisplayedOffset);
+ }
+ }
+ }
+ // source window page up
+ else if(bControl)
+ {
+ if(PICE_strlen(szCurrentFile))
+ {
+ if((ulCurrentlyDisplayedLineNumber-wWindow[SOURCE_WINDOW].cy)>0)
+ {
+ PICE_SYMBOLFILE_SOURCE* pSrc;
+
+ if(ConvertTokenToSrcFile(szCurrentFile,(PULONG)&pSrc) )
+ {
+ ulCurrentlyDisplayedLineNumber -= wWindow[SOURCE_WINDOW].cy;
+
+ DisplaySourceFile((LPSTR)pSrc+sizeof(PICE_SYMBOLFILE_SOURCE),
+ (LPSTR)pSrc+pSrc->ulOffsetToNext,
+ ulCurrentlyDisplayedLineNumber ,-1);
+ }
+ }
+ else
+ {
+ PICE_SYMBOLFILE_SOURCE* pSrc;
+
+ if(ConvertTokenToSrcFile(szCurrentFile,(PULONG)&pSrc) )
+ {
+ ulCurrentlyDisplayedLineNumber = 1;
+
+ DisplaySourceFile((LPSTR)pSrc+sizeof(PICE_SYMBOLFILE_SOURCE),
+ (LPSTR)pSrc+pSrc->ulOffsetToNext,
+ ulCurrentlyDisplayedLineNumber ,-1);
+ }
+ }
+ }
+ else
+ {
+ UnassembleOnePageUp(wWindow[SOURCE_WINDOW].cy);
+ }
+
+ }
+ else if(!bShift && !bControl && !bAlt)
+ {
+ }
+ break;
+ case SCANCODE_PGDN: // page down
+ DPRINT((0,"DebuggerShell(): PAGEDOWN\n"));
+ // memory window
+ if(bAlt)
+ {
+ OldOffset+=wWindow[DATA_WINDOW].cy*0x10;
+ // display data window
+ Args.Value[0]=OldSelector;
+ Args.Value[1]=OldOffset;
+ Args.Count=2;
+ DisplayMemory(&Args);
+ }
+ else if(bShift)
+ {
+ if(ulLastLineDisplayedOffset>wWindow[OUTPUT_WINDOW].cy)
+ {
+ ulLastLineDisplayedOffset -= (wWindow[OUTPUT_WINDOW].cy);
+
+ PrintRingBufferOffset(wWindow[OUTPUT_WINDOW].cy-1,ulLastLineDisplayedOffset);
+ }
+ else
+ {
+ if(ulLastLineDisplayedOffset)
+ {
+ ulLastLineDisplayedOffset = 0;
+ PrintRingBufferOffset(wWindow[OUTPUT_WINDOW].cy-1,ulLastLineDisplayedOffset);
+ }
+ }
+ }
+ else if(bControl)
+ {
+ if(PICE_strlen(szCurrentFile) )
+ {
+ if((ulCurrentlyDisplayedLineNumber+wWindow[SOURCE_WINDOW].cy)>0)
+ {
+ PICE_SYMBOLFILE_SOURCE* pSrc;
+
+ if(ConvertTokenToSrcFile(szCurrentFile,(PULONG)&pSrc) )
+ {
+ ulCurrentlyDisplayedLineNumber += wWindow[SOURCE_WINDOW].cy;
+
+ DisplaySourceFile((LPSTR)pSrc+sizeof(PICE_SYMBOLFILE_SOURCE),
+ (LPSTR)pSrc+pSrc->ulOffsetToNext,
+ ulCurrentlyDisplayedLineNumber ,-1);
+ }
+ }
+ else
+ {
+ PICE_SYMBOLFILE_SOURCE* pSrc;
+
+ if(ConvertTokenToSrcFile(szCurrentFile,(PULONG)&pSrc) )
+ {
+ ulCurrentlyDisplayedLineNumber = 1;
+
+ DisplaySourceFile((LPSTR)pSrc+sizeof(PICE_SYMBOLFILE_SOURCE),
+ (LPSTR)pSrc+pSrc->ulOffsetToNext,
+ ulCurrentlyDisplayedLineNumber ,-1);
+ }
+ }
+ }
+ else
+ {
+ UnassembleOnePageDown(wWindow[SOURCE_WINDOW].cy);
+ }
+ }
+ else if(!bShift && !bControl && !bAlt)
+ {
+ }
+ break;
+ }
+ }
+ }
+ }
+ ucKeyPressedWhileIdle=0;
+ }
+ }
+
+ SaveOldRegs();
+
+ PrintLogo(TRUE);
+
+ ShowRunningMsg();
+
+ if(bRev)
+ PrintCursor(TRUE);
+
+ // hide the cursor
+ HideCursor();
+
+ FlushKeyboardQueue();
+
+ RestoreGraphicsState();
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// RealIsr()
+//
+//*************************************************************************
+void RealIsr(ULONG dwReasonForBreak)
+{
+ BOOLEAN ReinstallPermanentBp = FALSE;
+
+ DPRINT((0,"reason: %u#################################################################\n", dwReasonForBreak));
+ ENTER_FUNC();
+
+ // in handler
+ bInDebuggerShell = TRUE;
+
+ bStepping = FALSE;
+
+ // don't assume we must call original handlers yet
+ dwCallOldInt1Handler = dwCallOldInt3Handler = dwCallOldIntEHandler = dwCallOldGPFaultHandler = 0;
+ bSkipMainLoop = FALSE;
+ bEnterNow = FALSE;
+
+ // reset trace flag (TF) on the stack
+ CurrentEFL&=(~0x100);
+
+ InstallPrintkHook();
+
+ // control is not depressed
+ bControl=FALSE;
+
+ bIrqStateAtBreak = ((CurrentEFL&(1<<9))!=0);
+
+ DPRINT((0,"\nbInDebuggerShell %x, dwReasonForBreak: %x, bIrqStateAtBreak: %d\n", bInDebuggerShell, dwReasonForBreak, bIrqStateAtBreak));
+ DPRINT((0,"CurrentEIP: %x, CurrentESP: %x\n", CurrentEIP, CurrentESP));
+
+ // came in because TF flag was set
+ if(dwReasonForBreak == REASON_SINGLESTEP)
+ {
+ ULONG ulAddress,ulAddressCurrent;
+
+ DPRINT((0,"REASON_SINGLESTEP: bSingleStep: %u\n", bSingleStep));
+
+ if(!bSingleStep)
+ {
+ dwCallOldInt1Handler = 1;
+ DPRINT((0,"no single step requested: %u!\n", dwCallOldInt1Handler));
+ goto common_return_point;
+ }
+
+ ulAddress = GetLinearAddress(OldCS,OldEIP);
+ ulAddressCurrent = GetLinearAddress(CurrentCS,CurrentEIP);
+
+ // if we came in because we needed to skip past a permanent
+ // INT3 hook, we need to put the INT3 back in place and
+ // simply restart the system.
+ if(NeedToReInstallSWBreakpoints(ulAddress,TRUE) )
+ {
+ DPRINT((0,"reinstalling INT3 @ %.4X:%.8X\n",OldCS,OldEIP));
+
+ ReInstallSWBreakpoint(ulAddress);
+
+ // previous command was go i.e. we did not single-step over a location
+ // where a permanent breakpoint was installed (Printk() etc.) we simply restart
+ // else we must stop the system.
+ if(bPreviousCommandWasGo)
+ {
+ bPreviousCommandWasGo = FALSE;
+ bInDebuggerShell = FALSE;
+
+ if(bStepThroughSource)
+ {
+ // set TF flag
+ CurrentEFL |= 0x100;
+ }
+
+ LEAVE_FUNC();
+ DPRINT((0,"singlestep-----------------------------------------------------------------\n"));
+ return;
+ }
+ bPreviousCommandWasGo = FALSE;
+ }
+
+ if(IsSwBpAtAddressInstalled(ulAddressCurrent))
+ DeInstallSWBreakpoint(ulAddressCurrent);
+
+ // we came here while stepping through source code block
+ if(bStepThroughSource)
+ {
+ ULONG ulLineNumber;
+ LPSTR pSrc,pFileName;
+
+ DPRINT((0,"RealIsr(): stepping through source!\n"));
+
+ // look up the corresponding source line
+ // if there isn't any or the source line number has changed
+ // we break back into the debugger
+ if(bShowSrc)
+ pSrc = FindSourceLineForAddress(ulAddressCurrent,&ulLineNumber,NULL,NULL,&pFileName);
+ else pSrc = NULL;
+
+ DPRINT((0,"RealIsr(): line #%u pSrc=%x (old line #%u)\n",ulLineNumber,(ULONG)pSrc,g_ulLineNumberStart));
+
+ // if we have found a source line there
+ if(pSrc && ulLineNumber==g_ulLineNumberStart)
+ {
+ DPRINT((0,"RealIsr(): stepping through line #%u in file = %s!\n",ulLineNumber,pFileName));
+
+ if(bStepInto)
+ StepInto(NULL);
+ else
+ StepOver(NULL);
+
+ bInDebuggerShell = FALSE;
+ LEAVE_FUNC();
+ DPRINT((0,"singstep-----------------------------------------------------------------\n"));
+ return;
+ }
+ bStepThroughSource = FALSE;
+ bNotifyToExit = FALSE;
+ bSkipMainLoop = FALSE;
+ }
+ }
+ // came in because hardware register triggered a breakpoint
+ else if(dwReasonForBreak == REASON_HARDWARE_BP)
+ {
+ ULONG ulReason;
+
+ DPRINT((0,"REASON_HARDWARE_BP\n"));
+
+ // disable HW breakpoints
+ __asm__("\n\t \
+ movl %%dr6,%%eax\n\t \
+ movl %%eax,%0\n\t \
+ xorl %%eax,%%eax\n\t \
+ movl %%eax,%%dr6\n\t \
+ movl %%eax,%%dr7"
+ :"=m" (ulReason)
+ :
+ :"eax"
+ );
+
+ DPRINT((0,"REASON_HARDWARE_BP: %x\n",(ulReason&0xF)));
+
+ // HW breakpoint DR1 (skip: only used in init_module detection)
+ if(ulReason&0x2)
+ {
+ CurrentEFL |=(1<<16); // set resume flag
+
+ bSkipMainLoop = TRUE;
+
+ TryToInstallVirtualSWBreakpoints();
+ }
+ // HW breakpoint DR0
+ else if(ulReason&0x1)
+ {
+ ULONG ulAddressCurrent;
+
+ ulAddressCurrent = GetLinearAddress(CurrentCS,CurrentEIP);
+
+ // we came here while stepping through source code block
+ if(bStepThroughSource)
+ {
+ ULONG ulLineNumber;
+ LPSTR pSrc,pFileName;
+
+ DPRINT((0,"RealIsr(): stepping through source! [2]\n"));
+
+ // look up the corresponding source line
+ // if there isn't any or the source line number has changed
+ // we break back into the debugger
+ if(bShowSrc)
+ pSrc = FindSourceLineForAddress(ulAddressCurrent,&ulLineNumber,NULL,NULL,&pFileName);
+ else
+ pSrc = NULL;
+
+ DPRINT((0,"RealIsr(): line #%u pSrc=%x (old line #%u) [2]\n",ulLineNumber,(ULONG)pSrc,g_ulLineNumberStart));
+
+ // if we have found a source line there
+ if(pSrc && ulLineNumber==g_ulLineNumberStart)
+ {
+ DPRINT((0,"RealIsr(): stepping through line #%u in file = %s! [2]\n",ulLineNumber,pFileName));
+
+ if(bStepInto)
+ StepInto(NULL);
+ else
+ StepOver(NULL);
+
+ bInDebuggerShell = FALSE;
+ LEAVE_FUNC();
+ DPRINT((0,"rrr-----------------------------------------------------------------\n"));
+ return;
+ }
+ bNotifyToExit = FALSE;
+ bSkipMainLoop = FALSE;
+ bStepThroughSource = FALSE;
+ }
+ }
+ }
+ else if(dwReasonForBreak==REASON_INT3)
+ {
+ ULONG ulAddress;
+
+ DPRINT((0,"REASON_INT3\n"));
+
+ // must subtract one cause INT3s are generated after instructions execution
+ CurrentEIP--;
+
+ // make a flat address
+ ulAddress = GetLinearAddress(CurrentCS,CurrentEIP);
+
+ DPRINT((0,"INT3 @ %.8X\n",ulAddress));
+
+ // if there's a breakpoint installed at current EIP remove it
+ if(DeInstallSWBreakpoint(ulAddress) )
+ {
+ PSW_BP p;
+
+ DPRINT((0,"INT3 @ %.8X removed\n",ulAddress));
+
+ // if it's permanent (must be Printk() ) skip the DebuggerShell() and
+ // do a callback
+ if( (p = IsPermanentSWBreakpoint(ulAddress)) )
+ {
+ DPRINT((0,"permanent breakpoint\n"));
+
+ ReinstallPermanentBp = TRUE;
+
+ OldCS = CurrentCS;
+ OldEIP = CurrentEIP;
+
+ bSkipMainLoop = TRUE;
+ DPRINT((0,"callback at %x\n",p->Callback));
+ if(p->Callback)
+ p->Callback();
+ }
+ else
+ {
+ LPSTR pFind;
+ if(ScanExportsByAddress(&pFind,GetLinearAddress(CurrentCS,CurrentEIP)))
+ {
+ PICE_sprintf(tempShell,"pICE: SW Breakpoint at %s (%.4X:%.8X)\n",pFind,CurrentCS,CurrentEIP);
+ }
+ else
+ {
+ PICE_sprintf(tempShell,"pICE: SW Breakpoint at %.4X:%.8X\n",CurrentCS,CurrentEIP);
+ }
+ Print(OUTPUT_WINDOW,tempShell);
+ }
+ CurrentEFL &= ~(1<<16); // clear resume flag
+ }
+ else
+ {
+ LPSTR pFind;
+ PEPROCESS my_current = IoGetCurrentProcess();
+
+ DPRINT((0,"can't deinstall, somebody else's breakpoint\n"));
+
+
+ // if no other debugger is running on this process and the address is
+ // above TASK_SIZE we assume this to be a hard embedded INT3
+/*
+#if REAL_LINUX_VERSION_CODE < 0x020400
+ if(ulAddress<TASK_SIZE && !(my_current->flags & PF_PTRACED) )
+#else
+ if(ulAddress<TASK_SIZE && !(my_current->ptrace & PT_PTRACED) )
+#endif
+*/
+ if( ulAddress )
+ {
+ if(ScanExportsByAddress(&pFind,GetLinearAddress(CurrentCS,CurrentEIP)))
+ {
+ PICE_sprintf(tempShell,"pICE: break due to embedded INT 3 at %s (%.4X:%.8X)\n",pFind,CurrentCS,CurrentEIP);
+ }
+ else
+ {
+ PICE_sprintf(tempShell,"pICE: break due to embedded INT 3 at user-mode address %.4X:%.8X\n",CurrentCS,CurrentEIP);
+ }
+ Print(OUTPUT_WINDOW,tempShell);
+ CurrentEFL &= ~(1<<16); // clear resume flag
+ }
+ // well someone is already debugging this, we must pass the INT3 on to old handler
+ // but only when it's a user-mode address
+/*
+ else
+ {
+ if(ulAddress<TASK_SIZE || !bInt3Here)
+ {
+ DPRINT((0,"SW Breakpoint but debugged by other process at %.4X:%.8X\n",CurrentCS,CurrentEIP));
+ // call the old handler on return from RealIsr()
+ dwCallOldInt3Handler = 1;
+ // and skip DebuggerShell()
+ bSkipMainLoop = TRUE;
+ }
+ else
+ {
+ if(ScanExportsByAddress(&pFind,GetLinearAddress(CurrentCS,CurrentEIP)))
+ {
+ PICE_sprintf(tempShell,"pICE: break due to embedded INT 3 at (%s) %.4X:%.8X\n",
+ pFind,CurrentCS,CurrentEIP);
+ }
+ else
+ {
+ PICE_sprintf(tempShell,"pICE: break due to embedded INT 3 at kernel-mode address %.4X:%.8X\n",
+ CurrentCS,CurrentEIP);
+ }
+ Print(OUTPUT_WINDOW,tempShell);
+ CurrentEFL &= ~(1<<16); // clear resume flag
+ }
+ }
+*/
+ // skip INT3
+ CurrentEIP++;
+ }
+ }
+ else if(dwReasonForBreak == REASON_PAGEFAULT)
+ {
+ LPSTR pSymbolName;
+
+ DPRINT((0,"REASON_PAGEFAULT\n"));
+
+ if( ScanExportsByAddress(&pSymbolName,GetLinearAddress(CurrentCS,CurrentEIP)) )
+ {
+ PICE_sprintf(tempShell,"pICE: Breakpoint due to page fault at %.4X:%.8X (%s)\n",CurrentCS,CurrentEIP,pSymbolName);
+ }
+ else
+ {
+ PICE_sprintf(tempShell,"pICE: Breakpoint due to page fault at %.4X:%.8X\n",CurrentCS,CurrentEIP);
+ }
+ Print(OUTPUT_WINDOW,tempShell);
+ PICE_sprintf(tempShell,"pICE: memory referenced %x\n",CurrentCR2);
+ Print(OUTPUT_WINDOW,tempShell);
+ dwCallOldIntEHandler = 1;
+ }
+ else if(dwReasonForBreak == REASON_GP_FAULT)
+ {
+ LPSTR pSymbolName;
+
+ DPRINT((0,"REASON_GPFAULT\n"));
+
+ if( ScanExportsByAddress(&pSymbolName,GetLinearAddress(CurrentCS,CurrentEIP)) )
+ {
+ PICE_sprintf(tempShell,"pICE: Breakpoint due to general protection fault at %.4X:%.8X (%s)\n",CurrentCS,CurrentEIP,pSymbolName);
+ }
+ else
+ {
+ PICE_sprintf(tempShell,"pICE: Breakpoint due to general protection fault at %.4X:%.8X\n",CurrentCS,CurrentEIP);
+ }
+ Print(OUTPUT_WINDOW,tempShell);
+ dwCallOldGPFaultHandler = 1;
+ }
+ else if(dwReasonForBreak == REASON_CTRLF)
+ {
+ DPRINT((0,"REASON_CTRLF\n"));
+ // nothing to do
+ }
+ else if(dwReasonForBreak == REASON_DOUBLE_FAULT)
+ {
+ DPRINT((0,"REASON_DOUBLE_FAULT\n"));
+
+ PICE_sprintf(tempShell,"pICE: Breakpoint due to double fault at %.4X:%.8X\n",CurrentCS,CurrentEIP);
+ Print(OUTPUT_WINDOW,tempShell);
+ }
+ else if(dwReasonForBreak == REASON_INTERNAL_ERROR)
+ {
+ DPRINT((0,"REASON_INTERNAL_ERROR\n"));
+
+ Print(OUTPUT_WINDOW,"pICE: Please report this error to klauspg@diamondmm.com!\n");
+// Print(OUTPUT_WINDOW,"pICE: !!! SYSTEM HALTED !!!\n");
+// __asm__ __volatile__("hlt");
+ }
+ else
+ {
+ DPRINT((0,"REASON_UNKNOWN\n"));
+
+ PICE_sprintf(tempShell,"pICE: Breakpoint due to unknown reason at %.4X:%.8X (code %x)\n",CurrentCS,CurrentEIP,dwReasonForBreak);
+ Print(OUTPUT_WINDOW,tempShell);
+ Print(OUTPUT_WINDOW,"pICE: Please report this error to klauspg@diamondmm.com!\n");
+ Print(OUTPUT_WINDOW,"pICE: !!! SYSTEM HALTED !!!\n");
+ __asm__ __volatile__("hlt");
+ }
+
+ // we don't single-step yet
+ DPRINT((0,"RealIsr(): not stepping yet\n"));
+ bSingleStep=FALSE;
+
+ // process commands
+ if(bSkipMainLoop == FALSE)
+ {
+ DPRINT((0,"RealIsr(): saving registers\n"));
+ // save the extended regs
+ __asm__ __volatile__
+ ("\n\t \
+ pushl %eax\n\t \
+ movw %es,%ax\n\t \
+ movw %ax,_CurrentES\n\t \
+ //movw %fs,%ax\n\t \
+ //movw %ax,_CurrentFS\n\t \
+ movw %gs,%ax\n\t \
+ movw %ax,_CurrentGS\n\t \
+ movl %dr0,%eax\n\t \
+ movl %eax,_CurrentDR0\n\t \
+ movl %dr1,%eax\n\t \
+ movl %eax,_CurrentDR1\n\t \
+ movl %dr2,%eax\n\t \
+ movl %eax,_CurrentDR2\n\t \
+ movl %dr3,%eax\n\t \
+ movl %eax,_CurrentDR3\n\t \
+ movl %dr6,%eax\n\t \
+ movl %eax,_CurrentDR6\n\t \
+ movl %dr7,%eax\n\t \
+ movl %eax,_CurrentDR7\n\t \
+ movl %cr0,%eax\n\t \
+ movl %eax,_CurrentCR0\n\t \
+ movl %cr2,%eax\n\t \
+ movl %eax,_CurrentCR2\n\t \
+ movl %cr3,%eax\n\t \
+ movl %eax,_CurrentCR3\n\t \
+ popl %eax"
+ );
+
+ CurrentFS = OLD_PCR;
+ DPRINT((0,"RealIsr(): adding colon to output()\n"));
+ Print(OUTPUT_WINDOW,":");
+
+ DPRINT((0,"RealIsr(): calling DebuggerShell()\n"));
+ DebuggerShell();
+ }
+
+ // if there was a SW breakpoint at CS:EIP
+ if(NeedToReInstallSWBreakpoints(GetLinearAddress(CurrentCS,CurrentEIP),TRUE) || ReinstallPermanentBp)
+ {
+ DPRINT((0,"need to reinstall INT3\n"));
+ // remember how we restarted last time
+ bPreviousCommandWasGo = !bSingleStep;
+ // do a single step to reinstall breakpoint
+ // modify trace flag
+ CurrentEFL|=0x100; // set trace flag (TF)
+
+ bSingleStep=TRUE;
+ bNotifyToExit=TRUE;
+ }
+
+common_return_point:
+
+ // reset the global flags
+ bNotifyToExit = FALSE;
+ bSkipMainLoop = FALSE;
+
+ // not in handler anymore
+ bInDebuggerShell = FALSE;
+
+ LEAVE_FUNC();
+ DPRINT((0,"common return-----------------------------------------------------------------\n"));
+}
+
+
+__asm__(".global NewInt31Handler\n\t \
+NewInt31Handler:\n\t \
+ cli\n\t \
+ cld\n\t \
+\n\t \
+ pushl %eax\n\t \
+ pushl %ds\n\t \
+\n\t \
+ movw %ss,%ax\n\t \
+ mov %ax,%ds\n\t \
+\n\t \
+ mov 0x4(%esp),%eax\n\t \
+ movl %eax,_CurrentEAX\n\t \
+ movl %ebx,_CurrentEBX\n\t \
+ movl %ecx,_CurrentECX\n\t \
+ movl %edx,_CurrentEDX\n\t \
+ movl %esi,_CurrentESI\n\t \
+ movl %edi,_CurrentEDI\n\t \
+ movl %ebp,_CurrentEBP\n\t \
+ movl (%esp),%eax\n\t \
+ movw %ax,_CurrentDS\n\t \
+\n\t \
+ // test for V86 mode\n\t \
+ testl $0x20000,5*4(%esp)\n\t \
+ jz notV86\n\t \
+\n\t \
+ int $0x03\n\t \
+\n\t \
+notV86:\n\t \
+ // test if stack switched (ring3->ring0 transition)\n\t \
+ // stack is switched if orig. SS is not global kernel code segment\n\t \
+ movl 4*4(%esp),%eax\n\t \
+ cmpw $" STR(GLOBAL_CODE_SEGMENT) ",%ax\n\t \
+ je notswitched\n\t \
+\n\t \
+ // switched stack\n\t \
+ movl 6*4(%esp),%eax\n\t \
+ mov %eax,_CurrentESP\n\t \
+ mov 7*4(%esp),%eax\n\t \
+ movzwl %ax,%eax\n\t \
+ mov %ax,_CurrentSS\n\t \
+ jmp afterswitch\n\t \
+\n\t \
+notswitched:\n\t \
+ // didn't switch stack\n\t \
+ movl %esp,_CurrentESP\n\t \
+ addl $24,_CurrentESP\n\t \
+ movw %ss,%ax\n\t \
+ movzwl %ax,%eax\n\t \
+ mov %ax,_CurrentSS\n\t \
+\n\t \
+afterswitch:\n\t \
+ // save EIP\n\t \
+ mov 3*4(%esp),%eax\n\t \
+ mov %eax,_CurrentEIP\n\t \
+ //save CS\n\t \
+ mov 4*4(%esp),%eax\n\t \
+ movzwl %ax,%eax\n\t \
+ movw %ax,_CurrentCS\n\t \
+ // save flags\n\t \
+ movl 5*4(%esp),%eax\n\t \
+ andl $0xFFFFFEFF,%eax\n\t \
+ movl %eax,_CurrentEFL\n\t \
+\n\t \
+ pushal\n\t \
+\n\t \
+ // get reason code\n\t \
+ mov 0x28(%esp),%ebx\n\t \
+\n\t \
+ /*\n\t \
+ * Load the PCR selector.\n\t \
+ */\n\t \
+\n\t \
+ movl %fs, %eax\n\t \
+ movl %eax, _OLD_PCR\n\t \
+ movl _PCR_SEL, %eax\n\t \
+ movl %eax, %fs\n\t \
+\n\t \
+ // setup a large work stack\n\t \
+ movl %esp,%eax\n\t \
+ movl %eax,_ulRealStackPtr\n\t \
+\n\t \
+ pushl %ebx\n\t \
+ call _RealIsr\n\t \
+ addl $4,%esp\n\t \
+\n\t \
+ pushl %eax\n\t \
+ movl _OLD_PCR, %eax\n\t \
+ movl %eax, %fs\n\t \
+ popl %eax\n\t \
+\n\t \
+ // restore all regs\n\t \
+ popal\n\t \
+\n\t \
+ // do an EOI to IRQ controller (because we definitely pressed some key)\n\t \
+ // TODO: SMP APIC support\n\t \
+ movb $0x20,%al\n\t \
+ outb %al,$0x20\n\t \
+\n\t \
+ popl %ds\n\t \
+ popl %eax\n\t \
+\n\t \
+ // remove reason code\n\t \
+ addl $4,%esp\n\t \
+\n\t \
+ // make EAX available\n\t \
+ pushl %eax\n\t \
+\n\t \
+ // modify or restore EFLAGS\n\t \
+ .byte 0x2e\n\t \
+ mov _CurrentEFL,%eax\n\t \
+ mov %eax,3*4(%esp)\n\t \
+ .byte 0x2e\n\t \
+ movzwl _CurrentCS,%eax\n\t \
+ mov %eax,2*4(%esp)\n\t \
+ .byte 0x2e\n\t \
+ mov _CurrentEIP,%eax\n\t \
+ mov %eax,1*4(%esp)\n\t \
+\n\t \
+ // restore EAX\n\t \
+ popl %eax\n\t \
+\n\t \
+ // do we need to call old INT1 handler\n\t \
+ .byte 0x2e\n\t \
+ cmp $0,_dwCallOldInt1Handler\n\t \
+ je do_iret2\n\t \
+\n\t \
+ // call INT3 handler\n\t \
+ .byte 0x2e\n\t \
+ jmp *_OldInt1Handler\n\t \
+\n\t \
+do_iret2:\n\t \
+ // do we need to call old INT3 handler\n\t \
+ .byte 0x2e\n\t \
+ cmp $0,_dwCallOldInt3Handler\n\t \
+ je do_iret1\n\t \
+\n\t \
+ // call INT3 handler\n\t \
+ .byte 0x2e\n\t \
+ jmp *_OldInt3Handler\n\t \
+\n\t \
+do_iret1:\n\t \
+ // do we need to call old pagefault handler\n\t \
+ .byte 0x2e\n\t \
+ cmp $0,_dwCallOldIntEHandler\n\t \
+ je do_iret3\n\t \
+\n\t \
+ // call old pagefault handler\n\t \
+ .byte 0x2e\n\t \
+ pushl _error_code\n\t \
+ .byte 0x2e\n\t \
+ jmp *_OldIntEHandler\n\t \
+\n\t \
+do_iret3:\n\t \
+ // do we need to call old general protection fault handler\n\t \
+ .byte 0x2e\n\t \
+ cmp $0,_dwCallOldGPFaultHandler\n\t \
+ je do_iret\n\t \
+\n\t \
+ // call old pagefault handler\n\t \
+ .byte 0x2e\n\t \
+ pushl _error_code\n\t \
+ .byte 0x2e\n\t \
+ jmp *_OldGPFaultHandler\n\t \
+\n\t \
+do_iret:\n\t \
+ //ei\n\t \
+ //int3\n\t \
+ iretl ");
+
+//
+// stub for entering via CTRL-F
+//
+// IDTs keyboard IRQ points here
+//
+__asm__ ("\n\t \
+NewGlobalInt31Handler:\n\t \
+ .byte 0x2e\n\t \
+ cmpb $0,_bEnterNow\n\t \
+ jne dotheenter\n\t \
+\n\t \
+ // chain to old handler\n\t \
+ .byte 0x2e\n\t \
+ jmp *_OldGlobalInt31Handler\n\t \
+\n\t \
+dotheenter:\n\t \
+ pushl $" STR(REASON_CTRLF) "\n\t \
+ jmp NewInt31Handler "
+);
+
+void InstallGlobalKeyboardHook(void)
+{
+ ULONG LocalNewGlobalInt31Handler;
+
+ ENTER_FUNC();
+
+ MaskIrqs();
+ if(!OldGlobalInt31Handler)
+ {
+ __asm__("mov $NewGlobalInt31Handler,%0"
+ :"=r" (LocalNewGlobalInt31Handler)
+ :
+ :"eax");
+ OldGlobalInt31Handler=SetGlobalInt(KeyboardIRQL,(ULONG)LocalNewGlobalInt31Handler);
+ }
+ UnmaskIrqs();
+
+ LEAVE_FUNC();
+}
+
+void DeInstallGlobalKeyboardHook(void)
+{
+ ENTER_FUNC();
+
+ MaskIrqs();
+ if(OldGlobalInt31Handler)
+ {
+ SetGlobalInt(KeyboardIRQL,(ULONG)OldGlobalInt31Handler);
+ OldGlobalInt31Handler=0;
+ }
+ UnmaskIrqs();
+
+ LEAVE_FUNC();
+}
+
+
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ shell.h
+
+Abstract:
+
+ HEADER for shell.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+//void InstallKeyboardHook(void);
+//void DeInstallKeyboardHook(void);
+void InstallGlobalKeyboardHook(void);
+void DeInstallGlobalKeyboardHook(void);
+
+void RealIsr(ULONG dwReasonForBreak);
+void NewInt31Handler(void);
+
+extern volatile BOOLEAN bNotifyToExit;
+extern volatile BOOLEAN bSingleStep;
+extern volatile UCHAR ucKeyPressedWhileIdle;
+extern volatile BOOLEAN bInDebuggerShell;
+
+extern ULONG CurrentEIP,CurrentEFL;
+extern ULONG CurrentEAX,CurrentEBX,CurrentECX,CurrentEDX;
+extern ULONG CurrentESP,CurrentEBP,CurrentESI,CurrentEDI;
+extern ULONG CurrentDR0,CurrentDR1,CurrentDR2,CurrentDR3,CurrentDR6,CurrentDR7;
+extern ULONG CurrentCR0,CurrentCR2,CurrentCR3;
+extern USHORT CurrentCS,CurrentDS,CurrentES,CurrentFS,CurrentGS,CurrentSS;
+extern volatile BOOLEAN bControl; // TRUE when CTRL key was pressed
+extern volatile BOOLEAN bShift; // TRUE when SHIFT key was pressed
+extern volatile BOOLEAN bAlt; // TRUE when SHIFT key was pressed
+
+// previous context
+extern ULONG OldEIP,OldEFL;
+extern ULONG OldEAX,OldEBX,OldECX,OldEDX;
+extern ULONG OldESP,OldEBP,OldESI,OldEDI;
+extern USHORT OldCS,OldDS,OldES,OldFS,OldGS,OldSS;
+
+extern ULONG CurrentProcess;
+
+extern USHORT OldSelector;
+extern ULONG OldOffset;
+
+extern ULONG ulRealStackPtr; // serves as current process pointer too!!
+
+extern ULONG g_ulLineNumberStart;
+extern BOOLEAN bStepThroughSource;
+extern BOOLEAN bStepInto;
+
+#define REASON_INT3 (0)
+#define REASON_SINGLESTEP (1)
+#define REASON_CTRLF (2)
+#define REASON_PAGEFAULT (3)
+#define REASON_GP_FAULT (4)
+#define REASON_HARDWARE_BP (5)
+#define REASON_DOUBLE_FAULT (6)
+#define REASON_MODULE_LOAD (7)
+#define REASON_INTERNAL_ERROR (8)
+
+extern volatile BOOLEAN bEnterNow;
+
+// keyboard controller defines
+#define I8042_PHYSICAL_BASE 0x60
+#define I8042_DATA_REGISTER_OFFSET 0
+#define I8042_COMMAND_REGISTER_OFFSET 4
+#define I8042_STATUS_REGISTER_OFFSET 4
+
+void ShowStatusLine(void);
+
+#define KEYBOARD_IRQ 1
--- /dev/null
+/* Table of DBX symbol codes for the GNU system.
+ Copyright (C) 1988, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* New stab from Solaris 2. This uses an n_type of 0, which in a.out files
+ overlaps the N_UNDF used for ordinary symbols. In ELF files, the
+ debug information is in a different file section, so there is no conflict.
+ This symbol's n_value gives the size of the string section associated
+ with this file. The symbol's n_strx (relative to the just-updated
+ string section start address) gives the name of the source file,
+ e.g. "foo.c", without any path information. The symbol's n_desc gives
+ the count of upcoming symbols associated with this file (not including
+ this one). */
+__define_stab (N_UNDF, 0x00, "UNDF")
+
+/* Global variable. Only the name is significant.
+ To find the address, look in the corresponding external symbol. */
+__define_stab (N_GSYM, 0x20, "GSYM")
+
+/* Function name for BSD Fortran. Only the name is significant.
+ To find the address, look in the corresponding external symbol. */
+__define_stab (N_FNAME, 0x22, "FNAME")
+
+/* Function name or text-segment variable for C. Value is its address.
+ Desc is supposedly starting line number, but GCC doesn't set it
+ and DBX seems not to miss it. */
+__define_stab (N_FUN, 0x24, "FUN")
+
+/* Data-segment variable with internal linkage. Value is its address.
+ "Static Sym". */
+__define_stab (N_STSYM, 0x26, "STSYM")
+
+/* BSS-segment variable with internal linkage. Value is its address. */
+__define_stab (N_LCSYM, 0x28, "LCSYM")
+
+/* Name of main routine. Only the name is significant. */
+__define_stab (N_MAIN, 0x2a, "MAIN")
+
+/* Solaris2: Read-only data symbols. */
+__define_stab (N_ROSYM, 0x2c, "ROSYM")
+
+/* Global symbol in Pascal.
+ Supposedly the value is its line number; I'm skeptical. */
+__define_stab (N_PC, 0x30, "PC")
+
+/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */
+__define_stab (N_NSYMS, 0x32, "NSYMS")
+
+/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */
+__define_stab (N_NOMAP, 0x34, "NOMAP")
+
+/* New stab from Solaris 2. Like N_SO, but for the object file. Two in
+ a row provide the build directory and the relative path of the .o from it.
+ Solaris2 uses this to avoid putting the stabs info into the linked
+ executable; this stab goes into the ".stab.index" section, and the debugger
+ reads the real stabs directly from the .o files instead. */
+__define_stab (N_OBJ, 0x38, "OBJ")
+
+/* New stab from Solaris 2. Options for the debugger, related to the
+ source language for this module. E.g. whether to use ANSI
+ integral promotions or traditional integral promotions. */
+__define_stab (N_OPT, 0x3c, "OPT")
+
+/* Register variable. Value is number of register. */
+__define_stab (N_RSYM, 0x40, "RSYM")
+
+/* Modula-2 compilation unit. Can someone say what info it contains? */
+__define_stab (N_M2C, 0x42, "M2C")
+
+/* Line number in text segment. Desc is the line number;
+ value is corresponding address. On Solaris2, the line number is
+ relative to the start of the current function. */
+__define_stab (N_SLINE, 0x44, "SLINE")
+
+/* Similar, for data segment. */
+__define_stab (N_DSLINE, 0x46, "DSLINE")
+
+/* Similar, for bss segment. */
+__define_stab (N_BSLINE, 0x48, "BSLINE")
+
+/* Sun's source-code browser stabs. ?? Don't know what the fields are.
+ Supposedly the field is "path to associated .cb file". THIS VALUE
+ OVERLAPS WITH N_BSLINE! */
+__define_stab_duplicate (N_BROWS, 0x48, "BROWS")
+
+/* GNU Modula-2 definition module dependency. Value is the modification time
+ of the definition file. Other is non-zero if it is imported with the
+ GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there
+ are enough empty fields? */
+__define_stab(N_DEFD, 0x4a, "DEFD")
+
+/* New in Solaris2. Function start/body/end line numbers. */
+__define_stab(N_FLINE, 0x4C, "FLINE")
+
+/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2
+ and one is for C++. Still,... */
+/* GNU C++ exception variable. Name is variable name. */
+__define_stab (N_EHDECL, 0x50, "EHDECL")
+/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */
+__define_stab_duplicate (N_MOD2, 0x50, "MOD2")
+
+/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if
+ this entry is immediately followed by a CAUGHT stab saying what exception
+ was caught. Multiple CAUGHT stabs means that multiple exceptions
+ can be caught here. If Desc is 0, it means all exceptions are caught
+ here. */
+__define_stab (N_CATCH, 0x54, "CATCH")
+
+/* Structure or union element. Value is offset in the structure. */
+__define_stab (N_SSYM, 0x60, "SSYM")
+
+/* Solaris2: Last stab emitted for module. */
+__define_stab (N_ENDM, 0x62, "ENDM")
+
+/* Name of main source file.
+ Value is starting text address of the compilation.
+ If multiple N_SO's appear, the first to contain a trailing / is the
+ compilation directory. The first to not contain a trailing / is the
+ source file name, relative to the compilation directory. Others (perhaps
+ resulting from cfront) are ignored.
+ On Solaris2, value is undefined, but desc is a source-language code. */
+
+__define_stab (N_SO, 0x64, "SO")
+
+/* Automatic variable in the stack. Value is offset from frame pointer.
+ Also used for type descriptions. */
+__define_stab (N_LSYM, 0x80, "LSYM")
+
+/* Beginning of an include file. Only Sun uses this.
+ In an object file, only the name is significant.
+ The Sun linker puts data into some of the other fields. */
+__define_stab (N_BINCL, 0x82, "BINCL")
+
+/* Name of sub-source file (#include file).
+ Value is starting text address of the compilation. */
+__define_stab (N_SOL, 0x84, "SOL")
+
+/* Parameter variable. Value is offset from argument pointer.
+ (On most machines the argument pointer is the same as the frame pointer. */
+__define_stab (N_PSYM, 0xa0, "PSYM")
+
+/* End of an include file. No name.
+ This and N_BINCL act as brackets around the file's output.
+ In an object file, there is no significant data in this entry.
+ The Sun linker puts data into some of the fields. */
+__define_stab (N_EINCL, 0xa2, "EINCL")
+
+/* Alternate entry point. Value is its address. */
+__define_stab (N_ENTRY, 0xa4, "ENTRY")
+
+/* Beginning of lexical block.
+ The desc is the nesting level in lexical blocks.
+ The value is the address of the start of the text for the block.
+ The variables declared inside the block *precede* the N_LBRAC symbol.
+ On Solaris2, the value is relative to the start of the current function. */
+__define_stab (N_LBRAC, 0xc0, "LBRAC")
+
+/* Place holder for deleted include file. Replaces a N_BINCL and everything
+ up to the corresponding N_EINCL. The Sun linker generates these when
+ it finds multiple identical copies of the symbols from an include file.
+ This appears only in output from the Sun linker. */
+__define_stab (N_EXCL, 0xc2, "EXCL")
+
+/* Modula-2 scope information. Can someone say what info it contains? */
+__define_stab (N_SCOPE, 0xc4, "SCOPE")
+
+/* End of a lexical block. Desc matches the N_LBRAC's desc.
+ The value is the address of the end of the text for the block.
+ On Solaris2, the value is relative to the start of the current function. */
+__define_stab (N_RBRAC, 0xe0, "RBRAC")
+
+/* Begin named common block. Only the name is significant. */
+__define_stab (N_BCOMM, 0xe2, "BCOMM")
+
+/* End named common block. Only the name is significant
+ (and it should match the N_BCOMM). */
+__define_stab (N_ECOMM, 0xe4, "ECOMM")
+
+/* Member of a common block; value is offset within the common block.
+ This should occur within a BCOMM/ECOMM pair. */
+__define_stab (N_ECOML, 0xe8, "ECOML")
+
+/* Solaris2: Pascal "with" statement: type,,0,0,offset */
+__define_stab (N_WITH, 0xea, "WITH")
+
+/* These STAB's are used on Gould systems for Non-Base register symbols
+ or something like that. FIXME. I have assigned the values at random
+ since I don't have a Gould here. Fixups from Gould folk welcome... */
+__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
+__define_stab (N_NBDATA, 0xF2, "NBDATA")
+__define_stab (N_NBBSS, 0xF4, "NBBSS")
+__define_stab (N_NBSTS, 0xF6, "NBSTS")
+__define_stab (N_NBLCS, 0xF8, "NBLCS")
+
+/* Second symbol entry containing a length-value for the preceding entry.
+ The value is the length. */
+__define_stab (N_LENG, 0xfe, "LENG")
+\f
+/* The above information, in matrix format.
+
+ STAB MATRIX
+ _________________________________________________
+ | 00 - 1F are not dbx stab symbols |
+ | In most cases, the low bit is the EXTernal bit|
+
+ | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA |
+ | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT |
+
+ | 08 BSS | 0A INDR | 0C FN_SEQ | 0E WEAKA |
+ | 09 |EXT | 0B | 0D WEAKU | 0F WEAKT |
+
+ | 10 WEAKD | 12 COMM | 14 SETA | 16 SETT |
+ | 11 WEAKB | 13 | 15 | 17 |
+
+ | 18 SETD | 1A SETB | 1C SETV | 1E WARNING|
+ | 19 | 1B | 1D | 1F FN |
+
+ |_______________________________________________|
+ | Debug entries with bit 01 set are unused. |
+ | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM |
+ | 28 LCSYM | 2A MAIN | 2C ROSYM | 2E |
+ | 30 PC | 32 NSYMS | 34 NOMAP | 36 |
+ | 38 OBJ | 3A | 3C OPT | 3E |
+ | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE |
+ | 48 BSLINE*| 4A DEFD | 4C FLINE | 4E |
+ | 50 EHDECL*| 52 | 54 CATCH | 56 |
+ | 58 | 5A | 5C | 5E |
+ | 60 SSYM | 62 ENDM | 64 SO | 66 |
+ | 68 | 6A | 6C | 6E |
+ | 70 | 72 | 74 | 76 |
+ | 78 | 7A | 7C | 7E |
+ | 80 LSYM | 82 BINCL | 84 SOL | 86 |
+ | 88 | 8A | 8C | 8E |
+ | 90 | 92 | 94 | 96 |
+ | 98 | 9A | 9C | 9E |
+ | A0 PSYM | A2 EINCL | A4 ENTRY | A6 |
+ | A8 | AA | AC | AE |
+ | B0 | B2 | B4 | B6 |
+ | B8 | BA | BC | BE |
+ | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 |
+ | C8 | CA | CC | CE |
+ | D0 | D2 | D4 | D6 |
+ | D8 | DA | DC | DE |
+ | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 |
+ | E8 ECOML | EA WITH | EC | EE |
+ | F0 | F2 | F4 | F6 |
+ | F8 | FA | FC | FE LENG |
+ +-----------------------------------------------+
+ * 50 EHDECL is also MOD2.
+ * 48 BSLINE is also BROWS.
+ */
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ stab_gnu.h
+
+Abstract:
+
+ HEADER, GNU stabs symbols
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+#ifndef __GNU_STAB__
+
+/* Indicate the GNU stab.h is in use. */
+
+#define __GNU_STAB__
+
+#define __define_stab(NAME, CODE, STRING) NAME=CODE,
+#define __define_stab_duplicate(NAME, CODE, STRING) NAME=CODE,
+
+enum __stab_debug_code
+{
+#include "stab.def"
+LAST_UNUSED_STAB_CODE
+};
+
+#undef __define_stab
+
+/* Definitions of "desc" field for N_SO stabs in Solaris2. */
+
+#define N_SO_AS 1
+#define N_SO_C 2
+#define N_SO_ANSI_C 3
+#define N_SO_CC 4 /* C++ */
+#define N_SO_FORTRAN 5
+#define N_SO_PASCAL 6
+
+/* Solaris2: Floating point type values in basic types. */
+
+#define NF_NONE 0
+#define NF_SINGLE 1 /* IEEE 32-bit */
+#define NF_DOUBLE 2 /* IEEE 64-bit */
+#define NF_COMPLEX 3 /* Fortran complex */
+#define NF_COMPLEX16 4 /* Fortran double complex */
+#define NF_COMPLEX32 5 /* Fortran complex*16 */
+#define NF_LDOUBLE 6 /* Long double (whatever that is) */
+
+#endif /* __GNU_STAB_ */
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module ModuleName:
+
+ symbols.c
+
+Abstract:
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+ Reactos Port by Eugene Ingerman
+
+Revision History:
+
+ 19-Aug-1998: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+#include "stab_gnu.h"
+
+#include <ntdll/ldr.h>
+#include <ntdll/rtl.h>
+#include <internal/ps.h>
+#include <internal/ob.h>
+#include <internal/module.h>
+
+#define NDEBUG
+#include <debug.h>
+
+
+PVOID pExports=0;
+ULONG ulExportLen=0;
+
+LOCAL_VARIABLE local_vars[512];
+
+PICE_SYMBOLFILE_HEADER* apSymbols[32]={NULL,};
+ULONG ulNumSymbolsLoaded=0;
+
+ULONG kernel_end=0;
+
+char tempSym[1024]; // temp buffer for output
+
+
+PULONG LocalRegs[]=
+{
+ &CurrentEAX,
+ &CurrentECX,
+ &CurrentEDX,
+ &CurrentEBX,
+ &CurrentESP,
+ &CurrentEBP,
+ &CurrentESI,
+ &CurrentEDI,
+ &CurrentEIP,
+ &CurrentEFL
+};
+
+typedef struct _VRET
+{
+ ULONG value;
+ ULONG type;
+ ULONG father_type;
+ ULONG error;
+ ULONG file;
+ ULONG size;
+ ULONG address;
+ char name[256];
+ char type_name[256];
+ BOOLEAN bPtrType;
+ BOOLEAN bStructType;
+ BOOLEAN bArrayType;
+ PICE_SYMBOLFILE_HEADER* pSymbols;
+}VRET,*PVRET;
+
+ULONG ulIndex;
+LPSTR pExpression;
+VRET vr;
+VRET vrStructMembers[1024];
+ULONG ulNumStructMembers;
+
+BOOLEAN Expression(PVRET pvr);
+
+LIST_ENTRY *pModuleListHead = NULL;
+extern PDIRECTORY_OBJECT *pNameSpaceRoot;
+extern PDEBUG_MODULE pdebug_module_tail;
+extern PDEBUG_MODULE pdebug_module_head;
+
+
+PVOID HEADER_TO_BODY(POBJECT_HEADER obj)
+{
+ return(((void *)obj)+sizeof(OBJECT_HEADER)-sizeof(COMMON_BODY_HEADER));
+}
+
+POBJECT_HEADER BODY_TO_HEADER(PVOID body)
+{
+ PCOMMON_BODY_HEADER chdr = (PCOMMON_BODY_HEADER)body;
+ return(CONTAINING_RECORD((&(chdr->Type)),OBJECT_HEADER,Type));
+}
+
+/*-----------------12/26/2001 7:59PM----------------
+ * FreeModuleList - free list allocated with InitModuleList. Must
+ * be called at passive irql.
+ * --------------------------------------------------*/
+VOID FreeModuleList( PDEBUG_MODULE pm )
+{
+ PDEBUG_MODULE pNext = pm;
+
+ ENTER_FUNC();
+
+ while( pNext ){
+ pNext = pm->next;
+ ExFreePool( pm );
+ }
+ LEAVE_FUNC();
+}
+
+/*-----------------12/26/2001 7:58PM----------------
+ * InitModuleList - creates linked list of length len for debugger. Can't be
+ * called at elevated IRQL
+ * --------------------------------------------------*/
+BOOLEAN InitModuleList( PDEBUG_MODULE *ppmodule, ULONG len )
+{
+ ULONG i;
+ PDEBUG_MODULE pNext = NULL, pm = *ppmodule;
+
+ ENTER_FUNC();
+
+ ASSERT(pm==NULL);
+
+ for(i=1;i<=len;i++){
+ pm = (PDEBUG_MODULE)ExAllocatePool( NonPagedPool, sizeof( DEBUG_MODULE ) );
+ if( !pm ){
+ FreeModuleList(pNext);
+ return FALSE;
+ }
+ pm->next = pNext;
+ pm->size = 0;
+ pm->BaseAddress = NULL;
+ //DbgPrint("len1: %d\n", pm->name.Length);
+ pNext = pm;
+ }
+ *ppmodule = pm;
+
+ LEAVE_FUNC();
+
+ return TRUE;
+}
+
+BOOLEAN ListUserModules( PPEB peb )
+{
+ PLIST_ENTRY UserModuleListHead;
+ PLIST_ENTRY Entry;
+ PLDR_DATA_TABLE_ENTRY Module;
+ PPEB_LDR_DATA Ldr;
+
+ ENTER_FUNC();
+
+ Ldr = peb->Ldr;
+ if( Ldr && IsAddressValid((ULONG)Ldr)){
+ UserModuleListHead = &Ldr->InLoadOrderModuleList;
+ ASSERT(IsAddressValid((ULONG)UserModuleListHead));
+ Entry = UserModuleListHead->Flink;
+ while (Entry != UserModuleListHead)
+ {
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
+ //DbgPrint("Module: %x, BaseAddress: %x\n", Module, Module->BaseAddress);
+
+ DPRINT((0,"FullName: %S, BaseName: %S, Length: %ld, EntryPoint: %x, BaseAddress: %x\n", Module->FullDllName.Buffer,
+ Module->BaseDllName.Buffer, Module->SizeOfImage, Module->EntryPoint, Module->BaseAddress ));
+
+ pdebug_module_tail->size = Module->SizeOfImage;
+ pdebug_module_tail->BaseAddress = Module->BaseAddress;
+ pdebug_module_tail->EntryPoint = (PVOID)(Module->EntryPoint);
+ ASSERT(Module->BaseDllName.Length<DEBUG_MODULE_NAME_LEN); //name length is limited
+ PICE_wcscpy( pdebug_module_tail->name, Module->BaseDllName.Buffer );
+ pdebug_module_tail = pdebug_module_tail->next;
+
+ Entry = Entry->Flink;
+ }
+ }
+ LEAVE_FUNC();
+ return TRUE;
+}
+
+POBJECT FindDriverObjectDirectory( void )
+{
+ PLIST_ENTRY current;
+ POBJECT_HEADER current_obj;
+ PDIRECTORY_OBJECT pd;
+
+ ENTER_FUNC();
+
+ if( pNameSpaceRoot && *pNameSpaceRoot ){
+ current = (*pNameSpaceRoot)->head.Flink;
+ while (current!=(&((*pNameSpaceRoot)->head)))
+ {
+ current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);
+ DPRINT((0,"Scanning %S\n",current_obj->Name.Buffer));
+ if (_wcsicmp(current_obj->Name.Buffer, L"Modules")==0)
+ {
+ pd=HEADER_TO_BODY(current_obj);
+ DPRINT((0,"Found it %x\n",pd));
+ return pd;
+ }
+ current = current->Flink;
+ }
+ }
+ LEAVE_FUNC();
+ return NULL;
+}
+
+BOOLEAN ListDriverModules( void )
+{
+ PLIST_ENTRY current_entry;
+ PMODULE_OBJECT current;
+ POBJECT_HEADER current_obj;
+
+ ENTER_FUNC();
+
+ ASSERT( pModuleListHead );
+
+ current_entry = pModuleListHead->Flink;
+
+ while (current_entry != (pModuleListHead)){
+
+ current = CONTAINING_RECORD(current_entry,MODULE_OBJECT,ListEntry);
+
+ DPRINT((0,"FullName: %S, BaseName: %S, Length: %ld, EntryPoint: %x\n", current->FullName.Buffer,
+ current->BaseName.Buffer, current->Length, current->EntryPoint ));
+
+ pdebug_module_tail->BaseAddress = current->Base;
+ pdebug_module_tail->size = current->Length;
+ PICE_wcscpy( pdebug_module_tail->name, current->BaseName.Buffer);
+ pdebug_module_tail->EntryPoint = current->EntryPoint;
+
+ pdebug_module_tail = pdebug_module_tail->next;
+
+ if (current && _wcsicmp(current->BaseName.Buffer, L"ntoskrnl")==0)
+ {
+ kernel_end = (ULONG)current->Base + current->Length;
+ }
+ current_entry = current_entry->Flink;
+ }
+
+ LEAVE_FUNC();
+ return TRUE;
+}
+
+BOOLEAN BuildModuleList( void )
+{
+ PPEB peb;
+ PEPROCESS tsk;
+ ENTER_FUNC();
+
+ pdebug_module_tail = pdebug_module_head;
+ tsk = IoGetCurrentProcess();
+ ASSERT(IsAddressValid((ULONG)tsk));
+ if( tsk ){
+ peb = tsk->Peb;
+ if( peb ){
+ if( !ListUserModules( peb ) ){
+ LEAVE_FUNC();
+ return FALSE;
+ }
+ }
+ }
+ if( !ListDriverModules() ){
+ LEAVE_FUNC();
+ return FALSE;
+ }
+ LEAVE_FUNC();
+ return TRUE;
+}
+
+//*************************************************************************
+// IsModuleLoaded()
+//
+//*************************************************************************
+PDEBUG_MODULE IsModuleLoaded(LPSTR p)
+{
+ PDEBUG_MODULE pd;
+
+ ENTER_FUNC();
+ DPRINT((0,"IsModuleLoaded(%s)\n",p));
+
+ if(BuildModuleList())
+ {
+ pd = pdebug_module_head;
+ do
+ {
+ char temp[DEBUG_MODULE_NAME_LEN];
+ DPRINT((0,"module (%x) %S\n",pd->size,pd->name));
+ CopyWideToAnsi(temp,pd->name);
+ if(pd->size && PICE_strcmpi(p,temp) == 0)
+ {
+ DPRINT((0,"module %S is loaded!\n",pd->name));
+ LEAVE_FUNC();
+ return pd;
+ }
+ }while((pd = pd->next)!=pdebug_module_tail);
+ }
+ LEAVE_FUNC();
+ return NULL;
+}
+
+//*************************************************************************
+// ScanExports()
+//
+//*************************************************************************
+BOOLEAN ScanExports(const char *pFind,PULONG pValue)
+{
+ char temp[256];
+ LPSTR pStr=NULL;
+ LPSTR pExp = pExports;
+ BOOLEAN bResult = FALSE;
+
+ ENTER_FUNC();
+ DPRINT((0,"ScanExports pValue: %x\n", pValue));
+nomatch:
+ if(pExports)
+ pStr = strstr(pExp,pFind);
+
+ if(pStr)
+ {
+ LPSTR p;
+ ULONG state;
+ LPSTR pOldStr = pStr;
+
+ for(;(*pStr!=0x0a && *pStr!=0x0d) && (ULONG)pStr>=(ULONG)pExports;pStr--);
+ pStr++;
+ p = temp;
+ for(;(*pStr!=0x0a && *pStr!=0x0d);)*p++=*pStr++;
+ *p=0;
+ p = (LPSTR) PICE_strtok(temp," ");
+ state=0;
+ while(p)
+ {
+ switch(state)
+ {
+ case 0:
+ ConvertTokenToHex(p,pValue);
+ break;
+ case 1:
+ break;
+ case 2:
+ if(strcmp(p,pFind)!=0)
+ {
+ DPRINT((0,"Not: %s\n", p));
+ pExp = pOldStr+1;
+ goto nomatch;
+ }
+ state = -1;
+ bResult = TRUE;
+ DPRINT((0,"%s @ %x\n",pFind,*pValue));
+ goto exit;
+ break;
+ }
+ state++;
+ p = (char*) PICE_strtok(NULL," ");
+ }
+ }
+exit:
+ DPRINT((0,"%s %x @ %x\n",pFind,pValue,*pValue));
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+//*************************************************************************
+// ReadHex()
+//
+//*************************************************************************
+BOOLEAN ReadHex(LPSTR p,PULONG pValue)
+{
+ ULONG result=0,i;
+
+ for(i=0;i<8 && p[i]!=0 && p[i]!=' ';i++)
+ {
+ if(p[i]>='0' && p[i]<='9')
+ {
+ result<<=4;
+ result|=(ULONG)(UCHAR)(p[i]-'0');
+ }
+ else if(p[i]>='A' && p[i]<='F')
+ {
+ result<<=4;
+ result|=(ULONG)(UCHAR)(p[i]-'A'+10);
+ }
+ else if(p[i]>='a' && p[i]<='f')
+ {
+ result<<=4;
+ result|=(ULONG)(UCHAR)(p[i]-'a'+10);
+ }
+ else
+ return FALSE;
+ }
+
+ *pValue = result;
+ return TRUE;
+}
+
+//*************************************************************************
+// ScanExportLine()
+//
+//*************************************************************************
+BOOLEAN ScanExportLine(LPSTR p,PULONG ulValue,LPSTR* ppPtrToSymbol)
+{
+ BOOLEAN bResult = FALSE;
+
+ if(ReadHex(p,ulValue))
+ {
+ p += 11;
+ *ppPtrToSymbol += 11;
+ bResult = TRUE;
+ }
+
+ return bResult;
+}
+
+//*************************************************************************
+// ValidityCheckSymbols()
+//
+//*************************************************************************
+BOOLEAN ValidityCheckSymbols(PICE_SYMBOLFILE_HEADER* pSymbols)
+{
+ BOOLEAN bRet;
+
+ DPRINT((0,"ValidityCheckSymbols()\n"));
+
+ bRet = (IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToHeaders,pSymbols->ulSizeOfHeader) &&
+ IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToGlobals,pSymbols->ulSizeOfGlobals) &&
+ IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToGlobalsStrings,pSymbols->ulSizeOfGlobalsStrings) &&
+ IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToStabs,pSymbols->ulSizeOfStabs) &&
+ IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings,pSymbols->ulSizeOfStabsStrings));
+
+ DPRINT((0,"ValidityCheckSymbols(): symbols are %s\n",bRet?"VALID":"NOT VALID"));
+
+ return bRet;
+}
+
+//*************************************************************************
+// FindModuleSymbols()
+//
+//*************************************************************************
+PICE_SYMBOLFILE_HEADER* FindModuleSymbols(ULONG addr)
+{
+ ULONG start,end,i;
+ PDEBUG_MODULE pd = pdebug_module_head;
+
+ DPRINT((0,"FindModuleSymbols(%x)\n",addr));
+ if(BuildModuleList())
+ {
+ i=0;
+ pd = pdebug_module_head;
+ do
+ {
+ DPRINT((0,"pd: %x\n", pd));
+ if(pd->size)
+ {
+ start = (ULONG)pd->BaseAddress;
+ end = start + pd->size;
+ DPRINT((0,"FindModuleSymbols(): %S %x-%x\n",pd->name,start,end));
+ if(addr>=start && addr<end)
+ {
+ DPRINT((0,"FindModuleSymbols(): address matches %S %x-%x\n",pd->name,start,end));
+ for(i=0;i<ulNumSymbolsLoaded;i++)
+ {
+ DPRINT((0,"%S -", apSymbols[i]->name ));
+ if(PICE_wcsicmp(pd->name,apSymbols[i]->name) == 0)
+ {
+ if(ValidityCheckSymbols(apSymbols[i]))
+ return apSymbols[i];
+ else
+ return NULL;
+ }
+ }
+ }
+ }
+ }while((pd = pd->next) != pdebug_module_tail);
+ }
+
+ return NULL;
+}
+
+//*************************************************************************
+// FindModuleFromAddress()
+//
+//*************************************************************************
+PDEBUG_MODULE FindModuleFromAddress(ULONG addr)
+{
+ PDEBUG_MODULE pd;
+ ULONG start,end;
+
+ DPRINT((0,"FindModuleFromAddress()\n"));
+ if(BuildModuleList())
+ {
+ pd = pdebug_module_head;
+ do
+ {
+ if(pd->size)
+ {
+ start = (ULONG)pd->BaseAddress;
+ end = start + pd->size;
+ DPRINT((0,"FindModuleFromAddress(): %S %x-%x\n",pd->name,start,end));
+ if(addr>=start && addr<end)
+ {
+ DPRINT((0,"FindModuleFromAddress(): found %S\n",pd->name));
+ return pd;
+ }
+ }
+ }while((pd = pd->next)!=pdebug_module_tail);
+ }
+
+ return NULL;
+}
+
+//*************************************************************************
+// FindModuleByName()
+//
+//*************************************************************************
+PDEBUG_MODULE FindModuleByName(LPSTR modname)
+{
+ PDEBUG_MODULE pd;
+ WCHAR tempstr[DEBUG_MODULE_NAME_LEN];
+
+ DPRINT((0,"FindModuleFromAddress()\n"));
+ if( !PICE_MultiByteToWideChar(CP_ACP, NULL, modname, -1, tempstr, DEBUG_MODULE_NAME_LEN ) )
+ {
+ DPRINT((0,"Can't convert module name.\n"));
+ return NULL;
+ }
+
+ if(BuildModuleList())
+ {
+ pd = pdebug_module_head;
+ do
+ {
+ if(pd->size)
+ {
+ if(PICE_wcsicmp(tempstr,pd->name) == 0)
+ {
+ DPRINT((0,"FindModuleByName(): found %S\n",pd->name));
+ return pd;
+ }
+ }
+ }while((pd = pd->next) != pdebug_module_tail);
+ }
+
+ return NULL;
+}
+
+//*************************************************************************
+// FindModuleSymbolsByModuleName()
+//
+//*************************************************************************
+PICE_SYMBOLFILE_HEADER* FindModuleSymbolsByModuleName(LPSTR modname)
+{
+ ULONG i;
+ WCHAR tempstr[DEBUG_MODULE_NAME_LEN];
+
+ DPRINT((0,"FindModuleSymbols()\n"));
+ if( !PICE_MultiByteToWideChar(CP_ACP, NULL, modname, -1, tempstr, DEBUG_MODULE_NAME_LEN ) )
+ {
+ DPRINT((0,"Can't convert module name in FindModuleSymbols.\n"));
+ return NULL;
+ }
+
+ for(i=0;i<ulNumSymbolsLoaded;i++)
+ {
+ if(PICE_wcsicmp(tempstr,apSymbols[i]->name) == 0)
+ return apSymbols[i];
+ }
+
+ return NULL;
+}
+
+//*************************************************************************
+// ScanExportsByAddress()
+//
+//*************************************************************************
+BOOLEAN ScanExportsByAddress(LPSTR *pFind,ULONG ulValue)
+{
+ char temp[256];
+ static char temp3[256];
+ LPSTR p,pStartOfLine,pSymbolName=NULL;
+ ULONG ulCurrentValue=0;
+ BOOLEAN bResult = FALSE;
+ PDEBUG_MODULE pd;
+ ULONG ulMinValue = -1;
+ PIMAGE_SYMBOL pSym,pSymEnd; //running pointer to symbols and end of sym talbe
+ PIMAGE_SYMBOL pFoundSym = NULL; //current best symbol match
+ ULONG ulAddr = 0x0; //address of the best match
+ LPSTR pStr;
+ PIMAGE_SECTION_HEADER pShdr;
+ PICE_SYMBOLFILE_HEADER* pSymbols;
+ ULONG ulSectionSize;
+ LPSTR pName;
+
+ ENTER_FUNC();
+ DPRINT((0,"In ScanExportsByAddress:\n"));
+
+ pSymbols = FindModuleSymbols(ulValue);
+ DPRINT((0,"pSymbols: %x\n", pSymbols));
+
+ if(BuildModuleList()){
+ if(pSymbols && pdebug_module_head)
+ {
+ PDEBUG_MODULE pdTemp;
+
+ DPRINT((0,"looking up symbols\n"));
+ pd = pdebug_module_head;
+ do
+ {
+ if(pd->size){
+ pdTemp = pd;
+
+ if(ulValue>=((ULONG)pdTemp->BaseAddress) && ulValue<((ULONG)pdTemp+pdTemp->size))
+ {
+ if(PICE_wcsicmp(pdTemp->name,pSymbols->name) == 0)
+ {
+ DPRINT((0,"ScanExportsByAddress(): found symbols for module %S @ %x \n",pdTemp->name,(ULONG)pSymbols));
+
+ pSym = (PIMAGE_SYMBOL)((ULONG)pSymbols+pSymbols->ulOffsetToGlobals);
+ pSymEnd = (PIMAGE_SYMBOL)((ULONG)pSym+pSymbols->ulSizeOfGlobals);
+ pStr = (LPSTR)((ULONG)pSymbols+pSymbols->ulOffsetToGlobalsStrings);
+ pShdr = (PIMAGE_SECTION_HEADER)((ULONG)pSymbols+pSymbols->ulOffsetToHeaders);
+
+ if(!IsRangeValid((ULONG)pSym,sizeof(IMAGE_SYMBOL) ) ) //should we actually check all the symbols here?
+ {
+ DPRINT((0,"ScanExportsByAddress(): pSym = %x is not a valid pointer\n",(ULONG)pSym));
+ return FALSE;
+ }
+
+ DPRINT((0,"ScanExportsByAddress(): pSym = %x\n",pSym));
+ DPRINT((0,"ScanExportsByAddress(): pStr = %x\n",pStr));
+ DPRINT((0,"ScanExportsByAddress(): pShdr = %x\n",pShdr));
+
+ DPRINT((0,"ScanExportsByAddress(): %S has %u symbols\n",pSymbols->name,pSymbols->ulSizeOfGlobals/sizeof(IMAGE_SYMBOL)));
+
+ /* go through all the global symbols and find the one with
+ the largest address which is less than ulValue */
+ while(pSym < pSymEnd)
+ { //it seems only 0x0 and 0x20 are used for type and External or Static storage classes
+ if(((pSym->Type == 0x0) || (pSym->Type == 0x20) ) &&
+ ((pSym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) || (pSym->StorageClass==IMAGE_SYM_CLASS_STATIC)) &&
+ (pSym->SectionNumber > 0 ))
+ {
+ ULONG ulCurrAddr;
+ PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pSym->SectionNumber-1);
+
+
+ DPRINT((0,"ScanExportsByAddress(): pShdr[%x] = %x\n",pSym->SectionNumber,(ULONG)pShdrThis));
+
+ if(!IsRangeValid((ULONG)pShdrThis,sizeof(IMAGE_SECTION_HEADER)) )
+ {
+ DPRINT((0,"ScanExportsByAddress(): pElfShdr[%x] = %x is not a valid pointer\n",pSym->SectionNumber,(ULONG)pShdrThis));
+ return FALSE;
+ }
+ //to get address in the memory we base address of the module and
+ //add offset of the section and then add offset of the symbol from
+ //the begining of the section
+ ulCurrAddr = ((ULONG)pdTemp->BaseAddress+pShdrThis->VirtualAddress+pSym->Value);
+ DPRINT((0,"ScanExportsByAddress(): CurrAddr [1] = %x\n",ulCurrAddr));
+
+ if(ulCurrAddr<=ulValue && ulCurrAddr>ulAddr)
+ {
+ ulAddr = ulCurrAddr;
+ pFoundSym = pSym;
+ }
+ }
+ //skip the auxiliary symbols and get the next symbol
+ pSym += pSym->NumberOfAuxSymbols + 1;
+ }
+ *pFind = temp3;
+ if( pFoundSym->N.Name.Short ){
+ pName = pFoundSym->N.ShortName; //name is in the header
+ PICE_sprintf(temp3,"%S!%.8s",pdTemp->name,pName); //if name is in the header it may be nonzero terminated
+ }
+ else{
+ ASSERT(pFoundSym->N.Name.Long<=pSymbols->ulSizeOfGlobalsStrings); //sanity check
+ pName = pStr+pFoundSym->N.Name.Long;
+ if(!IsAddressValid((ULONG)pName))
+ {
+ DPRINT((0,"ScanExportsByAddress(): pName = %x is not a valid pointer\n",pName));
+ return FALSE;
+ }
+ PICE_sprintf(temp3,"%S!%s",pdTemp->name,pName);
+ }
+ DPRINT((0,"ScanExportsByAddress(): pName = %x\n",(ULONG)pName));
+ return TRUE;
+ }
+ }
+ }
+ }while((pd = pd->next));
+ }
+ }
+ // if haven't found in the symbols try ntoskrnl exports. (note: check that this is needed since we
+ // already checked ntoskrnl coff symbol table)
+ if(pExports && ulValue >= KERNEL_START && ulValue < kernel_end)
+ {
+ p = pExports;
+ // while we bound in System.map
+ while(p<((LPSTR)pExports+ulExportLen))
+ {
+ // make a temp ptr to the line we can change
+ pStartOfLine = p;
+ // will read the hex value and return a pointer to the symbol name
+ if(ScanExportLine(p,&ulCurrentValue,&pStartOfLine))
+ {
+ if(ulValue>=ulCurrentValue && (ulValue-ulCurrentValue)<ulMinValue)
+ {
+ // save away our info for later
+ ulMinValue = ulValue-ulCurrentValue;
+ pSymbolName = pStartOfLine;
+ bResult = TRUE;
+ *pFind = temp3;
+ if(ulMinValue==0)
+ break;
+ }
+ }
+ // increment pointer to next line
+ p = pStartOfLine;
+ while(*p!=0 && *p!=0x0a && *p!=0x0d)p++;
+ p++;
+ }
+ if(bResult)
+ {
+ int i;
+ // copy symbol name to temp string
+ for(i=0;pSymbolName[i]!=0 && pSymbolName[i]!=0x0a && pSymbolName[i]!=0x0d;i++)
+ temp[i] = pSymbolName[i];
+ temp[i] = 0;
+ // decide if we need to append an offset
+ if(ulMinValue)
+ PICE_sprintf(temp3,"ntoskrnl!%s+%.8X",temp,ulMinValue);
+ else
+ PICE_sprintf(temp3,"ntoskrnl!%s",temp);
+ }
+ }
+
+ LEAVE_FUNC();
+ return bResult;
+}
+
+//*************************************************************************
+// FindFunctionByAddress()
+//
+//*************************************************************************
+LPSTR FindFunctionByAddress(ULONG ulValue,PULONG pulstart,PULONG pulend)
+{
+ PIMAGE_SYMBOL pSym, pSymEnd, pFoundSym;
+ LPSTR pStr;
+ PIMAGE_SECTION_HEADER pShdr;
+ PDEBUG_MODULE pd;
+ PDEBUG_MODULE pdTemp;
+ PICE_SYMBOLFILE_HEADER* pSymbols;
+ ULONG start,end;
+ static char temp4[256];
+ LPSTR pName;
+
+ pSymbols = FindModuleSymbols(ulValue);
+ DPRINT((0,"FindFunctionByAddress(): symbols for %S @ %x \n",pSymbols->name,(ULONG)pSymbols));
+ if(pSymbols && pdebug_module_head)
+ {
+ DPRINT((0,"looking up symbol\n"));
+ pd = pdebug_module_head;
+ do
+ {
+ ASSERT(pd->size);
+ pdTemp = pd;
+
+ //initial values for start and end.
+ start = (ULONG)pdTemp->BaseAddress;
+ end = start+pdTemp->size;
+
+ DPRINT((0,"FindFunctionByAddress(): ulValue %x\n",ulValue));
+
+ if(ulValue>=start && ulValue<end)
+ {
+ DPRINT((0,"FindFunctionByAddress(): address matches %S\n",(ULONG)pdTemp->name));
+ if(PICE_wcsicmp(pdTemp->name,pSymbols->name) == 0)
+ {
+ DPRINT((0,"found symbols for module %S\n",pdTemp->name));
+ pSym = (PIMAGE_SYMBOL)((ULONG)pSymbols+pSymbols->ulOffsetToGlobals);
+ pSymEnd = (PIMAGE_SYMBOL)((ULONG)pSym+pSymbols->ulSizeOfGlobals);
+ pStr = (LPSTR)((ULONG)pSymbols+pSymbols->ulOffsetToGlobalsStrings);
+ pShdr = (PIMAGE_SECTION_HEADER)((ULONG)pSymbols+pSymbols->ulOffsetToHeaders);
+
+ if(!IsRangeValid((ULONG)pSym,sizeof(IMAGE_SYMBOL) ) ) //should we actually check all the symbols here?
+ {
+ DPRINT((0,"FindFunctionByAddress(): pSym = %x is not a valid pointer\n",(ULONG)pSym));
+ return FALSE;
+ }
+ DPRINT((0,"pSym = %x\n",pSym));
+ DPRINT((0,"pStr = %x\n",pStr));
+ DPRINT((0,"pShdr = %x\n",pShdr));
+
+ while( pSym < pSymEnd )
+ {
+ //symbol is a function is it's type is 0x20, and section>0
+ if(( (pSym->Type == 0x20) &&
+ (pSym->SectionNumber > 0 )))
+ {
+ ULONG ulCurrAddr;
+ PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pSym->SectionNumber-1);
+
+ DPRINT((0,"FindFunctionByAddress(): pShdr[%x] = %x\n",pSym->SectionNumber,(ULONG)pShdrThis));
+
+ if(!IsRangeValid((ULONG)pShdrThis,sizeof(IMAGE_SECTION_HEADER)) )
+ {
+ DPRINT((0,"ScanExportsByAddress(): pElfShdr[%x] = %x is not a valid pointer\n",pSym->SectionNumber,(ULONG)pShdrThis));
+ return FALSE;
+ }
+ //to get address in the memory we base address of the module and
+ //add offset of the section and then add offset of the symbol from
+ //the begining of the section
+ ulCurrAddr = ((ULONG)pdTemp->BaseAddress+pShdrThis->VirtualAddress+pSym->Value);
+ DPRINT((0,"FindFunctionByAddress(): CurrAddr [1] = %x\n",ulCurrAddr));
+ DPRINT((0,"%x ", ulCurrAddr));
+
+ if(ulCurrAddr<=ulValue && ulCurrAddr>start)
+ {
+ start = ulCurrAddr;
+ pFoundSym = pSym;
+ //DPRINT((0,"FindFunctionByAddress(): CANDIDATE for start %x\n",start));
+ }
+ else if(ulCurrAddr>=ulValue && ulCurrAddr<end)
+ {
+ end = ulCurrAddr;
+ //DPRINT((0,"FindFunctionByAddress(): CANDIDATE for end %x\n",end));
+ }
+ }
+ //skip the auxiliary symbols and get the next symbol
+ pSym += pSym->NumberOfAuxSymbols + 1;
+ }
+ //we went through all the symbols for this module
+ //now start should point to the start of the function and
+ //end to the start of the next (or end of section)
+ if(pulstart)
+ *pulstart = start;
+
+ if(pulend){
+ //just in case there is more than one code section
+ PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pFoundSym->SectionNumber-1);
+ if( end > (ULONG)pdTemp->BaseAddress+pShdrThis->SizeOfRawData ){
+ DPRINT((0,"Hmm: end=%d, end of section: %d\n", end, (ULONG)pdTemp->BaseAddress+pShdrThis->SizeOfRawData));
+ end = (ULONG)pdTemp->BaseAddress+pShdrThis->SizeOfRawData;
+ }
+ *pulend = end;
+ }
+
+ if(pFoundSym->N.Name.Short){
+ //name is in the header. it's not zero terminated. have to copy.
+ PICE_sprintf(temp4,"%.8s", pFoundSym->N.ShortName);
+ pName = temp4;
+ DPRINT((0,"Function name: %S!%.8s",pdTemp->name,pName));
+ }
+ else{
+ ASSERT(pFoundSym->N.Name.Long<=pSymbols->ulSizeOfGlobalsStrings); //sanity check
+ pName = pStr+pFoundSym->N.Name.Long;
+ if(!IsAddressValid((ULONG)pName))
+ {
+ DPRINT((0,"FindFunctionByAddress(): pName = %x is not a valid pointer\n",pName));
+ return NULL;
+ }
+ DPRINT((0,"Function name: %S!%s",pdTemp->name,pName));
+ }
+ return pName;
+ }
+ }
+ }while((pd = pd->next) != pdebug_module_tail);
+ }
+ return NULL;
+}
+
+//*************************************************************************
+// FindDataSectionOffset()
+//
+//*************************************************************************
+/* ei: never used
+ULONG FindDataSectionOffset(Elf32_Shdr* pSHdr)
+{
+
+ DPRINT((0,"FindDataSectionOffset()\n"));
+
+ while(1)
+ {
+ DPRINT((0,"FindDataSectionOffset(): sh_offset %.8X sh_addr = %.8X\n",pSHdr->sh_offset,pSHdr->sh_addr));
+ if((pSHdr->sh_flags & (SHF_WRITE|SHF_ALLOC) ) == (SHF_WRITE|SHF_ALLOC))
+ {
+
+ return pSHdr->sh_offset;
+ }
+ pSHdr++;
+ }
+
+ return 0;
+}
+*/
+
+//*************************************************************************
+// FindFunctionInModuleByNameViaKsyms()
+//
+//*************************************************************************
+/* ei: not needed. no Ksyms!
+ULONG FindFunctionInModuleByNameViaKsyms(struct module* pMod,LPSTR szFunctionname)
+{
+ ULONG i;
+
+ ENTER_FUNC();
+
+ if(pMod->nsyms)
+ {
+ DPRINT((0,"FindFunctionInModuleByNameViaKsyms(): %u symbols for module %s\n",pMod->nsyms,pMod->name));
+ for(i=0;i<pMod->nsyms;i++)
+ {
+ DPRINT((0,"FindFunctionInModuleByNameViaKsyms(): %s\n",pMod->syms[i].name));
+ if(PICE_strcmpi((LPSTR)pMod->syms[i].name,szFunctionname) == 0)
+ {
+ DPRINT((0,"FindFunctionInModuleByName(): symbol was in exports\n"));
+ LEAVE_FUNC();
+ return pMod->syms[i].value;
+ }
+ }
+ }
+
+ DPRINT((0,"FindFunctionInModuleByName(): symbol wasn't in exports\n"));
+ LEAVE_FUNC();
+ return 0;
+}
+*/
+
+//*************************************************************************
+// FindFunctionInModuleByName()
+//
+//*************************************************************************
+ULONG FindFunctionInModuleByName(LPSTR szFunctionname, PDEBUG_MODULE pd)
+{
+ ULONG i,addr;
+ PICE_SYMBOLFILE_HEADER* pSymbols=NULL;
+ PIMAGE_SYMBOL pSym, pSymEnd;
+ LPSTR pStr;
+ PIMAGE_SECTION_HEADER pShdr;
+
+ ENTER_FUNC();
+ DPRINT((0,"FindFunctionInModuleByName(%s)\n",szFunctionname));
+ DPRINT((0,"FindFunctionInModuleByName(): mod size = %x\n",pd->size));
+ DPRINT((0,"FindFunctionInModuleByName(): module is %S\n",pd->name));
+
+ addr = (ULONG)pd->BaseAddress;
+
+ pSymbols = FindModuleSymbols(addr);
+ if(pSymbols)
+ {
+ DPRINT((0,"FindFunctionInModuleByName(): found symbol table for %S\n",pSymbols->name));
+ pSym = (PIMAGE_SYMBOL)((ULONG)pSymbols+pSymbols->ulOffsetToGlobals);
+ pSymEnd = (PIMAGE_SYMBOL)((ULONG)pSym+pSymbols->ulSizeOfGlobals);
+ pStr = (LPSTR)((ULONG)pSymbols+pSymbols->ulOffsetToGlobalsStrings);
+ pShdr = (PIMAGE_SECTION_HEADER)((ULONG)pSymbols+pSymbols->ulOffsetToHeaders);
+
+ while( pSym < pSymEnd )
+ {
+ //symbol is a function is it's type is 0x20, storage class is external and section>0
+ //if(( (pSym->Type == 0x20) && (pSym->StorageClass==IMAGE_SYM_CLASS_EXTERNAL) &&
+ // (pSym->SectionNumber > 0 )))
+
+ if(((pSym->Type == 0x0) || (pSym->Type == 0x20) ) &&
+ ((pSym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) || (pSym->StorageClass==IMAGE_SYM_CLASS_STATIC)) &&
+ (pSym->SectionNumber > 0 ))
+
+ {
+ ULONG start;
+ LPSTR pName;
+ PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pSym->SectionNumber-1);
+
+ start = ((ULONG)pd->BaseAddress+pShdrThis->VirtualAddress+pSym->Value);
+ DPRINT((0,"FindFunctionInModuleByName(): %s @ %x\n",szFunctionname,start));
+
+ if(pSym->N.Name.Short){ //if name is stored in the structure
+ //name may be not zero terminated but 8 characters max
+ DPRINT((0,"FindFunctionInModuleByName: %.8s\n", pSym->N.ShortName));
+ pName = pSym->N.ShortName; //name is in the header
+ if((PICE_fnncmp(pName,szFunctionname, 8) == 0) && start)
+ {
+ DPRINT((0,"FindFunctionInModuleByName(): symbol was in symbol table, start: %x\n", start));
+ LEAVE_FUNC();
+ return start;
+ }
+ }else{
+ pName = pStr+pSym->N.Name.Long;
+ DPRINT((0,"FindFunctionInModuleByName: %s\n", pName));
+ if((PICE_fncmp(pName,szFunctionname) == 0) && start)
+ {
+ DPRINT((0,"FindFunctionInModuleByName(): symbol was in string table, start: %x\n", start));
+ LEAVE_FUNC();
+ return start;
+ }
+ }
+ }
+ //skip the auxiliary symbols and get the next symbol
+ pSym += pSym->NumberOfAuxSymbols + 1;
+ }
+ }
+ LEAVE_FUNC();
+ return 0;
+}
+
+//*************************************************************************
+// ExtractTypeNumber()
+//
+//*************************************************************************
+ULONG ExtractTypeNumber(LPSTR p)
+{
+ LPSTR pTypeNumber;
+ ULONG ulTypeNumber = 0;
+
+ DPRINT((0,"ExtractTypeNumber(%s)\n",p));
+
+ pTypeNumber = PICE_strchr(p,'(');
+
+ if(pTypeNumber)
+ {
+ pTypeNumber++;
+ ulTypeNumber = ExtractNumber(pTypeNumber);
+ ulTypeNumber <<= 16;
+ pTypeNumber = PICE_strchr(p,',');
+ if(pTypeNumber)
+ {
+ pTypeNumber++;
+ ulTypeNumber += ExtractNumber(pTypeNumber);
+ }
+ else
+ {
+ ulTypeNumber = 0;
+ }
+ }
+ return ulTypeNumber;
+}
+
+//*************************************************************************
+// FindTypeDefinitionForCombinedTypes()
+//
+//*************************************************************************
+LPSTR FindTypeDefinitionForCombinedTypes(PICE_SYMBOLFILE_HEADER* pSymbols,ULONG ulTypeNumber,ULONG ulFileNumber)
+{
+ ULONG i;
+ PSTAB_ENTRY pStab;
+ LPSTR pStr,pName,pTypeNumber,pTypeDefIncluded,pNameTemp;
+ int nStabLen;
+ int nOffset=0,nNextOffset=0,nLen;
+ static char szAccumulatedName[2048];
+ ULONG ulCurrentTypeNumber,ulCurrentFileNumber=0;
+ static char szCurrentPath[256];
+
+ ENTER_FUNC();
+
+ *szAccumulatedName = 0;
+
+ pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
+ nStabLen = pSymbols->ulSizeOfStabs;
+ pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
+
+ DPRINT((0,"FindTypeDefinitionForCombinedTypes()\n"));
+
+ for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
+ {
+ pName = &pStr[pStab->n_strx + nOffset];
+
+ switch(pStab->n_type)
+ {
+ case N_UNDF:
+ nOffset += nNextOffset;
+ nNextOffset = pStab->n_value;
+ break;
+ case N_SO:
+ if((nLen = PICE_strlen(pName)))
+ {
+ if(pName[nLen-1]!='/')
+ {
+ ulCurrentFileNumber++;
+ if(PICE_strlen(szCurrentPath))
+ {
+ PICE_strcat(szCurrentPath,pName);
+ DPRINT((0,"FindTypeDefinitionForCombinedTypes(): changing source file %s\n",szCurrentPath));
+ }
+ else
+ {
+ DPRINT((0,"FindTypeDefinitionForCombinedTypes(): changing source file %s\n",pName));
+ }
+ }
+ else
+ PICE_strcpy(szCurrentPath,pName);
+ }
+ else
+ {
+ szCurrentPath[0]=0;
+ }
+ break;
+ case N_GSYM:
+ //ei File number count is not reliable
+ if( 1 /*ulCurrentFileNumber == ulFileNumber*/)
+ {
+ DPRINT((0,"FindTypeDefinitionForCombinedTypes(): %s\n",pName));
+
+ // handle multi-line symbols
+ if(PICE_strchr(pName,'\\'))
+ {
+ if(PICE_strlen(szAccumulatedName))
+ {
+ PICE_strcat(szAccumulatedName,pName);
+ }
+ else
+ {
+ PICE_strcpy(szAccumulatedName,pName);
+ }
+ szAccumulatedName[PICE_strlen(szAccumulatedName)-1]=0;
+ //DPRINT((0,"accum. %s\n",szAccumulatedName));
+ }
+ else
+ {
+ if(PICE_strlen(szAccumulatedName)==0)
+ {
+ PICE_strcpy(szAccumulatedName,pName);
+ }
+ else
+ {
+ PICE_strcat(szAccumulatedName,pName);
+ }
+ pNameTemp = szAccumulatedName;
+
+ // symbol-name:type-identifier type-number =
+ nLen = StrLenUpToWhiteChar(pNameTemp,":");
+ if((pTypeDefIncluded = PICE_strchr(pNameTemp,'=')) && pNameTemp[nLen+1]=='G')
+ {
+ DPRINT((0,"FindTypeDefinitionForCombinedTypes(): symbol includes type definition (%s)\n",pNameTemp));
+ pTypeNumber = pNameTemp+nLen+1;
+ if((ulCurrentTypeNumber = ExtractTypeNumber(pTypeNumber)) )
+ {
+ DPRINT((0,"FindTypeDefinitionForCombinedTypes(): type-number %x\n",ulCurrentTypeNumber));
+ if(ulCurrentTypeNumber == ulTypeNumber)
+ {
+ DPRINT((0,"FindTypeDefinitionForCombinedTypes(): typenumber %x matches!\n",ulCurrentTypeNumber));
+ return pNameTemp;
+ }
+ }
+ }
+ *szAccumulatedName = 0;
+ }
+ }
+ break;
+ }
+ pStab++;
+ }
+ return NULL;
+}
+
+//*************************************************************************
+// FindTypeDefinition()
+//
+//*************************************************************************
+LPSTR FindTypeDefinition(PICE_SYMBOLFILE_HEADER* pSymbols,ULONG ulTypeNumber,ULONG ulFileNumber)
+{
+ ULONG i;
+ PSTAB_ENTRY pStab;
+ LPSTR pStr,pName,pTypeString;
+ int nStabLen;
+ int nOffset=0,nNextOffset=0,strLen;
+ static char szAccumulatedName[2048];
+ ULONG ulCurrentTypeNumber,ulCurrentFileNumber=0;
+ LPSTR pTypeSymbol;
+ static char szCurrentPath[256];
+
+ ENTER_FUNC();
+ DPRINT((0,"FindTypeDefinition(%u,%u)\n",ulTypeNumber,ulFileNumber));
+
+ *szAccumulatedName = 0;
+
+ pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
+ nStabLen = pSymbols->ulSizeOfStabs;
+ pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
+
+ for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
+ {
+ pName = &pStr[pStab->n_strx + nOffset];
+
+ switch(pStab->n_type)
+ {
+ case N_UNDF:
+ nOffset += nNextOffset;
+ nNextOffset = pStab->n_value;
+ break;
+ case N_SO:
+ if((strLen = PICE_strlen(pName)))
+ {
+ if(pName[strLen-1]!='/')
+ {
+ ulCurrentFileNumber++;
+ if(PICE_strlen(szCurrentPath))
+ {
+ PICE_strcat(szCurrentPath,pName);
+ DPRINT((0,"FindTypeDefinition()1: cha %s, %u\n",szCurrentPath, ulCurrentFileNumber));
+ }
+ else
+ {
+ DPRINT((0,"FindTypeDefinition(): cha %s, %u\n",pName, ulCurrentFileNumber));
+ }
+ }
+ else
+ PICE_strcpy(szCurrentPath,pName);
+ }
+ else
+ {
+ szCurrentPath[0]=0;
+ }
+ break;
+ case N_LSYM:
+ // stab has no value -> must be type definition
+ //ei File number count is not reliable
+ if(pStab->n_value == 0 /*&& ulCurrentFileNumber==ulFileNumber*/)
+ {
+ DPRINT((0,"FindTypeDefinition(): pre type definition %s\n",pName));
+ // handle multi-line symbols
+ if(strrchr(pName,'\\'))
+ {
+ if(PICE_strlen(szAccumulatedName))
+ {
+ PICE_strcat(szAccumulatedName,pName);
+ DPRINT((0,"FindTypeDefinition(): [1] accum. %s\n",szAccumulatedName));
+ }
+ else
+ {
+ PICE_strcpy(szAccumulatedName,pName);
+ DPRINT((0,"FindTypeDefinition(): [2] accum. %s\n",szAccumulatedName));
+ }
+ szAccumulatedName[PICE_strlen(szAccumulatedName)-1]=0;
+ }
+ else
+ {
+ DPRINT((0,"FindTypeDefinition(): [3] accum. %s, pname: %s\n",szAccumulatedName, pName));
+ if(PICE_strlen(szAccumulatedName)==0)
+ {
+ PICE_strcpy(szAccumulatedName,pName);
+ }
+ else
+ {
+ PICE_strcat(szAccumulatedName,pName);
+ }
+ pTypeString = szAccumulatedName;
+
+ pTypeSymbol = PICE_strchr(pTypeString,':');
+ if(pTypeSymbol && (*(pTypeSymbol+1)=='t' || *(pTypeSymbol+1)=='T'))
+ {
+ // parse it
+ ulCurrentTypeNumber = ExtractTypeNumber(pTypeString);
+ DPRINT((0,"FindTypeDefinition(): ulCurrType: %u, LSYM is type %s\n",ulCurrentTypeNumber,pName));
+ if(ulCurrentTypeNumber == ulTypeNumber)
+ {
+ DPRINT((0,"FindTypeDefinition(): type definition %s\n",pTypeString));
+ return pTypeString;
+ }
+ }
+ *szAccumulatedName=0;
+ }
+ }
+ break;
+ }
+ pStab++;
+ }
+
+ return FindTypeDefinitionForCombinedTypes(pSymbols,ulTypeNumber,ulFileNumber);
+
+}
+
+//*************************************************************************
+// TruncateString()
+//
+//*************************************************************************
+LPSTR TruncateString(LPSTR p,char c)
+{
+ static char temp[1024];
+ LPSTR pTemp;
+
+ pTemp = temp;
+
+ while(*p!=0 && *p!=c)
+ *pTemp++ = *p++;
+
+ *pTemp = 0;
+
+ return temp;
+}
+
+//*************************************************************************
+// FindLocalsByAddress()
+//
+// find all locals for a given address by first looking up the function
+// and then it's locals
+//*************************************************************************
+PLOCAL_VARIABLE FindLocalsByAddress(ULONG addr)
+{
+ ULONG i;
+ PSTAB_ENTRY pStab;
+ LPSTR pStr,pName;
+ int nStabLen;
+ int nOffset=0,nNextOffset=0;
+ PICE_SYMBOLFILE_HEADER* pSymbols;
+ static char szCurrentFunction[256];
+ static char szCurrentPath[256];
+ LPSTR pFunctionName;
+ ULONG start,end,strLen;
+ ULONG ulTypeNumber,ulCurrentFileNumber=0;
+ LPSTR pTypedef;
+ ULONG ulNumLocalVars=0;
+
+ DPRINT((0,"FindLocalsByAddress()\n"));
+
+ pFunctionName = FindFunctionByAddress(addr,&start,&end);
+ DPRINT((0,"FindLocalsByAddress(): pFunctionName = %s\n",pFunctionName));
+ if(pFunctionName)
+ {
+ pSymbols = FindModuleSymbols(addr);
+ if(pSymbols)
+ {
+ pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
+ nStabLen = pSymbols->ulSizeOfStabs;
+ pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
+
+ for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
+ {
+ pName = &pStr[pStab->n_strx + nOffset];
+
+ DPRINT((0,"FindLocalsByAddress(): %x %x %x %x %x\n",
+ pStab->n_strx,
+ pStab->n_type,
+ pStab->n_other,
+ pStab->n_desc,
+ pStab->n_value));
+
+ switch(pStab->n_type)
+ {
+ case N_UNDF:
+ nOffset += nNextOffset;
+ nNextOffset = pStab->n_value;
+ break;
+ case N_SO:
+ if((strLen = PICE_strlen(pName)))
+ {
+ if(pName[strLen-1]!='/')
+ {
+ ulCurrentFileNumber++;
+ if(PICE_strlen(szCurrentPath))
+ {
+ PICE_strcat(szCurrentPath,pName);
+ DPRINT((0,"changing source file1 %s, %u\n",szCurrentPath,ulCurrentFileNumber));
+ }
+ else
+ {
+ DPRINT((0,"changing source file %s, %u\n",pName,ulCurrentFileNumber));
+ }
+ }
+ else
+ PICE_strcpy(szCurrentPath,pName);
+ }
+ else
+ {
+ szCurrentPath[0]=0;
+ }
+ break;
+ case N_LSYM:
+ // if we're in the function we're looking for
+ if(szCurrentFunction[0] && PICE_fncmp(szCurrentFunction,pFunctionName)==0)
+ {
+ DPRINT((0,"local variable1 %.8X %.8X %.8X %.8X %.8X %s\n",pStab->n_strx,pStab->n_type,pStab->n_other,pStab->n_desc,pStab->n_value,pName));
+ ulTypeNumber = ExtractTypeNumber(pName);
+ DPRINT((0,"type number = %u\n",ulTypeNumber));
+ if((pTypedef = FindTypeDefinition(pSymbols,ulTypeNumber,ulCurrentFileNumber)))
+ {
+ DPRINT((0,"pTypedef: %x\n", pTypedef));
+ PICE_strcpy(local_vars[ulNumLocalVars].type_name,TruncateString(pTypedef,':'));
+ PICE_strcpy(local_vars[ulNumLocalVars].name,TruncateString(pName,':'));
+ local_vars[ulNumLocalVars].value = (CurrentEBP+pStab->n_value);
+ local_vars[ulNumLocalVars].offset = pStab->n_value;
+ local_vars[ulNumLocalVars].line = pStab->n_desc;
+ local_vars[ulNumLocalVars].bRegister = FALSE;
+ ulNumLocalVars++;
+ }
+ }
+ break;
+ case N_PSYM:
+ // if we're in the function we're looking for
+ if(szCurrentFunction[0] && PICE_fncmp(szCurrentFunction,pFunctionName)==0)
+ {
+ DPRINT((0,"parameter variable %.8X %.8X %.8X %.8X %.8X %s\n",pStab->n_strx,pStab->n_type,pStab->n_other,pStab->n_desc,pStab->n_value,pName));
+ ulTypeNumber = ExtractTypeNumber(pName);
+ DPRINT((0,"type number = %x\n",ulTypeNumber));
+ if((pTypedef = FindTypeDefinition(pSymbols,ulTypeNumber,ulCurrentFileNumber)))
+ {
+ PICE_strcpy(local_vars[ulNumLocalVars].type_name,TruncateString(pTypedef,':'));
+ PICE_strcpy(local_vars[ulNumLocalVars].name,TruncateString(pName,':'));
+ local_vars[ulNumLocalVars].value = (CurrentEBP+pStab->n_value);
+ local_vars[ulNumLocalVars].offset = pStab->n_value;
+ ulNumLocalVars++;
+ }
+ }
+ break;
+ case N_RSYM:
+ // if we're in the function we're looking for
+ if(szCurrentFunction[0] && PICE_fncmp(szCurrentFunction,pFunctionName)==0)
+ {
+ DPRINT((0,"local variable2 %.8X %.8X %.8X %.8X %.8X %s\n",pStab->n_strx,pStab->n_type,pStab->n_other,pStab->n_desc,pStab->n_value,pName));
+ ulTypeNumber = ExtractTypeNumber(pName);
+ DPRINT((0,"type number = %x\n",ulTypeNumber));
+ if((pTypedef = FindTypeDefinition(pSymbols,ulTypeNumber,ulCurrentFileNumber)))
+ {
+ PICE_strcpy(local_vars[ulNumLocalVars].type_name,TruncateString(pTypedef,':'));
+ PICE_strcpy(local_vars[ulNumLocalVars].name,TruncateString(pName,':'));
+ local_vars[ulNumLocalVars].value = (LocalRegs[pStab->n_value]);
+ local_vars[ulNumLocalVars].offset = pStab->n_value;
+ local_vars[ulNumLocalVars].line = pStab->n_desc;
+ local_vars[ulNumLocalVars].bRegister = TRUE;
+ ulNumLocalVars++;
+ }
+ }
+ break;
+ case N_FUN:
+ if(PICE_strlen(pName))
+ {
+ ULONG len;
+
+ len=StrLenUpToWhiteChar(pName,":");
+ PICE_strncpy(szCurrentFunction,pName,len);
+ szCurrentFunction[len]=0;
+ DPRINT((0,"function %s\n",szCurrentFunction));
+ }
+ else
+ {
+ DPRINT((0,"END of function %s\n",szCurrentFunction));
+ szCurrentFunction[0]=0;
+ if(ulNumLocalVars)
+ {
+ *local_vars[ulNumLocalVars].name = 0;
+ return local_vars;
+ }
+ }
+ break;
+ }
+ pStab++;
+ }
+ }
+ }
+ return NULL;
+}
+
+//*************************************************************************
+// FindSourceLineForAddress()
+//
+//*************************************************************************
+LPSTR FindSourceLineForAddress(ULONG addr,PULONG pulLineNumber,LPSTR* ppSrcStart,LPSTR* ppSrcEnd,LPSTR* ppFilename)
+{
+ ULONG i; // index for walking through STABS
+ PSTAB_ENTRY pStab; // pointer to STABS
+ LPSTR pStr,pName; // pointer to STAB strings and current STAB string
+ int nStabLen; // length of STAB section in bytes
+ int nOffset=0,nNextOffset=0; // offset and next offset in string table
+ PICE_SYMBOLFILE_HEADER* pSymbols; // pointer to module's STAB symbol table
+ static char szCurrentFunction[256];
+ static char szCurrentPath[256];
+ static char szWantedPath[256];
+ LPSTR pFunctionName; // name of function that brackets the current address
+ ULONG start,end,strLen,ulMinValue=0xFFFFFFFF;
+ LPSTR pSrcLine=NULL;
+ BOOLEAN bFirstOccurence = TRUE;
+
+ // lookup the functions name and start-end (external symbols)
+ pFunctionName = FindFunctionByAddress(addr,&start,&end);
+ DPRINT((0,"FindSourceLineForAddress: for function: %s\n", pFunctionName));
+
+ if(pFunctionName)
+ {
+ // lookup the modules symbol table (STABS)
+ pSymbols = FindModuleSymbols(addr);
+ DPRINT((0,"FindSourceLineForAddress: pSymbols %x\n", pSymbols));
+ if(pSymbols)
+ {
+ DPRINT((0,"FindSourceLineForAddress: pSymbols->ulNumberOfSrcFiles %x\n", pSymbols->ulNumberOfSrcFiles));
+ // no source files so we don't need to lookup anything
+ if(!pSymbols->ulNumberOfSrcFiles)
+ return NULL;
+
+ // prepare STABS access
+ pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
+ nStabLen = pSymbols->ulSizeOfStabs;
+ pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
+
+ // walk over all STABS
+ for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
+ {
+ // the name string corresponding to the STAB
+ pName = &pStr[pStab->n_strx + nOffset];
+
+ // switch STAB type
+ switch(pStab->n_type)
+ {
+ // change offset of name strings
+ case N_UNDF:
+ nOffset += nNextOffset;
+ nNextOffset = pStab->n_value;
+ break;
+ // source file change
+ case N_SO:
+ DPRINT((0,"changing source file %s\n",pName));
+ // if filename has a length record it
+ if((strLen = PICE_strlen(pName)))
+ {
+ PICE_strcpy(szCurrentPath,pName);
+ }
+ // else empty filename
+ else
+ {
+ szCurrentPath[0]=0;
+ }
+ break;
+ // sub-source file change
+ case N_SOL:
+ DPRINT((0,"changing sub source file %s\n",pName));
+ // if filename has a length record it
+ if((strLen = PICE_strlen(pName)))
+ {
+ PICE_strcpy(szCurrentPath,pName);
+ }
+ // else empty filename
+ else
+ {
+ szCurrentPath[0]=0;
+ }
+ break;
+ // a function symbol
+ case N_FUN:
+ if(!PICE_strlen(pName))
+ {// it's the end of a function
+ DPRINT((0,"END of function %s\n",szCurrentFunction));
+
+ szCurrentFunction[0]=0;
+
+ // in case we haven't had a zero delta match we return from here
+ if(pSrcLine)
+ return pSrcLine;
+
+ break;
+ }
+ else
+ {// if it has a length it's the start of a function
+ ULONG len;
+ // extract the name only, the type string is of no use here
+ len=StrLenUpToWhiteChar(pName,":");
+ PICE_strncpy(szCurrentFunction,pName,len);
+ szCurrentFunction[len]=0;
+
+ DPRINT((0,"function %s\n",szCurrentFunction));
+ }
+ //intentional fall through
+
+ // line number
+ case N_SLINE:
+ // if we're in the function we're looking for
+ if(szCurrentFunction[0] && PICE_fncmp(szCurrentFunction,pFunctionName)==0)
+ {
+ DPRINT((0,"cslnum#%u for addr.%x (fn @ %x) ulMinVal=%x ulDelta=%x\n",pStab->n_desc,start+pStab->n_value,start,ulMinValue,(addr-(start+pStab->n_value))));
+
+ if(bFirstOccurence)
+ {
+ PICE_strcpy(szWantedPath,szCurrentPath);
+ DPRINT((0,"source file must be %s\n",szWantedPath));
+ bFirstOccurence = FALSE;
+ }
+ DPRINT((0,"wanted %s, current: %s\n",szWantedPath, szCurrentPath));
+ // we might have a match if our address is greater than the one in the STAB
+ // and we're lower or equal than minimum value
+ if(addr>=start+pStab->n_value &&
+ (addr-(start+pStab->n_value))<=ulMinValue &&
+ PICE_strcmpi(szWantedPath,szCurrentPath)==0 )
+ {
+ ULONG j;
+ PICE_SYMBOLFILE_SOURCE* pSrc = (PICE_SYMBOLFILE_SOURCE*)((ULONG)pSymbols+pSymbols->ulOffsetToSrcFiles);
+
+ DPRINT((0,"code source line number #%u for addr. %x found!\n",pStab->n_desc,start+pStab->n_value));
+
+ // compute new minimum
+ ulMinValue = addr-(start+pStab->n_value);
+
+ // if we have a pointer for storage of line number, store it
+ if(pulLineNumber)
+ *pulLineNumber = pStab->n_desc;
+
+ // NB: should put this somewhere else so that it's not done all the time
+ // if we have source files at all
+ DPRINT((0,"%u source files @ %x\n",pSymbols->ulNumberOfSrcFiles,pSrc));
+
+ // for all source files in this module
+ for(j=0;j<pSymbols->ulNumberOfSrcFiles;j++)
+ {
+ LPSTR pSlash;
+ ULONG currlen, fnamelen;
+
+ currlen = PICE_strlen( szCurrentPath );
+ fnamelen = PICE_strlen( pSrc->filename );
+ pSlash = pSrc->filename + fnamelen - currlen;
+
+ //DPRINT((0,"pSlash: %s, szCurrentPath: %s\n", pSlash, szCurrentPath));
+ // if base name matches current path we have found the correct source file
+ if(PICE_strcmpi(pSlash,szCurrentPath)==0)
+ {
+ // the linenumber
+ ULONG k = pStab->n_desc;
+
+ DPRINT((0,"found src file %s @ %x\n",pSrc->filename,pSrc));
+
+ // store the pointer to the filename
+ if(ppFilename)
+ *ppFilename = pSrc->filename;
+
+ if(pSrc->ulOffsetToNext > sizeof(PICE_SYMBOLFILE_SOURCE))
+ {
+ // get a pointer to the source file (right after the file header)
+ pSrcLine = (LPSTR)((ULONG)pSrc+sizeof(PICE_SYMBOLFILE_SOURCE));
+
+ // store the source start and end address
+ if(ppSrcStart)
+ *ppSrcStart = pSrcLine;
+ if(ppSrcEnd)
+ *ppSrcEnd = pSrcLine+pSrc->ulOffsetToNext-sizeof(PICE_SYMBOLFILE_SOURCE);
+
+ // goto to the right line
+ while(--k)
+ {
+ while(*pSrcLine!=0 && *pSrcLine!=0x0a && *pSrcLine!=0x0d)
+ pSrcLine++;
+ if(!IsAddressValid((ULONG)pSrcLine))
+ return NULL;
+ pSrcLine++;
+ }
+
+ if(ulMinValue == 0)
+ return pSrcLine;
+ }
+ else
+ {
+ DPRINT((0,"src file descriptor found, but contains no source\n"));
+ }
+
+ break;
+ }
+ (ULONG)pSrc += pSrc->ulOffsetToNext;
+ }
+ }
+ }
+ break;
+ }
+ pStab++;
+ }
+ }
+ }
+ DPRINT((0,"FindSourceLineForAddress: exit 1\n"));
+ return NULL;
+}
+
+//*************************************************************************
+// FindAddressForSourceLine()
+//
+//*************************************************************************
+BOOLEAN FindAddressForSourceLine(ULONG ulLineNumber,LPSTR pFilename,PDEBUG_MODULE pMod,PULONG pValue)
+{
+ ULONG i;
+ PSTAB_ENTRY pStab;
+ LPSTR pStr,pName;
+ int nStabLen;
+ int nOffset=0,nNextOffset=0;
+ PICE_SYMBOLFILE_HEADER* pSymbols;
+ static char szCurrentFunction[256];
+ static char szCurrentPath[256];
+ ULONG strLen,addr,ulMinValue=0xFFFFFFFF;
+ BOOLEAN bFound = FALSE;
+
+ DPRINT((0,"FindAddressForSourceLine(%u,%s,%x)\n",ulLineNumber,pFilename,(ULONG)pMod));
+
+ addr = (ULONG)pMod->BaseAddress;
+
+ pSymbols = FindModuleSymbols(addr);
+ if(pSymbols)
+ {
+ pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
+ nStabLen = pSymbols->ulSizeOfStabs;
+ pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
+
+ for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
+ {
+ pName = &pStr[pStab->n_strx + nOffset];
+
+ switch(pStab->n_type)
+ {
+ case N_UNDF:
+ nOffset += nNextOffset;
+ nNextOffset = pStab->n_value;
+ break;
+ case N_SO:
+ if((strLen = PICE_strlen(pName)))
+ {
+ if(pName[strLen-1]!='/')
+ {
+ if(PICE_strlen(szCurrentPath))
+ {
+ PICE_strcat(szCurrentPath,pName);
+ DPRINT((0,"changing source file %s\n",szCurrentPath));
+ }
+ else
+ {
+ DPRINT((0,"changing source file %s\n",pName));
+ PICE_strcpy(szCurrentPath,pName);
+ }
+ }
+ else
+ PICE_strcpy(szCurrentPath,pName);
+ }
+ else
+ {
+ szCurrentPath[0]=0;
+ }
+ break;
+ case N_SLINE:
+ // if we're in the function we're looking for
+ if(PICE_strcmpi(pFilename,szCurrentPath)==0)
+ {
+ if(pStab->n_desc>=ulLineNumber && (pStab->n_desc-ulLineNumber)<=ulMinValue)
+ {
+ ulMinValue = pStab->n_desc-ulLineNumber;
+
+ DPRINT((0,"code source line number #%u for offset %x in function @ %s)\n",pStab->n_desc,pStab->n_value,szCurrentFunction));
+ addr = FindFunctionInModuleByName(szCurrentFunction,pMod);
+ if(addr)
+ {
+ *pValue = addr + pStab->n_value;
+ bFound = TRUE;
+ }
+ }
+ }
+ break;
+ case N_FUN:
+ if(PICE_strlen(pName))
+ {
+ ULONG len;
+
+ len=StrLenUpToWhiteChar(pName,":");
+ PICE_strncpy(szCurrentFunction,pName,len);
+ szCurrentFunction[len]=0;
+ DPRINT((0,"function %s\n",szCurrentFunction));
+ }
+ else
+ {
+ DPRINT((0,"END of function %s\n",szCurrentFunction));
+ szCurrentFunction[0]=0;
+ }
+ break;
+ }
+ pStab++;
+ }
+ }
+ return bFound;
+}
+
+//*************************************************************************
+// ListSymbolStartingAt()
+// iterate through the list of module symbols (both functions and variables)
+//*************************************************************************
+ULONG ListSymbolStartingAt(PDEBUG_MODULE pMod,PICE_SYMBOLFILE_HEADER* pSymbols,ULONG index,LPSTR pOutput)
+{
+ PIMAGE_SYMBOL pSym, pSymEnd;
+ LPSTR pStr;
+ PIMAGE_SECTION_HEADER pShdr;
+
+ DPRINT((0,"ListSymbolStartingAt(%x,%u)\n",(ULONG)pSymbols,index));
+ DPRINT((0,"ListSymbolStartingAt(): ulOffsetToGlobals = %x ulSizeofGlobals = %x\n",pSymbols->ulOffsetToGlobals,pSymbols->ulSizeOfGlobals));
+ pSym = (PIMAGE_SYMBOL)((ULONG)pSymbols+pSymbols->ulOffsetToGlobals);
+ pSymEnd = (PIMAGE_SYMBOL)((ULONG)pSym+pSymbols->ulSizeOfGlobals);
+ pStr = (LPSTR)((ULONG)pSymbols+pSymbols->ulOffsetToGlobalsStrings);
+ pShdr = (PIMAGE_SECTION_HEADER)((ULONG)pSymbols+pSymbols->ulOffsetToHeaders);
+
+ pSym += index;
+
+ while( pSym < pSymEnd )
+ {
+ LPSTR pName;
+
+ if(((pSym->Type == 0x0) || (pSym->Type == 0x20) ) &&
+ ((pSym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) /*|| (pSym->StorageClass==IMAGE_SYM_CLASS_STATIC)*/) &&
+ (pSym->SectionNumber > 0 ))
+ {
+ PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pSym->SectionNumber-1);
+ ULONG section_flags;
+ ULONG start;
+
+ DPRINT((0,"ListSymbolStartingAt(): pShdr[%x] = %x\n",pSym->SectionNumber,(ULONG)pShdrThis));
+
+ if(!IsRangeValid((ULONG)pShdrThis,sizeof(IMAGE_SECTION_HEADER)) )
+ {
+ DPRINT((0,"ListSymbolStartingAt(): pShdr[%x] = %x is not a valid pointer\n",pSym->SectionNumber,(ULONG)pShdrThis));
+ return FALSE;
+ }
+ section_flags = pShdrThis->Characteristics;
+ //to get address in the memory we base address of the module and
+ //add offset of the section and then add offset of the symbol from
+ //the begining of the section
+
+ start = ((ULONG)pMod->BaseAddress+pShdrThis->VirtualAddress+pSym->Value);
+ if(pSym->N.Name.Short){
+ //name is in the header. it's not zero terminated. have to copy.
+ PICE_sprintf(pOutput,"%.8X (%s) %.8s\n",start,(section_flags&IMAGE_SCN_CNT_CODE)?"TEXT":"DATA",pSym->N.ShortName);
+ }
+ else{
+ ASSERT(pSym->N.Name.Long<=pSymbols->ulSizeOfGlobalsStrings); //sanity check
+ pName = pStr+pSym->N.Name.Long;
+ if(!IsAddressValid((ULONG)pName))
+ {
+ DPRINT((0,"ListSymbolStartingAt(): pName = %x is not a valid pointer\n",pName));
+ return 0;
+ }
+ PICE_sprintf(pOutput,"%.8X (%s) %s\n",start,(section_flags&IMAGE_SCN_CNT_CODE)?"TEXT":"DATA",pName);
+ }
+
+ if((pSym+pSym->NumberOfAuxSymbols+1)<(pSymEnd))
+ return (index+pSym->NumberOfAuxSymbols+1);
+ }
+ index += pSym->NumberOfAuxSymbols + 1;
+ pSym += pSym->NumberOfAuxSymbols + 1;
+ }
+ return 0;
+}
+
+//*************************************************************************
+// SanityCheckExports()
+//
+//*************************************************************************
+BOOLEAN SanityCheckExports(void)
+{
+ BOOLEAN bResult = FALSE;
+ ULONG i,ulValue,incr;
+
+ Print(OUTPUT_WINDOW,"pICE: sanity-checking exports...\n");
+ return TRUE;
+ /* fix later!!! do we really need to cross reference two kinds of symbolic info?
+ if(fake_kernel_module.nsyms && fake_kernel_module.syms)
+ {
+ incr = (fake_kernel_module.nsyms/4);
+ if(!incr)incr = 1;
+ for(i=0;i<fake_kernel_module.nsyms;i+=incr)
+ {
+ if(ScanExports((char*)fake_kernel_module.syms[i].name,&ulValue) )
+ {
+ if(!(i%25))
+ {
+ ClrLine(wWindow[OUTPUT_WINDOW].y + wWindow[OUTPUT_WINDOW].usCurY);
+ PICE_sprintf(tempSym,"pICE: sanity-checking exports %u/%u",
+ i,
+ fake_kernel_module.nsyms);
+ PutChar(tempSym,1,wWindow[OUTPUT_WINDOW].y + wWindow[OUTPUT_WINDOW].usCurY);
+ }
+
+ if(fake_kernel_module.syms[i].value != ulValue)
+ {
+ PICE_sprintf(tempSym,"pICE: %s doesn't match (%.8X != %.8X)\n",
+ fake_kernel_module.syms[i].name,
+ fake_kernel_module.syms[i].value,
+ ulValue);
+ Print(OUTPUT_WINDOW,tempSym);
+
+ return FALSE;
+ }
+ }
+ }
+
+ bResult = TRUE;
+ }
+
+ return bResult;
+ */
+}
+
+//*************************************************************************
+// LoadExports()
+//
+//*************************************************************************
+BOOLEAN LoadExports(void)
+{
+ HANDLE hf;
+ BOOLEAN bResult = TRUE;
+
+ ENTER_FUNC();
+
+ Print(OUTPUT_WINDOW,"pICE: loading exports...\n");
+ hf = PICE_open(L"\\SystemRoot\\symbols\\ntoskrnl.map",OF_READ);
+ /*
+ if(hf)
+ {
+ Print(OUTPUT_WINDOW,"pICE: no System.map in /boot\n");
+ hf = PICE_open("/System.map",OF_READ);
+ }
+ */
+
+ if(hf)
+ {
+ //mm_segment_t oldfs;
+ size_t len;
+
+ len = PICE_len(hf);
+ if(len)
+ {
+ DPRINT((0,"file len = %d\n",len));
+
+ pExports = PICE_malloc(len+1,NONPAGEDPOOL); // maybe make pool setting an option
+
+ DPRINT((0,"pExports = %x\n",pExports));
+
+ if(pExports)
+ {
+ //oldfs = get_fs(); set_fs(KERNEL_DS);
+ ulExportLen = len;
+ ((PUCHAR)pExports)[len]=0;
+ if(len == PICE_read(hf,pExports,len))
+ {
+ DPRINT((0,"success reading system map!\n"));
+ PICE_sprintf(tempSym,"pICE: ntoskrnl.sym @ %x (size %x)\n",pExports,len);
+ Print(OUTPUT_WINDOW,tempSym);
+ }
+ else
+ DbgPrint("error reading ntoskrnl map!\n");
+ //set_fs(oldfs);
+ }
+ }
+ PICE_close(hf);
+ }
+ else
+ {
+ Print(OUTPUT_WINDOW,"pICE: no ntoskrnl.sys \n");
+ Print(OUTPUT_WINDOW,"pICE: could not load exports...\n");
+ bResult = FALSE;
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+//*************************************************************************
+// UnloadExports()
+//
+//*************************************************************************
+void UnloadExports(void)
+{
+ ENTER_FUNC();
+ if(pExports)
+ {
+ DPRINT((0,"freeing %x\n",pExports));
+ PICE_free(pExports);
+ pExports = NULL;
+ }
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// LoadSymbols()
+//
+//*************************************************************************
+PICE_SYMBOLFILE_HEADER* LoadSymbols(LPSTR filename)
+{
+ HANDLE hf;
+ PICE_SYMBOLFILE_HEADER* pSymbols=NULL;
+ WCHAR tempstr[256];
+ int conv;
+ ENTER_FUNC();
+
+ if( !( conv = PICE_MultiByteToWideChar(CP_ACP, NULL, filename, -1, tempstr, 256 ) ) )
+ {
+ DPRINT((0,"Can't convert module name.\n"));
+ return NULL;
+ }
+ DPRINT((0,"LoadSymbols: filename %s, tempstr %S, conv: %d\n", filename, tempstr, conv));
+
+ if(ulNumSymbolsLoaded<DIM(apSymbols))
+ {
+ hf = PICE_open(tempstr,OF_READ);
+ DPRINT((0,"LoadSymbols: hf: %x, file: %S\n",hf, tempstr));
+ if(hf)
+ {
+ //mm_segment_t oldfs;
+ size_t len;
+
+ DPRINT((0,"hf = %x\n",hf));
+
+ len = PICE_len(hf);
+ DPRINT((0,"file len = %d\n",len));
+
+ if(len)
+ {
+ pSymbols = PICE_malloc(len+1,NONPAGEDPOOL); // maybe make pool setting an option
+ DPRINT((0,"pSymbols = %x\n",pSymbols));
+
+ if(pSymbols)
+ {
+ //oldfs = get_fs(); set_fs(KERNEL_DS);
+ if(len == PICE_read(hf,(PVOID)pSymbols,len))
+ {
+ DPRINT((0,"LoadSymbols(): success reading symbols!\n"));
+ DPRINT((0,"LoadSymbols(): pSymbols->magic = %X\n",pSymbols->magic));
+ }
+ //set_fs(oldfs);
+
+
+ if(pSymbols->magic == PICE_MAGIC)
+ {
+ DPRINT((0,"magic = %X\n",pSymbols->magic));
+ DPRINT((0,"name = %S\n",pSymbols->name));
+ DPRINT((0,"ulOffsetToHeaders,ulSizeOfHeader = %X,%X\n",pSymbols->ulOffsetToHeaders,pSymbols->ulSizeOfHeader));
+ DPRINT((0,"ulOffsetToGlobals,ulSizeOfGlobals = %X,%X\n",pSymbols->ulOffsetToGlobals,pSymbols->ulSizeOfGlobals));
+ DPRINT((0,"ulOffsetToGlobalsStrings,ulSizeOfGlobalsStrings = %X,%X\n",pSymbols->ulOffsetToGlobalsStrings,pSymbols->ulSizeOfGlobalsStrings));
+ DPRINT((0,"ulOffsetToStabs,ulSizeOfStabs = %X,%X\n",pSymbols->ulOffsetToStabs,pSymbols->ulSizeOfStabs));
+ DPRINT((0,"ulOffsetToStabsStrings,ulSizeOfStabsStrings = %X,%X\n",pSymbols->ulOffsetToStabsStrings,pSymbols->ulSizeOfStabsStrings));
+ DPRINT((0,"ulOffsetToSrcFiles,ulNumberOfSrcFiles = %X,%X\n",pSymbols->ulOffsetToSrcFiles,pSymbols->ulNumberOfSrcFiles));
+ DPRINT((0,"pICE: symbols loaded for module \"%S\" @ %x\n",pSymbols->name,pSymbols));
+ apSymbols[ulNumSymbolsLoaded++]=pSymbols;
+ }
+ else
+ {
+ DPRINT((0,"LoadSymbols(): freeing %x\n",pSymbols));
+ DPRINT((0,"pICE: symbols file \"%s\" corrupt\n",filename));
+ PICE_free(pSymbols);
+ }
+ }
+
+ }
+ PICE_close(hf);
+ }
+ else
+ {
+ DPRINT((0,"pICE: could not load symbols for %s...\n",filename));
+ }
+ }
+
+ LEAVE_FUNC();
+
+ return pSymbols;
+}
+
+//*************************************************************************
+// ReloadSymbols()
+//
+//*************************************************************************
+BOOLEAN ReloadSymbols(void)
+{
+ BOOLEAN bResult;
+
+ ENTER_FUNC();
+
+ UnloadSymbols();
+
+ bResult = LoadSymbolsFromConfig(TRUE);
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+//*************************************************************************
+// UnloadSymbols()
+//
+//*************************************************************************
+void UnloadSymbols()
+{
+ ULONG i;
+
+ ENTER_FUNC();
+
+ if(ulNumSymbolsLoaded)
+ {
+ for(i=0;i<ulNumSymbolsLoaded;i++)
+ {
+ DPRINT((0,"freeing [%u] %x\n",i,apSymbols[i]));
+ PICE_free(apSymbols[i]);
+ apSymbols[i] = NULL;
+ }
+ ulNumSymbolsLoaded = 0;
+ }
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// LoadSymbolsFromConfig()
+//
+//*************************************************************************
+BOOLEAN LoadSymbolsFromConfig(BOOLEAN bIgnoreBootParams)
+{
+ HANDLE hf;
+ LPSTR pConfig,pConfigEnd,pTemp;
+ char temp[256];
+ ULONG line = 1;
+ BOOLEAN bResult = FALSE;
+
+ ENTER_FUNC();
+
+ hf = PICE_open(L"\\SystemRoot\\symbols\\pice.cfg",OF_READ);
+ if(hf)
+ {
+ //mm_segment_t oldfs;
+ size_t len;
+
+ DPRINT((0,"hf = %x\n",hf));
+
+ len = PICE_len(hf);
+ DPRINT((0,"file len = %d\n",len));
+
+ if(len)
+ {
+ pConfig = PICE_malloc(len+1,NONPAGEDPOOL); // maybe make pool setting an option
+ DPRINT((0,"pConfig = %x\n",pConfig));
+ //oldfs = get_fs(); set_fs(KERNEL_DS);
+
+ if(len == PICE_read(hf,(PVOID)pConfig,len))
+ {
+ //set_fs(oldfs);
+
+ pConfigEnd = pConfig + len;
+
+ while(pConfig<pConfigEnd)
+ {
+ // skip leading spaces
+ while(*pConfig==' ' && pConfig<pConfigEnd)
+ pConfig++;
+ // get ptr to temporary
+ pTemp = temp;
+ // fill in temporary with symbol path
+ while(*pConfig!=0 && *pConfig!=0x0a && *pConfig!=0x0d && pConfig<pConfigEnd)
+ *pTemp++ = *pConfig++;
+ // finish up symbol path string
+ *pTemp = 0;
+ // skip any line ends
+ while((*pConfig==0x0a || *pConfig==0x0d) && pConfig<pConfigEnd)
+ pConfig++;
+
+ // finally try to load the symbols
+ if(PICE_strlen(temp))
+ {
+ PICE_SYMBOLFILE_HEADER *pSymbols;
+
+ // boot parameter
+ if(*temp == '!')
+ {
+ if(!bIgnoreBootParams)
+ {
+ if(!PICE_strlen(szBootParams))
+ {
+ PICE_strcpy(szBootParams,temp+1);
+ DPRINT((0,"pICE: boot params = %s\n",szBootParams));
+ }
+ else
+ {
+ DPRINT((0,"pICE: boot params already exist! ignoring...\n",szBootParams));
+ }
+ }
+ }
+ // options
+ else if(*temp == '+')
+ {
+ if(PICE_strlen(temp)>1)
+ {
+ if(PICE_strcmpi(temp,"+vga")==0)
+ {
+ eTerminalMode = TERMINAL_MODE_VGA_TEXT;
+ DPRINT((0,"pICE: eTerminalMode = TERMINAL_MODE_VGA_TEXT\n"));
+ }
+ else if(PICE_strcmpi(temp,"+hercules")==0)
+ {
+ eTerminalMode = TERMINAL_MODE_HERCULES_GRAPHICS;
+ DPRINT((0,"pICE: eTerminalMode = TERMINAL_MODE_HERCULES_GRAPHICS\n"));
+ }
+ else if(PICE_strcmpi(temp,"+serial")==0)
+ {
+ eTerminalMode = TERMINAL_MODE_SERIAL;
+ DPRINT((0,"pICE: eTerminalMode = TERMINAL_MODE_SERIAL\n"));
+ }
+ }
+ else
+ {
+ DPRINT((0,"pICE: found option, but no value\n"));
+ }
+ }
+ // comment
+ else if(*temp == '#')
+ {
+ DPRINT((0,"comment out\n"));
+ }
+ // symbol file name/path
+ else
+ {
+ DPRINT((0,"Load symbols from file %s\n", temp));
+ pSymbols = LoadSymbols(temp);
+ DPRINT((0,"Load symbols from file %s, pSymbols: %x\n", temp, pSymbols));
+ if(pSymbols)
+ {
+ PICE_SYMBOLFILE_SOURCE* pSrc;
+ LPSTR p;
+
+ pSrc = (PICE_SYMBOLFILE_SOURCE*)((ULONG)pSymbols + pSymbols->ulOffsetToSrcFiles);
+ pCurrentSymbols = pSymbols;
+ p = strrchr(pSrc->filename,'\\');
+ if(p)
+ {
+ PICE_strcpy(szCurrentFile,p+1);
+ }
+ else
+ {
+ PICE_strcpy(szCurrentFile,pSrc->filename);
+ }
+ }
+ }
+ }
+ else
+ {
+ DPRINT((0,"invalid line [%u] in config!\n",line));
+ }
+ line++;
+ }
+ }
+ else
+ {
+ //set_fs(oldfs);
+ }
+ }
+
+ PICE_close(hf);
+ bResult = TRUE;
+ }
+ else
+ {
+ DPRINT((0,"pICE: config file not found! No symbols loaded.\n"));
+ DPRINT((0,"pICE: Please make sure to create a file \\systemroot\\symbols\\pice.conf\n"));
+ DPRINT((0,"pICE: if you want to have symbols for any module loaded.\n"));
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+
+//*************************************************************************
+// EVALUATION OF EXPRESSIONS
+//*************************************************************************
+
+//*************************************************************************
+// SkipSpaces()
+//
+//*************************************************************************
+void SkipSpaces(void)
+{
+ while(pExpression[ulIndex]==' ')
+ ulIndex++;
+};
+
+//*************************************************************************
+// FindGlobalStabSymbol()
+//
+//*************************************************************************
+BOOLEAN FindGlobalStabSymbol(LPSTR pExpression,PULONG pValue,PULONG pulTypeNumber,PULONG pulFileNumber)
+{
+ ULONG i;
+ PSTAB_ENTRY pStab;
+ LPSTR pStr,pName;
+ int nStabLen;
+ int nOffset=0,nNextOffset=0,nLen,strLen;
+ PICE_SYMBOLFILE_HEADER* pSymbols;
+ ULONG ulTypeNumber;
+ static char SymbolName[1024];
+ static char szCurrentPath[256];
+ ULONG ulCurrentFileNumber=0;
+ LPSTR pTypeDefIncluded;
+ ULONG addr;
+
+ // must have a current module
+ if(pCurrentMod)
+ {
+ // in case we query for the kernel we need to use the fake kernel module
+ addr = (ULONG)pCurrentMod->BaseAddress;
+
+ // find the symbols for the module
+ pSymbols = FindModuleSymbols(addr);
+ if(pSymbols)
+ {
+ // prepare table access
+ pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
+ nStabLen = pSymbols->ulSizeOfStabs;
+ pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
+ // starting at file 0
+ *pulFileNumber = 0;
+
+ // go through stabs
+ for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
+ {
+ pName = &pStr[pStab->n_strx + nOffset];
+
+ switch(pStab->n_type)
+ {
+ // an N_UNDF symbol marks a change of string table offset
+ case N_UNDF:
+ nOffset += nNextOffset;
+ nNextOffset = pStab->n_value;
+ break;
+ // a source file symbol
+ case N_SO:
+ if((strLen = PICE_strlen(pName)))
+ {
+ if(pName[strLen-1]!='/')
+ {
+ ulCurrentFileNumber++;
+ if(PICE_strlen(szCurrentPath))
+ {
+ PICE_strcat(szCurrentPath,pName);
+ DPRINT((0,"changing source file %s\n",szCurrentPath));
+ }
+ else
+ {
+ DPRINT((0,"changing source file %s\n",pName));
+ }
+ }
+ else
+ PICE_strcpy(szCurrentPath,pName);
+ }
+ else
+ {
+ szCurrentPath[0]=0;
+ }
+ break;
+ case N_GSYM:
+ case N_LSYM:
+ case N_PSYM:
+ // symbol-name:type-identifier type-number =
+ nLen = StrLenUpToWhiteChar(pName,":");
+ PICE_strncpy(SymbolName,pName,nLen);
+ SymbolName[nLen] = 0;
+ if(PICE_strcmpi(SymbolName,pExpression)==0)
+ {
+ DPRINT((0,"global symbol %s\n",pName));
+ // extract type-number from stab
+ ulTypeNumber = ExtractTypeNumber(pName);
+ DPRINT((0,"type number = %x, from %s\n",ulTypeNumber, pName));
+ *pulTypeNumber = ulTypeNumber;
+ // look for symbols address in external symbols
+ if( pStab->n_type == N_LSYM || pStab->n_type == N_PSYM )
+ *pValue = CurrentEBP + pStab->n_value;
+ else *pValue = FindFunctionInModuleByName(SymbolName,pCurrentMod);
+
+ DPRINT((0,"value = %x\n",*pValue));
+ *pulFileNumber = ulCurrentFileNumber;
+ DPRINT((0,"file = %x\n",ulCurrentFileNumber));
+ if((pTypeDefIncluded = PICE_strchr(pName,'=')) )
+ {
+ DPRINT((0,"symbol includes type definition (%s)\n",pTypeDefIncluded));
+ }
+ return TRUE;
+ }
+ break;
+ }
+ pStab++;
+ }
+ }
+ }
+ return FALSE;
+}
+
+//*************************************************************************
+// ExtractToken()
+//
+//*************************************************************************
+void ExtractToken(LPSTR pStringToken)
+{
+ while(PICE_isalpha(pExpression[ulIndex]) || PICE_isdigit(pExpression[ulIndex]) || pExpression[ulIndex]=='_')
+ {
+ *pStringToken++=pExpression[ulIndex++];
+ *pStringToken=0;
+ }
+}
+
+//*************************************************************************
+// ExtractTypeName()
+//
+//*************************************************************************
+LPSTR ExtractTypeName(LPSTR p)
+{
+ static char temp[1024];
+ ULONG i;
+
+ DPRINT((1,"ExtractTypeName(%s)\n",p));
+
+ for(i=0;IsAddressValid((ULONG)p) && *p!=0 && *p!=':';i++,p++)
+ temp[i] = *p;
+
+ if(!IsAddressValid((ULONG)p) )
+ {
+ DPRINT((1,"hit invalid page %x!\n",(ULONG)p));
+ }
+
+ temp[i]=0;
+
+ return temp;
+}
+
+//*************************************************************************
+// ExtractNumber()
+//
+//*************************************************************************
+LONG ExtractNumber(LPSTR p)
+{
+ LONG lMinus = 1,lBase;
+ ULONG lNumber = 0;
+
+ DPRINT((0,"ExtractNumber(): %s\n",p));
+
+ if(!IsAddressValid((ULONG)p) )
+ {
+ DPRINT((1,"ExtractNumber(): [1] invalid page %x hit!\n",p));
+ return 0;
+ }
+
+ if(*p == '-')
+ {
+ lMinus = -1;
+ p++;
+ }
+
+ if(!IsAddressValid((ULONG)p) )
+ {
+ DPRINT((1,"ExtractNumber(): [2] invalid page %x hit!\n",p));
+ return 0;
+ }
+
+ if(*p != '0') // non-octal -> decimal number
+ lBase = 10;
+ else
+ lBase = 8;
+
+ if(!IsAddressValid((ULONG)p) )
+ {
+ DPRINT((1,"ExtractNumber(): [3] invalid page %x hit!\n",p));
+ return 0;
+ }
+
+ while(PICE_isdigit(*p))
+ {
+ lNumber *= lBase;
+ lNumber += *p-'0';
+ p++;
+ if(!IsAddressValid((ULONG)p) )
+ {
+ DPRINT((1,"ExtractNumber(): [4] invalid page %x hit!\n",p));
+ return 0;
+ }
+ }
+
+ return (lNumber*lMinus);
+}
+
+//*************************************************************************
+// ExtractArray()
+//
+//*************************************************************************
+BOOLEAN ExtractArray(PVRET pvr,LPSTR p)
+{
+ ULONG index_typenumber,type_number;
+ ULONG lower_bound,upper_bound;
+ LPSTR pTypeDef;
+
+ DPRINT((1,"ExtractArray(%s)\n",p));
+
+ // index-type index-type-number;lower;upper;element-type-number
+ pvr->bArrayType = TRUE;
+ p++;
+ index_typenumber = ExtractTypeNumber(p);
+ p = PICE_strchr(p,';');
+ if(p)
+ {
+ p++;
+ lower_bound = ExtractNumber(p);
+ p = PICE_strchr(p,';');
+ if(p)
+ {
+ p++;
+
+ upper_bound = ExtractNumber(p);
+ p = PICE_strchr(p,';');
+ if(p)
+ {
+ p++;
+
+ type_number = ExtractTypeNumber(p);
+
+ DPRINT((1,"ExtractArray(): %x %x %x %x\n",index_typenumber,lower_bound,upper_bound,type_number));
+
+ pTypeDef = FindTypeDefinition(pvr->pSymbols,type_number,pvr->file);
+ if(pTypeDef)
+ {
+ PICE_strcpy(pvr->type_name,ExtractTypeName(pTypeDef));
+ pvr->type = type_number;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+//*************************************************************************
+// ExtractStructMembers()
+//
+//*************************************************************************
+PVRET ExtractStructMembers(PVRET pvr,LPSTR p)
+{
+ ULONG len;
+ static char member_name[128];
+ LONG bit_offset,bit_size,type_number,byte_size;
+ static VRET vr;
+ LPSTR pTypeDef,pEqual;
+
+ DPRINT((1,"ExtractStructMembers(): %s\n",p));
+
+ PICE_memset(&vr,0,sizeof(vr));
+
+ // name:type-number,bit-offset,bit-size
+ len=StrLenUpToWhiteChar(p,":");
+ if(len)
+ {
+ // extract member name
+ PICE_strncpy(member_name,p,len);
+ member_name[len]=0;
+ DPRINT((1,"ExtractStructMembers(): member_name = %s\n",member_name));
+
+ // go to char following ':'
+ p += (len+1);
+ if(IsAddressValid((ULONG)p) )
+ {
+ type_number = ExtractTypeNumber(p);
+ DPRINT((1,"ExtractStructMembers(): type_number = %x\n",type_number));
+
+ vr.type = type_number;
+
+ pEqual = PICE_strchr(p,')');
+ // see if it includes type def
+ if(pEqual)
+ {
+ p = pEqual+1;
+ if(*p == '=')
+ {
+ p++;
+ if(*p == 'a')
+ {
+ DPRINT((1,"ExtractStructMembers(): member is array\n"));
+ vr.bArrayType = TRUE;
+ p = PICE_strchr(p,';');
+ p = PICE_strchr(p,';');
+ p = PICE_strchr(p,';');
+ if(p)
+ p++;
+
+ type_number = ExtractTypeNumber(p);
+ vr.father_type = type_number;
+ }
+ else if(*p == '*')
+ {
+ DPRINT((1,"ExtractStructMembers(): member is ptr\n"));
+ vr.bPtrType = TRUE;
+ type_number = ExtractTypeNumber(p);
+ DPRINT((1,"ExtractStructMembers(): type_number = %x\n",type_number));
+ vr.father_type = type_number;
+ }
+ else if(*p == 'u')
+ {
+ DPRINT((1,"ExtractStructMembers(): member is union\n"));
+ while(*p!=';' && *(p+1)!=';' && *p!=0)p++;
+ }
+ }
+ }
+
+ p = PICE_strchr(p,',');
+ if(p)
+ {
+ p++;
+ bit_offset = ExtractNumber(p);
+ DPRINT((1,"ExtractStructMembers(): bit_offset = %x\n",bit_offset));
+ p = PICE_strchr(p,',');
+ if(p)
+ {
+ p++;
+
+ bit_size = ExtractNumber(p);
+ DPRINT((1,"ExtractStructMembers(): bit_size = %x\n",bit_size));
+
+ vr.address = pvr->value + bit_offset/8;
+ vr.file = pvr->file;
+ vr.size = bit_size;
+ PICE_strcpy(vr.name,member_name);
+ byte_size = (bit_size+1)/8;
+ if(!byte_size)
+ byte_size = 4;
+ pvr->address = pvr->value;
+ if(IsRangeValid(vr.address,byte_size))
+ {
+ switch(byte_size)
+ {
+ case 1:
+ vr.value = *(PUCHAR)vr.address;
+ break;
+ case 2:
+ vr.value = *(PUSHORT)vr.address;
+ break;
+ case 4:
+ vr.value = *(PULONG)vr.address;
+ break;
+ }
+ }
+
+ DPRINT((1,"ExtractStructMembers(): member %s type %x bit_offset %x bit_size%x\n",member_name,type_number,bit_offset,bit_size));
+
+ pTypeDef = FindTypeDefinition(pvr->pSymbols,type_number,pvr->file);
+ if(pTypeDef)
+ {
+ DPRINT((1,"ExtractStructMembers(): pTypedef= %s\n",pTypeDef));
+ PICE_strcpy(vr.type_name,ExtractTypeName(pTypeDef));
+ pTypeDef = PICE_strchr(pTypeDef,':');
+ if(pTypeDef)
+ {
+ pTypeDef++;
+ type_number = ExtractTypeNumber(pTypeDef);
+ DPRINT((1,"ExtractStructMembers(): type_number = %x\n",type_number));
+ vr.father_type = type_number;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return &vr;
+}
+
+//*************************************************************************
+// EvaluateSymbol()
+//
+//*************************************************************************
+BOOLEAN EvaluateSymbol(PVRET pvr,LPSTR pToken)
+{
+ LPSTR pTypeDef,pTypeName,pTypeBase,pSemiColon,pStructMembers;
+ BOOLEAN bDone = FALSE;
+ ULONG ulType,ulBits,ulBytes;
+ LONG lLowerRange,lUpperRange,lDelta;
+ static char type_def[2048];
+
+ DPRINT((1,"EvaluateSymbol(%s)\n",pToken));
+
+ if(FindGlobalStabSymbol(pToken,&pvr->value,&pvr->type,&pvr->file))
+ {
+ DPRINT((1,"EvaluateSymbol(%s) pvr->value = %x pvr->type = %x\n",pToken,pvr->value,pvr->type));
+ while(!bDone)
+ {
+ if(!(pTypeDef = FindTypeDefinition(pvr->pSymbols,pvr->type,pvr->file)))
+ break;
+ PICE_strcpy(type_def,pTypeDef);
+
+ pTypeDef = type_def;
+
+ pTypeName = ExtractTypeName(pTypeDef);
+
+ DPRINT((1,"%s %s\n",pTypeName,pToken));
+
+ PICE_strcpy(pvr->type_name,pTypeName);
+
+ pTypeBase = PICE_strchr(pTypeDef,'=');
+
+ if(!pTypeBase)
+ return FALSE;
+
+ pTypeBase++;
+
+ switch(*pTypeBase)
+ {
+ case '(': // type reference
+ ulType = ExtractTypeNumber(pTypeBase);
+ DPRINT((1,"%x is a type reference to %x\n",pvr->type,ulType));
+ pvr->type = ulType;
+ break;
+ case 'r': // subrange
+ pTypeBase++;
+ ulType = ExtractTypeNumber(pTypeBase);
+ DPRINT((1,"%x is sub range of %x\n",pvr->type,ulType));
+ if(pvr->type == ulType)
+ {
+ DPRINT((1,"%x is a self reference\n",pvr->type));
+ pSemiColon = PICE_strchr(pTypeBase,';');
+ pSemiColon++;
+ lLowerRange = ExtractNumber(pSemiColon);
+ pSemiColon = PICE_strchr(pSemiColon,';');
+ pSemiColon++;
+ lUpperRange = ExtractNumber(pSemiColon);
+ lDelta = lUpperRange-lLowerRange;
+ DPRINT((1,"bounds %x-%x range %x\n",lLowerRange,lUpperRange,lDelta));
+ ulBits=0;
+ do
+ {
+ ulBits++;
+ lDelta /= 2;
+ }while(lDelta);
+ ulBytes = (ulBits+1)/8;
+ if(!ulBytes)
+ ulBytes = 4;
+ DPRINT((1,"# of bytes = %x\n",ulBytes));
+ pvr->address = pvr->value;
+ if(IsRangeValid(pvr->value,ulBytes))
+ {
+ switch(ulBytes)
+ {
+ case 1:
+ pvr->value = *(PUCHAR)pvr->value;
+ break;
+ case 2:
+ pvr->value = *(PUSHORT)pvr->value;
+ break;
+ case 4:
+ pvr->value = *(PULONG)pvr->value;
+ break;
+ }
+ }
+ bDone=TRUE;
+ }
+ else
+ pvr->type = ulType;
+ break;
+ case 'a': // array type
+ DPRINT((1,"%x array\n",pvr->type));
+ pTypeBase++;
+ if(!ExtractArray(pvr,pTypeBase))
+ {
+ bDone = TRUE;
+ pvr->error = 1;
+ }
+ break;
+ case '*': // ptr type
+ DPRINT((1,"%x is ptr to\n",pvr->type));
+ bDone = TRUE; // meanwhile
+ break;
+ case 's': // struct type [name:T(#,#)=s#membername1:(#,#),#,#;membername1:(#,#),#,#;;]
+ // go past 's'
+ pTypeBase++;
+
+ // extract the the struct size
+ lLowerRange = ExtractNumber(pTypeBase);
+ DPRINT((1,"%x struct size = %x\n",pvr->type,lLowerRange));
+
+ // skip over the digits
+ while(PICE_isdigit(*pTypeBase))
+ pTypeBase++;
+
+ // the structs address is is value
+ pvr->address = pvr->value;
+ pvr->bStructType = TRUE;
+
+ // decode the struct members. pStructMembers now points to first member name
+ pStructMembers = pTypeBase;
+
+ while(pStructMembers && *pStructMembers && *pStructMembers!=';' && ulNumStructMembers<DIM(vrStructMembers))
+ {
+ DPRINT((1,"EvaluateSymbol(): member #%u\n",ulNumStructMembers));
+ // put this into our array
+ vrStructMembers[ulNumStructMembers] = *ExtractStructMembers(pvr,pStructMembers);
+
+ if(!PICE_strlen(vrStructMembers[ulNumStructMembers].type_name))
+ {
+ ULONG i;
+ PVRET pvrThis = &vrStructMembers[ulNumStructMembers];
+
+ DPRINT((1,"EvaluateSymbol(): no type name\n"));
+ for(i=0;i<ulNumStructMembers;i++)
+ {
+ DPRINT((1,"EvaluateSymbol(): vr[i].type_name = %s\n",vrStructMembers[i].type_name));
+ DPRINT((1,"EvaluateSymbol(): vr[i].name = %s\n",vrStructMembers[i].name));
+ DPRINT((1,"EvaluateSymbol(): vr[i].address = %.8X\n",vrStructMembers[i].address));
+ DPRINT((1,"EvaluateSymbol(): vr[i].value = %.8X\n",vrStructMembers[i].value));
+ DPRINT((1,"EvaluateSymbol(): vr[i].size = %.8X\n",vrStructMembers[i].size));
+ DPRINT((1,"EvaluateSymbol(): vr[i].type = %.8X\n",vrStructMembers[i].type));
+ if(pvrThis->type == vrStructMembers[i].type)
+ {
+ PICE_strcpy(pvrThis->type_name,vrStructMembers[i].type_name);
+ pvrThis->bArrayType = vrStructMembers[i].bArrayType;
+ pvrThis->bPtrType = vrStructMembers[i].bPtrType;
+ pvrThis->bStructType = vrStructMembers[i].bStructType;
+ break;
+ }
+ }
+ }
+
+ DPRINT((1,"EvaluateSymbol(): vr.type_name = %s\n",vrStructMembers[ulNumStructMembers].type_name));
+ DPRINT((1,"EvaluateSymbol(): vr.name = %s\n",vrStructMembers[ulNumStructMembers].name));
+ DPRINT((1,"EvaluateSymbol(): vr.address = %.8X\n",vrStructMembers[ulNumStructMembers].address));
+ DPRINT((1,"EvaluateSymbol(): vr.value = %.8X\n",vrStructMembers[ulNumStructMembers].value));
+ DPRINT((1,"EvaluateSymbol(): vr.size = %.8X\n",vrStructMembers[ulNumStructMembers].size));
+ DPRINT((1,"EvaluateSymbol(): vr.type = %.8X\n",vrStructMembers[ulNumStructMembers].type));
+
+ ulNumStructMembers++;
+
+ // skip to next ':'
+ pStructMembers = PICE_strchr(pStructMembers,';');
+ pStructMembers = PICE_strchr(pStructMembers,':');
+ if(pStructMembers)
+ {
+ DPRINT((1,"EvaluateSymbol(): ptr is now %s\n",pStructMembers));
+ // go back to where member name starts
+ while(*pStructMembers!=';')
+ pStructMembers--;
+ // if ';' present, go to next char
+ if(pStructMembers)
+ pStructMembers++;
+ }
+ }
+
+ bDone = TRUE; // meanwhile
+ break;
+ case 'u': // union type
+ DPRINT((1,"%x union\n",pvr->type));
+ bDone = TRUE; // meanwhile
+ break;
+ case 'e': // enum type
+ DPRINT((1,"%x enum\n",pvr->type));
+ bDone = TRUE; // meanwhile
+ break;
+ default:
+ DPRINT((1,"DEFAULT %x, base: %c\n",pvr->type, *pTypeBase));
+ pvr->address = pvr->value;
+ if(IsRangeValid(pvr->value,ulBytes))
+ {
+ switch(ulBytes)
+ {
+ case 1:
+ pvr->value = *(PUCHAR)pvr->value;
+ break;
+ case 2:
+ pvr->value = *(PUSHORT)pvr->value;
+ break;
+ case 4:
+ pvr->value = *(PULONG)pvr->value;
+ break;
+ }
+ }
+ bDone = TRUE;
+ break;
+ }
+
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//*************************************************************************
+// Symbol()
+//
+// Symbol := v
+//*************************************************************************
+BOOLEAN Symbol(PVRET pvr)
+{
+ char SymbolToken[128];
+
+ ExtractToken(SymbolToken);
+
+ DPRINT((1,"SymbolToken = %s\n",SymbolToken));
+
+ return EvaluateSymbol(pvr,SymbolToken);
+}
+
+//*************************************************************************
+// Expression()
+//
+// Expression := Symbol | Symbol->Symbol
+//*************************************************************************
+BOOLEAN Expression(PVRET pvr)
+{
+ if(!Symbol(pvr))
+ return FALSE;
+
+ return TRUE;
+}
+
+//*************************************************************************
+// Evaluate()
+//
+//*************************************************************************
+void Evaluate(PICE_SYMBOLFILE_HEADER* pSymbols,LPSTR p)
+{
+ ULONG i;
+
+ PICE_memset(&vr,0,sizeof(vr));
+ vr.pSymbols = pSymbols;
+
+ pExpression = p;
+ ulIndex=0;
+ ulNumStructMembers=0;
+ if(Expression(&vr))
+ {
+ DPRINT((1,"\nOK!\n"));
+ DPRINT((1,"value = %x type = %x\n",vr.value,vr.type));
+ if(vr.bStructType)
+ {
+ PICE_sprintf(tempSym,"struct %s %s @ %x\n",vr.type_name,p,vr.address);
+ Print(OUTPUT_WINDOW,tempSym);
+ for(i=0;i<ulNumStructMembers;i++)
+ {
+ if(vrStructMembers[i].bArrayType)
+ {
+ PICE_sprintf(tempSym,"[%.8X %.8X] %s %s[%u]\n",
+ vrStructMembers[i].address,
+ vrStructMembers[i].size/8,
+ vrStructMembers[i].type_name,
+ vrStructMembers[i].name,
+ vrStructMembers[i].size/8);
+ }
+ else if(vrStructMembers[i].bPtrType)
+ {
+ PICE_sprintf(tempSym,"[%.8X %.8X] %s* %s -> %x (%u)\n",
+ vrStructMembers[i].address,
+ vrStructMembers[i].size/8,
+ vrStructMembers[i].type_name,
+ vrStructMembers[i].name,
+ vrStructMembers[i].value,
+ vrStructMembers[i].value);
+ }
+ else
+ {
+ PICE_sprintf(tempSym,"[%.8X %.8X] %s %s = %x (%u)\n",
+ vrStructMembers[i].address,
+ vrStructMembers[i].size/8,
+ vrStructMembers[i].type_name,
+ vrStructMembers[i].name,
+ vrStructMembers[i].value,
+ vrStructMembers[i].value);
+ }
+ Print(OUTPUT_WINDOW,tempSym);
+ }
+ }
+ else if(vr.bArrayType)
+ {
+ Print(OUTPUT_WINDOW,"array\n");
+ }
+ else
+ {
+ PICE_sprintf(tempSym,"%s %s @ %x = %x (%u)\n",vr.type_name,p,vr.address,vr.value,vr.value);
+ Print(OUTPUT_WINDOW,tempSym);
+ }
+ }
+ else
+ {
+ DPRINT((1,"\nERROR: code %x\n",vr.error));
+ }
+}
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ symbols.h
+
+Abstract:
+
+ HEADER for symbols.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+typedef struct _LOCAL_VARIABLE
+{
+ char type_name[64];
+ char name[64];
+ ULONG value,offset,line;
+ BOOLEAN bRegister;
+}LOCAL_VARIABLE,*PLOCAL_VARIABLE;
+
+
+struct _DEBUG_MODULE_SYMBOL_
+{
+ ULONG value;
+ char* name;
+};
+
+typedef struct _DEBUG_MODULE_
+{
+ struct _DEBUG_MODULE_ *next;
+ ULONG size;
+ PVOID BaseAddress;
+ PVOID EntryPoint;
+ WCHAR name[DEBUG_MODULE_NAME_LEN];
+ struct _DEBUG_MODULE_SYMBOL_ syms;
+}DEBUG_MODULE, *PDEBUG_MODULE;
+
+BOOLEAN InitFakeKernelModule(void);
+BOOLEAN LoadExports(void);
+BOOLEAN SanityCheckExports(void);
+void UnloadExports(void);
+BOOLEAN ScanExports(const char *pFind,PULONG pValue);
+BOOLEAN ScanExportsByAddress(LPSTR *pFind,ULONG ulValue);
+PICE_SYMBOLFILE_HEADER* LoadSymbols(LPSTR filename);
+BOOLEAN LoadSymbolsFromConfig(BOOLEAN bIgnoreBootParams);
+void UnloadSymbols(void);
+BOOLEAN ReloadSymbols(void);
+LPSTR FindFunctionByAddress(ULONG ulValue,PULONG pulstart,PULONG pulend);
+LPSTR FindSourceLineForAddress(ULONG addr,PULONG pulLineNumber,LPSTR* ppSrcStart,LPSTR* ppSrcEnd,LPSTR* ppFilename);
+PLOCAL_VARIABLE FindLocalsByAddress(ULONG addr);
+ULONG FindFunctionInModuleByName(LPSTR szFunctionname, PDEBUG_MODULE pMod);
+PICE_SYMBOLFILE_HEADER* FindModuleSymbolsByModuleName(LPSTR modname);
+BOOLEAN FindAddressForSourceLine(ULONG ulLineNumber,LPSTR pFilename, PDEBUG_MODULE pMod,PULONG pValue);
+ULONG ConvertDecimalToUlong(LPSTR p);
+PDEBUG_MODULE FindModuleFromAddress(ULONG addr);
+PICE_SYMBOLFILE_HEADER* FindModuleSymbols(ULONG addr);
+ULONG ListSymbolStartingAt(PDEBUG_MODULE pMod,PICE_SYMBOLFILE_HEADER* pSymbols,ULONG index,LPSTR pOutput);
+PDEBUG_MODULE FindModuleByName(LPSTR modname);
+void Evaluate(PICE_SYMBOLFILE_HEADER* pSymbols,LPSTR p);
+LONG ExtractNumber(LPSTR p);
+LPSTR ExtractTypeName(LPSTR p);
+PDEBUG_MODULE IsModuleLoaded(LPSTR p);
+
+//extern ULONG kernel_end;
+extern PICE_SYMBOLFILE_HEADER* apSymbols[32];
+
+//extern struct module fake_kernel_module;
+#define KERNEL_START (0xc0000000)
+
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ syscall.c
+
+Abstract:
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 12-Nov-1999: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+
+char syscallTemp[1024];
+
+typedef struct _FRAME_SYSCALL
+{
+ ULONG eip;
+ ULONG cs;
+ ULONG eflags;
+}FRAME_SYSCALL;
+
+BOOLEAN bReportProcessEvents = TRUE;
+
+ULONG OldSyscallHandler=0;
+
+ULONG ulFreeModule=0;
+
+PDEBUG_MODULE pModJustFreed=NULL;
+void (*old_cleanup_module)(void)=NULL;
+
+void other_module_cleanup_module(void)
+{
+ DPRINT((0,"other_module_cleanup_module()\n"));
+
+ if(old_cleanup_module)
+ {
+ DPRINT((0,"other_module_cleanup_module(): calling %x\n",(ULONG)old_cleanup_module));
+ old_cleanup_module();
+ }
+
+ if(pModJustFreed)
+ {
+ DPRINT((0,"other_module_cleanup_module(): calling RevirtualizeBreakpointsForModule(%x)\n",(ULONG)pModJustFreed));
+ RevirtualizeBreakpointsForModule(pModJustFreed);
+ }
+}
+
+void CSyscallHandler(FRAME_SYSCALL* ptr,ULONG ulSysCall,ULONG ebx)
+{
+// DPRINT((0,"CSyscallHandler(): %.4X:%.8X (syscall = %u)\n",ptr->cs,ptr->eip,ulSysCall));
+/*
+ switch(ulSysCall)
+ {
+ case 1: // sys_exit
+ DPRINT((0,"CSysCallHandler(): 1\n"));
+ if(bReportProcessEvents)
+ {
+ PICE_sprintf(syscallTemp,"pICE: process destroyed \"%s\" PID=%.4X\n",current->comm,current->pid);
+ AddToRingBuffer(syscallTemp);
+ }
+ break;
+ case 11: // sys_execve
+ DPRINT((0,"CSysCallHandler(): 11\n"));
+ if(bReportProcessEvents)
+ {
+ if(PICE_strlen((char*)ebx))
+ PICE_sprintf(syscallTemp,"pICE: process created \"%s\" PID=%.4X (parent \"%s\")\n",(char *)ebx,current->pid,current->comm);
+ else
+ PICE_sprintf(syscallTemp,"pICE: process created PID=%.4X (parent \"%s\")\n",current->pid,current->comm);
+ AddToRingBuffer(syscallTemp);
+ }
+ break;
+ case 128: // sys_init_module
+ DPRINT((0,"CSysCallHandler(): 128\n"));
+ if(PICE_strlen((char *)ebx))
+ {
+ if(pmodule_list)
+ {
+ struct module* pMod = *pmodule_list;
+ do
+ {
+ if(PICE_strcmpi((char*)ebx,(LPSTR)pMod->name)==0)
+ {
+ ULONG ulInitAddress;
+ PICE_sprintf(syscallTemp,"pICE: module \"%s\" loaded (%x-%x init @ %x)\n",(char*)ebx,pMod,(ULONG)pMod+pMod->size,pMod->init);
+ if((ulInitAddress=FindFunctionInModuleByName("init_module",pMod)))
+ {
+ DPRINT((0,"setting DR1=%.8x\n",ulInitAddress));
+
+ SetHardwareBreakPoint(ulInitAddress,1);
+ }
+ }
+ }while((pMod = pMod->next));
+ }
+ else
+ {
+ PICE_sprintf(syscallTemp,"pICE: module loaded \"%s\"\n",(char *)ebx);
+ }
+ }
+ else
+ PICE_sprintf(syscallTemp,"pICE: module loaded\n");
+ AddToRingBuffer(syscallTemp);
+ break;
+ case 129: // sys_delete_module
+ DPRINT((0,"CSysCallHandler(): 129\n"));
+ if(PICE_strlen((char *)ebx))
+ {
+ if(IsModuleLoaded((LPSTR)ebx)!=NULL && PICE_strcmpi((char*)ebx,"pice")!=0 )
+ {
+ PICE_sprintf(syscallTemp,"pICE: module freed \"%s\"\n",(char *)ebx);
+ Print(OUTPUT_WINDOW,syscallTemp);
+ if((pModJustFreed = FindModuleByName((char*)ebx)) )
+ {
+ if(pModJustFreed->cleanup)
+ {
+ old_cleanup_module = pModJustFreed->cleanup;
+ pModJustFreed->cleanup = other_module_cleanup_module;
+ }
+ else
+ {
+ RevirtualizeBreakpointsForModule(pModJustFreed);
+ }
+ }
+ }
+ }
+ else
+ {
+ PICE_sprintf(syscallTemp,"pICE: module freed\n");
+ AddToRingBuffer(syscallTemp);
+ }
+ break;
+ }
+ */
+}
+
+__asm__ ("\n\t \
+NewSyscallHandler:\n\t \
+ // save used regs\n\t \
+ pushfl\n\t \
+ cli\n\t \
+ cld\n\t \
+ pushal\n\t \
+ pushl %ds\n\t \
+\n\t \
+ // push the syscall number\n\t \
+ pushl %ebx\n\t \
+ pushl %eax\n\t \
+\n\t \
+ // frame ptr\n\t \
+ lea 48(%esp),%eax\n\t \
+ pushl %eax\n\t \
+\n\t \
+ // setup default data selectors\n\t \
+ movw %ss,%ax\n\t \
+ movw %ax,%ds\n\t \
+\n\t \
+ call _CSyscallHandler\n\t \
+\n\t \
+ // remove pushed params\n\t \
+ add $12,%esp\n\t \
+\n\t \
+ // restore used regs\n\t \
+ popl %ds\n\t \
+ popal\n\t \
+ popfl\n\t \
+\n\t \
+ // chain to old handler\n\t \
+ .byte 0x2e\n\t \
+ jmp *_OldSyscallHandler");
+
+void InstallSyscallHook(void)
+{
+ ULONG LocalSyscallHandler;
+
+ ENTER_FUNC();
+/*ei fix later
+ MaskIrqs();
+ if(!OldSyscallHandler)
+ {
+ __asm__("mov $NewSyscallHandler,%0"
+ :"=r" (LocalSyscallHandler)
+ :
+ :"eax");
+ OldSyscallHandler=SetGlobalInt(0x2e,(ULONG)LocalSyscallHandler);
+
+ ScanExports("free_module",(PULONG)&ulFreeModule);
+
+ DPRINT((0,"InstallSyscallHook(): free_module @ %x\n",ulFreeModule));
+ }
+ UnmaskIrqs();
+ */
+ LEAVE_FUNC();
+}
+
+void DeInstallSyscallHook(void)
+{
+ ENTER_FUNC();
+/*ei
+ MaskIrqs();
+ if(OldSyscallHandler)
+ {
+ SetGlobalInt(0x2e,(ULONG)OldSyscallHandler);
+ (ULONG)OldSyscallHandler=0;
+ }
+ UnmaskIrqs();
+*/
+ LEAVE_FUNC();
+}
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ syscall.h
+
+Abstract:
+
+ HEADER for syscall.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+void InstallSyscallHook(void);
+void DeInstallSyscallHook(void);
+
+void CReturnFromSyscallHandler(void);
+
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ trace.c
+
+Abstract:
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 19-Aug-1998: created
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+
+#include "precomp.h"
+
+extern void NewInt31Handler(void);
+
+void DeInstallTraceHook(void);
+
+volatile ULONG OldInt1Handler=0;
+
+BOOLEAN InstallTraceHook(void)
+{
+ ULONG LocalInt1Handler;
+
+ DPRINT((0,"InstallTraceHook(OldInt1Handler=%0.8x)...\n",OldInt1Handler));
+
+ MaskIrqs();
+ if(!OldInt1Handler)
+ {
+ __asm__("mov $NewInt1Handler,%0"
+ :"=r" (LocalInt1Handler)
+ :
+ :"eax");
+ OldInt1Handler=SetGlobalInt(0x01,(ULONG)LocalInt1Handler);
+ }
+ UnmaskIrqs();
+ return TRUE;
+}
+
+//this asm function must be at least second in the file. otherwise gcc does not
+//generate correct code.
+__asm__("\n\t \
+NewInt1Handler:\n\t \
+ pushl %eax\n\t \
+ movl %dr6,%eax\n\t \
+ testl $(1<<14),%eax\n\t \
+ jz exceptionnotsinglestep\n\t \
+\n\t \
+ popl %eax\n\t \
+ pushl $" STR(REASON_SINGLESTEP) "\n\t \
+ jmp NewInt31Handler\n\t \
+\n\t \
+exceptionnotsinglestep:\n\t \
+ popl %eax\n\t \
+ pushl $" STR(REASON_HARDWARE_BP) "\n\t \
+ jmp NewInt31Handler\n\t \
+");
+
+void DeInstallTraceHook(void)
+{
+ DPRINT((0,"DeInstallTraceHook(OldInt1Handler=%0.8x)...\n",OldInt1Handler));
+
+ MaskIrqs();
+ if(OldInt1Handler)
+ {
+ SetGlobalInt(0x01,(ULONG)OldInt1Handler);
+ OldInt1Handler = 0;
+ }
+ UnmaskIrqs();
+}
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ trace.h
+
+Abstract:
+
+ HEADER for trace.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+void DeInstallTraceHook(void);
+BOOLEAN InstallTraceHook(void);
+void NewInt1Handler(void);
+
+extern volatile ULONG OldInt1Handler;
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ util.c
+
+Abstract:
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 19-Aug-1998: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+#include <defines.h>
+
+
+////////////////////////////////////////////////////
+// GLOBALS
+////
+// output string
+char tempUtil[1024];
+char tempFlowChanges[256];
+
+//PMADDRESS_SPACE my_init_mm=NULL;
+
+ULONG TwoPagesForPhysMem[2*_PAGE_SIZE];
+
+// scancode to ASCII table
+SCANTOASCII ucScanToAscii_DE[]=
+{
+// German keyboard
+ {16,'q'},{17,'w'},{18,'e'},{19,'r'},{20,'t'},
+ {21,'z'},{22,'u'},{23,'i'},{24,'o'},{25,'p'},
+ {30,'a'},{31,'s'},{32,'d'},{33,'f'},{34,'g'},
+ {35,'h'},{36,'j'},{37,'k'},{38,'l'},
+ {44,'y'},{45,'x'},{46,'c'},{47,'v'},{48,'b'},
+ {49,'n'},{50,'m'},
+ {2,'1'},{3,'2'},{4,'3'},{ 5,'4'},{ 6,'5'},
+ {7,'6'},{8,'7'},{9,'8'},{10,'9'},{11,'0'},
+ {12,'ß'}, // 239 = ß
+ {0x39,' '},{0x35,'-'},{0x34,'.'},{0x1b,'+'},
+ {0,0}
+};
+
+SCANTOASCII ucShiftScanToAscii_DE[]=
+{
+// German keyboard SHIFTED
+ {16,'Q'},{17,'W'},{18,'E'},{19,'R'},{20,'T'},
+ {21,'Z'},{22,'U'},{23,'I'},{24,'O'},{25,'P'},
+ {30,'A'},{31,'S'},{32,'D'},{33,'F'},{34,'G'},
+ {35,'H'},{36,'J'},{37,'K'},{38,'L'},
+ {44,'Y'},{45,'X'},{46,'C'},{47,'V'},{48,'B'},
+ {49,'N'},{50,'M'},
+ {2,'!'},{3,'\"'}, // " // (fixes mc syntax highlighting)
+ {4,'@'}, // is pragraph sign on keyboard
+ { 5,'$'},{ 6,'%'},
+ {7,'&'},{8,'/'},{9,'('},{10,')'},{11,'='},
+ {12,'?'},
+ {0x39,' '},{0x35,'_'},{0x34,':'},{0x1b,'*'},
+ {0,0}
+};
+
+SCANTOASCII ucScanToAscii_US[]=
+{
+// US keyboard
+ {16,'q'},{17,'w'},{18,'e'},{19,'r'},
+ {20,'t'},{21,'y'},{22,'u'},{23,'i'},
+ {24,'o'},{25,'p'},{30,'a'},{31,'s'},
+ {32,'d'},{33,'f'},{34,'g'},{35,'h'},
+ {36,'j'},{37,'k'},{38,'l'},{44,'z'},
+ {45,'x'},{46,'c'},{47,'v'},{48,'b'},
+ {49,'n'},{50,'m'},{2,'1'},{3,'2'},
+ {4,'3'},{5,'4'},{6,'5'},{7,'6'},
+ {8,'7'},{9,'8'},{10,'9'},{11,'0'},{12,'-'},
+ {0x39,' '},{0x35,'/'},{0x34,'.'},{0x1b,']'},
+ {0x1a,'['},{0x33,','},{0x27,';'},{0x0d,'='},
+ {0x2b,'\\'},{0x28,'\''},{0x29,'`'},
+ {0,0}
+};
+
+SCANTOASCII ucShiftScanToAscii_US[]=
+{
+// US keyboard SHIFTED
+ {16,'Q'},{17,'W'},{18,'E'},{19,'R'},
+ {20,'T'},{21,'Y'},{22,'U'},{23,'I'},
+ {24,'O'},{25,'P'},{30,'A'},{31,'S'},
+ {32,'D'},{33,'F'},{34,'G'},{35,'H'},
+ {36,'J'},{37,'K'},{38,'L'},{44,'Z'},
+ {45,'X'},{46,'C'},{47,'V'},{48,'B'},
+ {49,'N'},{50,'M'},{2,'!'},{3,'@'},
+ {4,'#'},{5,'$'},{6,'%'},{7,'^'},
+ {8,'&'},{9,'*'},{10,'('},{11,')'},{12,'_'},
+ {0x39,' '},{0x35,'?'},{0x34,'>'},{0x1b,'}'},
+ {0x1a,'{'},{0x33,'<'},{0x27,':'},{0x0d,'+'},
+ {0x2b,'|'},{0x28,'\"'},{0x29,'~'},
+ {0,0}
+};
+
+
+SCANTOASCII ucScanToAscii_DK[]=
+{
+// Danish keyboard
+ {16,'q'},{17,'w'},{18,'e'},{19,'r'},
+ {20,'t'},{21,'y'},{22,'u'},{23,'i'},
+ {24,'o'},{25,'p'},{30,'a'},{31,'s'},
+ {32,'d'},{33,'f'},{34,'g'},{35,'h'},
+ {36,'j'},{37,'k'},{38,'l'},{44,'z'},
+ {45,'x'},{46,'c'},{47,'v'},{48,'b'},
+ {49,'n'},{50,'m'},{2,'1'},{3,'2'},
+ {4,'3'},{5,'4'},{6,'5'},{7,'6'},
+ {8,'7'},{9,'8'},{10,'9'},{11,'0'},{12,'+'},
+ {0x39,' '},{0x35,'-'},{0x34,'.'},{0x1b,'¨'},
+ {0x1a,'å'},{0x33,','},{0x27,'æ'},{0x0d,'´'},
+ {0x2b,'\''},{0x28,'ø'},{0x29,' '},
+ {0,0}
+};
+
+SCANTOASCII ucShiftScanToAscii_DK[]=
+{
+// Danish keyboard SHIFTED
+ {16,'Q'},{17,'W'},{18,'E'},{19,'R'},
+ {20,'T'},{21,'Y'},{22,'U'},{23,'I'},
+ {24,'O'},{25,'P'},{30,'A'},{31,'S'},
+ {32,'D'},{33,'F'},{34,'G'},{35,'H'},
+ {36,'J'},{37,'K'},{38,'L'},{44,'Z'},
+ {45,'X'},{46,'C'},{47,'V'},{48,'B'},
+ {49,'N'},{50,'M'},{2,'!'},{3,'"'},
+ {4,'#'},{5,'¤'},{6,'%'},{7,'&'},
+ {8,'/'},{9,'('},{10,')'},{11,'='},{12,'?'},
+ {0x39,' '},{0x35,'_'},{0x34,':'},{0x1b,'^'},
+ {0x1a,'Å'},{0x33,';'},{0x27,'Æ'},{0x0d,'`'},
+ {0x2b,'*'},{0x28,'Ø'},{0x29,'§'},
+ {0,0}
+};
+
+SCANTOASCII ucAltScanToAscii_DK[]=
+{
+// Danish keyboard ALTED
+ {16,' '},{17,' '},{18,' '},{19,' '},
+ {20,' '},{21,' '},{22,' '},{23,' '},
+ {24,' '},{25,' '},{30,' '},{31,' '},
+ {32,' '},{33,' '},{34,' '},{35,' '},
+ {36,' '},{37,' '},{38,' '},{44,' '},
+ {45,' '},{46,' '},{47,' '},{48,' '},
+ {49,' '},{50,' '},{2,' '},{3,'@'},
+ {4,'£'},{5,'$'},{6,'\80'},{7,' '},
+ {8,'{'},{9,'['},{10,']'},{11,'}'},{12,' '},
+ {0x39,' '},{0x35,' '},{0x34,' '},{0x1b,'~'},
+ {0x1a,' '},{0x33,' '},{0x27,' '},{0x0d,'|'},
+ {0x2b,' '},{0x28,' '},{0x29,' '},
+ {0,0}
+};
+
+KEYBOARD_LAYOUT ucKeyboard[]=
+{
+ {"de", ucScanToAscii_DE, ucShiftScanToAscii_DE, NULL},
+ {"us", ucScanToAscii_US, ucShiftScanToAscii_US, NULL},
+ {"dk", ucScanToAscii_DK, ucShiftScanToAscii_DK, ucAltScanToAscii_DK},
+ {NULL, NULL, NULL, NULL}
+};
+
+PKEYBOARD_LAYOUT CurrentKeyboard = NULL;
+
+
+////////////////////////////////////////////////////
+// FUNCTIONS
+////
+
+//*************************************************************************
+// GetKeyboardLayout()
+//
+//*************************************************************************
+PKEYBOARD_LAYOUT GetKeyboardLayout()
+{
+ if (CurrentKeyboard == NULL)
+ {
+ CurrentKeyboard = &ucKeyboard[kbUS];
+ }
+
+ return CurrentKeyboard;
+}
+
+//*************************************************************************
+// SetKeyboardLayoutByName()
+//
+//*************************************************************************
+PKEYBOARD_LAYOUT SetKeyboardLayoutByName(LPSTR Name)
+{
+ CHAR tempCmd[256];
+ ULONG i;
+
+ for(i=0;ucKeyboard[i].name != NULL;i++)
+ {
+ if(PICE_strcmpi(ucKeyboard[i].name, Name) == 0)
+ {
+ CurrentKeyboard = &ucKeyboard[i];
+ return CurrentKeyboard;
+ }
+ }
+ return GetKeyboardLayout();
+}
+
+//*************************************************************************
+// PICE_memset()
+//
+//*************************************************************************
+void PICE_memset(void* p,unsigned char c,int sz)
+{
+ unsigned char *p2 = (unsigned char *)p;
+ while(sz--)
+ *p2++ = c;
+}
+
+//*************************************************************************
+// PICE_memcpy()
+//
+//*************************************************************************
+void PICE_memcpy(void* t,void* s,int sz)
+{
+ memcpy(t,s,sz);
+}
+
+//*************************************************************************
+// PICE_isprint()
+//
+//*************************************************************************
+BOOLEAN PICE_isprint(char c)
+{
+ BOOLEAN bResult = FALSE;
+
+ if((ULONG)c>=0x20 && (ULONG)c<=0x7f)
+ bResult = TRUE;
+
+ return bResult;
+}
+
+//*************************************************************************
+// PICE_strchr()
+//
+//*************************************************************************
+char* PICE_strchr(char* s,char c)
+{
+ while(IsAddressValid((ULONG)s) && *s)
+ {
+ if(*s == c)
+ return s;
+ s++;
+ }
+#ifdef DEBUG
+ if(!IsAddressValid((ULONG)s) )
+ {
+ DPRINT((0,"PICE_strchr(): ********************\n"));
+ DPRINT((0,"PICE_strchr(): EXCEPTION @ %.8X\n",(ULONG)s));
+ DPRINT((0,"PICE_strchr(): ********************\n"));
+ }
+#endif
+
+ return NULL;
+}
+
+//*************************************************************************
+// PICE_strncpy()
+//
+//*************************************************************************
+char* PICE_strncpy(char* s1,char* s2,int len)
+{
+ ULONG len2 = PICE_strlen(s2);
+
+ if(len<len2)
+ PICE_memcpy(s1,s2,len2+1);
+ else
+ PICE_memcpy(s1,s2,len);
+
+ return s1;
+}
+
+//*************************************************************************
+// PICE_strcpy()
+//
+//*************************************************************************
+char* PICE_strcpy(char* s1,char* s2)
+{
+ ULONG len2 = PICE_strlen(s2);
+
+ PICE_memcpy(s1,s2,len2+1);
+
+ return s1;
+}
+
+//*************************************************************************
+// PICE_strcat()
+//
+//*************************************************************************
+char* PICE_strcat(char* s1,char* s2)
+{
+ ULONG len1 = PICE_strlen(s1);
+ ULONG len2 = PICE_strlen(s2);
+
+ PICE_memcpy(&s1[len1],s2,len2+1);
+
+ return s1;
+}
+
+//*************************************************************************
+// PICE_toupper()
+//
+//*************************************************************************
+char PICE_toupper(char c)
+{
+ if(c>='a' && c<='z')
+ c = (c-'a')+'A';
+
+ return c;
+}
+
+int PICE_isdigit( int c )
+{
+ return ((c>=0x30) && (c<=0x39));
+}
+
+int PICE_isxdigit( int c )
+{
+ return (PICE_isdigit(c) || ((c>=0x41) && (c<=0x46)) || ((c>=0x61) && (c<=0x66)));
+}
+
+int PICE_islower( int c )
+{
+ return ((c>=0x61) && (c<=0x7a));
+}
+
+int PICE_isalpha( int c )
+{
+ return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
+}
+
+//*************************************************************************
+// PICE_strncmpi()
+//
+// my version of strncmpi()
+//*************************************************************************
+ULONG PICE_strncmpi(char* s1,char* s2,ULONG len)
+{
+ULONG result=1;
+
+ while(len &&
+ IsAddressValid((ULONG)s1) && *s1 && // not end of string
+ IsAddressValid((ULONG)s2) && *s2 && // not end of string
+ PICE_toupper(*s1)==PICE_toupper(*s2) ) // char are the same except case
+ {
+ s1++;
+ s2++;
+ len--;
+ }
+ // strings same length
+ if(len==0)
+ result=0;
+
+ return result;
+}
+
+//*************************************************************************
+// PICE_strcmpi()
+//
+// my version of strcmp()
+//*************************************************************************
+ULONG PICE_strcmpi(char* s1,char* s2)
+{
+ULONG result=1;
+
+ while(IsAddressValid((ULONG)s1) && *s1 && // not end of string
+ IsAddressValid((ULONG)s2) && *s2 && // not end of string
+ PICE_toupper(*s1)==PICE_toupper(*s2) ) // char are the same except case
+ {
+ s1++;
+ s2++;
+ }
+ // strings same length
+ if(*s1==0 && *s2==0)
+ result=0;
+
+ return result;
+}
+
+//*************************************************************************
+// PICE_strcmp()
+//
+// my version of strcmp()
+//*************************************************************************
+ULONG PICE_strcmp(char* s1,char* s2)
+{
+ ULONG result=1;
+
+ while(IsAddressValid((ULONG)s1) && *s1 && // not end of string
+ IsAddressValid((ULONG)s2) && *s2 && // not end of string
+ (*s1)==(*s2) )
+ {
+ s1++;
+ s2++;
+ }
+ // strings same length
+ if(*s1==0 && *s2==0)
+ result=0;
+
+ return result;
+}
+
+//*************************************************************************
+// PICE_fncmp()
+//
+// compare function names ignoring decorations:
+// leading '_' or '@" and trailing "@xx"
+//*************************************************************************
+ULONG PICE_fncmp(char* s1,char* s2)
+{
+ ULONG result=1;
+
+ if( IsAddressValid((ULONG)s1) && (*s1 == '_' || *s1 == '@'))
+ s1++;
+
+ if( IsAddressValid((ULONG)s2) && (*s2 == '_' || *s2 == '@'))
+ s2++;
+
+ while(IsAddressValid((ULONG)s1) && *s1 && // not end of string
+ IsAddressValid((ULONG)s2) && *s2 )
+ {
+ if( (*s1 != *s2) || *s1=='@' || *s2=='@' )
+ break;
+ s1++;
+ s2++;
+ }
+ // strings same length
+ if((*s1==0 || *s1=='@') && (*s2==0 || *s2 =='@')){
+ result=0;
+ }
+ return result;
+}
+
+//*************************************************************************
+// PICE_fnncmp()
+//
+// compare function names ignoring decorations:
+// leading '_' or '@" and trailing "@xx" . Decorations are included in total length.
+//*************************************************************************
+ULONG PICE_fnncmp(char* s1,char* s2, ULONG len)
+{
+ ULONG result=1;
+ ULONG len1 = len, len2 = len;
+
+ if( IsAddressValid((ULONG)s1) && (*s1 == '_' || *s1 == '@')){
+ s1++;
+ len1--;
+ }
+
+ if( IsAddressValid((ULONG)s2) && (*s2 == '_' || *s2 == '@')){
+ s2++;
+ len2--;
+ }
+
+ while(len1 && len2 && IsAddressValid((ULONG)s1) && *s1 && // not end of string
+ IsAddressValid((ULONG)s2) && *s2 )
+ {
+ if( (*s1 != *s2) || *s1=='@' || *s2=='@' )
+ break;
+ s1++;
+ s2++;
+ len1--;
+ len2--;
+ }
+ // strings are the same length
+ if((*s1=='\0' || *s1=='@') && (*s2=='\0' || *s2 =='@')){
+ result=0;
+ }
+ return result;
+}
+
+wchar_t PICE_towlower(wchar_t c)
+{
+ if ( c>=L'A' && c<=L'Z' )
+ return (c - (L'A' - L'a'));
+ return(c);
+}
+
+ULONG PICE_wcsicmp(WCHAR* s1, WCHAR* s2)
+{
+ ULONG result=1;
+
+ while(IsAddressValid((ULONG)s1) && *s1 && // not end of string
+ IsAddressValid((ULONG)s2) && *s2 && // not end of string
+ PICE_towlower(*s1)==PICE_towlower(*s2) ) // char are the same except case
+ {
+ s1++;
+ s2++;
+ }
+ // strings same length
+ if(*s1==0 && *s2==0)
+ result=0;
+
+ return result;
+}
+
+//*************************************************************************
+// PICE_strrev()
+//
+// my version of strrev()
+//*************************************************************************
+char* PICE_strrev(char* s)
+{
+ULONG i,j,len=PICE_strlen(s)-1;
+char c;
+
+ for(i=0,j=len;i<j;i++,j--)
+ {
+ c=s[i]; s[i]=s[j]; s[j]=c;
+ }
+
+ return s;
+}
+
+//*************************************************************************
+// PICE_strlen()
+//
+// my version of strlen()
+//
+// does a page validity check on every character in th string
+//*************************************************************************
+USHORT PICE_strlen(const char* s)
+{
+ USHORT i;
+
+ for(i=0;IsAddressValid((ULONG)&s[i]) && s[i]!=0 && i<_PAGE_SIZE;i++);
+
+ if(IsAddressValid((ULONG)&s[i]) && s[i]==0)
+ return i;
+
+ return 0;
+}
+
+WCHAR * PICE_wcscpy(WCHAR * str1,const WCHAR * str2)
+{
+ WCHAR *save = str1;
+
+ for (; (*str1 = *str2); ++str2, ++str1);
+ return save;
+}
+
+#ifndef LINUX
+//*************************************************************************
+// GetShortName()
+//
+// separates module name from path
+//*************************************************************************
+LPSTR GetShortName(LPSTR p)
+{
+ULONG i;
+
+ // scan backwards till backslash or start
+ for(i=PICE_strlen(p);p[i]!='\\' && &p[i]!=p;i--);
+ // it's not start, inc. counter
+ if(&p[i]!=p)i++;
+
+ // return section of string containing mod name
+ return &p[i];
+}
+
+//*************************************************************************
+// CopyWideToAnsi()
+//
+// copy wide string to ANSI string
+//*************************************************************************
+void CopyWideToAnsi(LPSTR pAnsi,PWSTR pWide)
+{
+ULONG j;
+
+ for(j=0;pWide[j]!=0;j++)
+ {
+ if((char)(pWide[j]>>8)==0)
+ pAnsi[j]=(char)(pWide[j]);
+ else
+ pAnsi[j]=0x20;
+ }
+ pAnsi[j]=0;
+
+}
+#endif // LINUX
+
+//*************************************************************************
+// IsAddressValid()
+//
+//*************************************************************************
+BOOLEAN IsAddressValid(ULONG address)
+{
+ PULONG pPGD;
+ PULONG pPTE;
+ BOOLEAN bResult = FALSE;
+
+ address &= (~(_PAGE_SIZE-1));
+
+ pPGD = ADDR_TO_PDE(address);
+ if(pPGD && ((*pPGD)&_PAGE_PRESENT))
+ {
+ // not large page
+ if(!((*pPGD)&_PAGE_4M))
+ {
+ pPTE = ADDR_TO_PTE(address);
+ if(pPTE)
+ {
+ bResult = (*pPTE)&(_PAGE_PRESENT | _PAGE_PSE);
+ }
+ }
+ // large page
+ else
+ {
+ bResult = TRUE;
+ }
+ }
+
+ return bResult;
+}
+
+
+//*************************************************************************
+// IsAddressWriteable()
+//
+// returns:
+// TRUE if adress/page is writeable
+// FALSE if adress/page is not writeable
+//
+//*************************************************************************
+BOOLEAN IsAddressWriteable(ULONG address)
+{
+ PULONG pPGD;
+ PULONG pPTE;
+
+ //address &= (~(_PAGE_SIZE-1));
+ pPGD = ADDR_TO_PDE(address);
+ if(pPGD && ((*pPGD)&_PAGE_PRESENT))
+ {
+ // not large page
+ if(!((*pPGD)&_PAGE_4M))
+ {
+ if(!((*pPGD) & _PAGE_RW))
+ return FALSE;
+
+ pPTE = ADDR_TO_PTE(address);
+ if(pPTE)
+ {
+ if( ((*pPTE)&(_PAGE_PRESENT | _PAGE_PSE)) &&
+ ((*pPTE) & _PAGE_RW))
+ return TRUE;
+ else
+ return FALSE;
+ }
+ }
+ // large page
+ else
+ return ((*pPGD) & _PAGE_RW);
+ }
+
+ return FALSE;
+}
+
+
+//*************************************************************************
+// SetAddressWriteable()
+//
+//*************************************************************************
+BOOLEAN SetAddressWriteable(ULONG address,BOOLEAN bSet)
+{
+ PULONG pPGD;
+ PULONG pPTE;
+
+ //address &= (~(_PAGE_SIZE-1));
+
+ pPGD = ADDR_TO_PDE(address);
+ if(pPGD && ((*pPGD)&_PAGE_PRESENT))
+ {
+ // not large page
+ if(!((*pPGD)&_PAGE_4M))
+ {
+ pPTE = ADDR_TO_PTE(address);
+ if(pPTE)
+ {
+ if( (*pPTE)&(_PAGE_PRESENT | _PAGE_PSE) )
+ {
+ if( bSet ){
+ *pPTE |= _PAGE_RW;
+ }
+ else{
+ *pPTE &= ~_PAGE_RW;
+ }
+ FLUSH_TLB;
+ return TRUE;
+ }
+ }
+ }
+ // large page
+ else
+ {
+ if( bSet )
+ *pPGD |= _PAGE_RW;
+ else
+ *pPGD &= ~_PAGE_RW;
+ FLUSH_TLB;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+//*************************************************************************
+// IsRangeValid()
+//
+// scan range for page present
+//*************************************************************************
+BOOLEAN IsRangeValid(ULONG Addr,ULONG Length)
+{
+ULONG i,NumPages,PageNum;
+
+ // need to only touch one byte per page
+ // calculate PICE_number of pages to touch
+ NumPages=(Length+(_PAGE_SIZE-1))>>12;
+
+ // calculate PICE_number of page
+ PageNum=Addr>>PAGE_SHIFT;
+
+ // touch all pages containing range
+ for(i=0;i<NumPages;i++)
+ {
+ // if any one page is invalid range is invalid
+ if(!IsAddressValid((ULONG)((PageNum+i)*_PAGE_SIZE)) )
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+//*************************************************************************
+// GetGDTPtr()
+//
+// return flat address of GDT
+//*************************************************************************
+PGDT GetGDTPtr(void)
+{
+ULONG gdtr[2];
+PGDT pGdt;
+
+ ENTER_FUNC();
+
+ __asm__("sgdt %0;":"=m" (gdtr));
+ pGdt=(PGDT)(((ULONG)(gdtr[1]<<16))|((ULONG)(gdtr[0]>>16)));
+
+ LEAVE_FUNC();
+
+ return pGdt;
+}
+
+//*************************************************************************
+// GetLinearAddress()
+//
+// return flat address for SEGMENT:OFFSET
+//*************************************************************************
+ULONG GetLinearAddress(USHORT Segment,ULONG Offset)
+{
+ PGDT pGdt;
+ ULONG result=0;
+ PDESCRIPTOR pSel;
+ USHORT OriginalSegment=Segment;
+
+ ENTER_FUNC();
+
+ pSel=(struct tagDESCRIPTOR*)&Segment;
+
+ // get GDT pointer
+ pGdt=GetGDTPtr();
+ DPRINT((0,"GetLinearAddress(): pGDT = %.8X\n",pGdt));
+ DPRINT((0,"GetLinearAddress(): original Segment:Offset = %.4X:%.8X\n",Segment,Offset));
+
+ // see if segment selector is in LDT
+ if(pSel->Ti)
+ {
+ DPRINT((0,"GetLinearAddress(): Segment is in LDT\n"));
+ // get LDT selector
+ __asm__("\n\t \
+ sldt %%ax\n\t \
+ mov %%ax,%0"
+ :"=m" (Segment));
+ if(Segment)
+ {
+ DPRINT((0,"GetLinearAddress(): no LDT\n"));
+ // get LDT selector
+ pGdt=(PGDT)((pGdt[pSel->Val].Base_31_24<<24)|
+ (pGdt[pSel->Val].Base_23_16<<16)|
+ (pGdt[pSel->Val].Base_15_0));
+ if(!IsRangeValid((ULONG)pGdt,0x8) )
+ pGdt=0;
+ }
+ else
+ {
+ pGdt=0;
+ }
+ }
+
+ if(pGdt && Segment)
+ {
+ DPRINT((0,"GetLinearAddress(): Segment:Offset = %.4X:%.8X\n",Segment,Offset));
+ result=pGdt[OriginalSegment>>3].Base_15_0|
+ (pGdt[OriginalSegment>>3].Base_23_16<<16)|
+ (pGdt[OriginalSegment>>3].Base_31_24<<24);
+ result+=Offset;
+ }
+ DPRINT((0,"GetLinearAddress(%.4X:%.8X)=%.8X\n",OriginalSegment,Offset,result));
+
+ LEAVE_FUNC();
+
+ return result;
+}
+
+//*************************************************************************
+// ShowRunningMsg()
+//
+// place RUNNING message
+//*************************************************************************
+void ShowRunningMsg(void)
+{
+ ENTER_FUNC();
+
+ SetForegroundColor(COLOR_TEXT);
+ SetBackgroundColor(COLOR_CAPTION);
+ ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
+ PutChar(" Reactos is running... (Press CTRL-D to stop) ",1,wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
+ ResetColor();
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// ShowStoppedMsg()
+//
+// place STOPPED message
+//*************************************************************************
+void ShowStoppedMsg(void)
+{
+ ENTER_FUNC();
+
+ SetForegroundColor(COLOR_TEXT);
+ SetBackgroundColor(COLOR_CAPTION);
+ ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
+ PutChar(" Stopped... (Type 'x' to continue) ",1,wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
+ ResetColor();
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// SetHardwareBreakPoint()
+//
+//*************************************************************************
+void SetHardwareBreakPoint(ULONG ulAddress,ULONG ulReg)
+{
+ ULONG mask = 0x300;
+ ULONG enable_mask = 0x3;
+
+ DPRINT((0,"SetHardwareBreakPoint(%x,DR%x)\n",ulAddress,ulReg));
+
+ enable_mask <<= (ulReg*2);
+ mask |= enable_mask;
+
+ DPRINT((0,"mask = %x\n",mask));
+
+ __asm__ __volatile__
+ ("\n\t \
+ xorl %%eax,%%eax\n\t \
+ mov %%eax,%%dr6\n\t \
+ mov %%dr7,%%eax\n\t \
+ orl %0,%%eax\n\t \
+ mov %%eax,%%dr7\n\t \
+ "
+ :
+ :"m" (mask)
+ :"eax");
+
+ switch(ulReg)
+ {
+ case 0:
+ __asm__ __volatile__
+ ("\n\t \
+ mov %0,%%eax\n\t \
+ mov %%eax,%%dr0\n\t \
+ "
+ :
+ :"m" (ulAddress)
+ :"eax");
+ break;
+ case 1:
+ __asm__ __volatile__
+ ("\n\t \
+ mov %0,%%eax\n\t \
+ mov %%eax,%%dr1\n\t \
+ "
+ :
+ :"m" (ulAddress)
+ :"eax");
+ break;
+ case 2:
+ __asm__ __volatile__
+ ("\n\t \
+ mov %0,%%eax\n\t \
+ mov %%eax,%%dr2\n\t \
+ "
+ :
+ :"m" (ulAddress)
+ :"eax");
+ break;
+ case 3:
+ __asm__ __volatile__
+ ("\n\t \
+ mov %0,%%eax\n\t \
+ mov %%eax,%%dr3\n\t \
+ "
+ :
+ :"m" (ulAddress)
+ :"eax");
+ break;
+ }
+}
+
+//*************************************************************************
+// SetHardwareBreakPoints()
+//
+// install HW breakpoints
+//*************************************************************************
+void SetHardwareBreakPoints(void)
+{
+ULONG i;
+ULONG mask;
+ULONG LinAddr0,LinAddr1,LinAddr2,LinAddr3;
+PULONG LinAddr[4]={&LinAddr0,&LinAddr1,&LinAddr2,&LinAddr3};
+
+ ENTER_FUNC();
+
+ // cancel all debug activity
+ __asm__("\n\t \
+ pushl %eax\n\t \
+ xorl %eax,%eax\n\t \
+ mov %eax,%dr6\n\t \
+ mov %eax,%dr7\n\t \
+ popl %eax");
+ // build DR7 mask
+ for(mask=0,i=0;i<4;i++)
+ {
+ mask<<=2;
+ if(Bp[i].Active && Bp[i].Used && !Bp[i].Virtual)
+ {
+ mask|=0x03;
+ *LinAddr[3-i]=Bp[i].LinearAddress;
+ DPRINT((0,"breakpoint %u at %.8X\n",i,Bp[i].LinearAddress));
+ }
+ }
+ if(mask)
+ {
+ __asm__("\n\t \
+ pushl %%eax\n\t \
+ movl %0,%%eax\n\t \
+ andl $0x000000FF,%%eax\n\t \
+ orl $0x300,%%eax\n\t \
+ mov %%eax,%%dr7\n\t \
+ mov %1,%%eax\n\t \
+ mov %%eax,%%dr0\n\t \
+ mov %2,%%eax\n\t \
+ mov %%eax,%%dr1\n\t \
+ mov %3,%%eax\n\t \
+ mov %%eax,%%dr2\n\t \
+ mov %4,%%eax\n\t \
+ mov %%eax,%%dr3\n\t \
+ popl %%eax"
+ :
+ :"m" (mask),"m" (LinAddr0),"m" (LinAddr1),"m" (LinAddr2),"m" (LinAddr3));
+ }
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// IsCallInstrAtEIP()
+//
+// check if instruction at CS:EIP changes program flow
+//*************************************************************************
+BOOLEAN IsCallInstrAtEIP(void)
+{
+PUCHAR linear;
+BOOLEAN result=FALSE;
+
+ ENTER_FUNC();
+ DPRINT((0,"IsCallInstrAtEIP()\n"));
+
+ linear=(PUCHAR)GetLinearAddress(CurrentCS,CurrentEIP);
+ if(IsRangeValid((ULONG)linear,2))
+ {
+ if(*linear== 0xE8 || // call
+ (*linear== 0xFF && ( ((*(linear+1)>>3)&0x7)==0x2 || ((*(linear+1)>>3)&0x7)==0x3) ) || // call
+ *linear== 0x9A || // call
+ *linear== 0xF2 || // REP
+ *linear== 0xF3) // REP
+ result=TRUE;
+ }
+
+ LEAVE_FUNC();
+
+ return result;
+}
+
+
+//*************************************************************************
+// IsRetAtEIP()
+//
+// check if instruction at CS:EIP is a return instruction
+//*************************************************************************
+BOOLEAN IsRetAtEIP(void)
+{
+ PUCHAR linear;
+ BOOLEAN bResult = FALSE;
+
+ ENTER_FUNC();
+ DPRINT((0,"IsRetAtEIP()\n"));
+
+ linear=(PUCHAR)GetLinearAddress(CurrentCS,CurrentEIP);
+
+ switch(*linear)
+ {
+ case 0xc2:
+ case 0xc3:
+ case 0xca:
+ case 0xcb:
+ case 0xcf: // IRET/IRETD
+ bResult = TRUE;
+ break;
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+//*************************************************************************
+// VisualizeFlags()
+//
+// display CPU EFLAGS as string
+//*************************************************************************
+LPSTR VisualizeFlags(ULONG EFlags)
+{
+ static UCHAR FlagNames[]={'c',0,'p',0,'a',0,'z','s','t','i','d','o'};
+ ULONG i,j;
+ static char temp[32];
+
+ for(j=0,i=0;i<sizeof(FlagNames);i++)
+ {
+ if(FlagNames[i]!=0)
+ {
+ if(EFlags&1)
+ temp[j++] = PICE_toupper(FlagNames[i]);
+ else
+ temp[j++] = FlagNames[i];
+ temp[j++]=' ';
+ }
+ EFlags>>=1;
+ }
+ temp[j]=0;
+ PICE_strrev(temp);
+ return temp;
+}
+
+//*************************************************************************
+// DisplayRegs()
+//
+// display CPU registers
+//*************************************************************************
+void DisplayRegs(void)
+{
+ char tempDisplayRegs[48];
+
+ ENTER_FUNC();
+
+// Clear(REGISTER_WINDOW);
+ Home(REGISTER_WINDOW);
+ // EAX
+ Print(REGISTER_WINDOW,"EAX=");
+ PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEAX);
+ if(OldEAX!=CurrentEAX)
+ {
+ SetForegroundColor(WHITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldEAX!=CurrentEAX)
+ {
+ ResetColor();
+ }
+
+ // EBX
+ Print(REGISTER_WINDOW," EBX=");
+ PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEBX);
+ if(OldEBX!=CurrentEBX)
+ {
+ SetForegroundColor(WHITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldEBX!=CurrentEBX)
+ {
+ ResetColor();
+ }
+
+ // ECX
+ Print(REGISTER_WINDOW," ECX=");
+ PICE_sprintf(tempDisplayRegs,"%.8X",CurrentECX);
+ if(OldECX!=CurrentECX)
+ {
+ SetForegroundColor(WHITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldECX!=CurrentECX)
+ {
+ ResetColor();
+ }
+
+ // EDX
+ Print(REGISTER_WINDOW," EDX=");
+ PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEDX);
+ if(OldEDX!=CurrentEDX)
+ {
+ SetForegroundColor(COLOR_HILITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldEDX!=CurrentEDX)
+ {
+ ResetColor();
+ }
+
+ // ESI
+ Print(REGISTER_WINDOW," ESI=");
+ PICE_sprintf(tempDisplayRegs,"%.8X",CurrentESI);
+ if(OldESI!=CurrentESI)
+ {
+ SetForegroundColor(COLOR_HILITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldESI!=CurrentESI)
+ {
+ ResetColor();
+ }
+
+ // EDI
+ Print(REGISTER_WINDOW," EDI=");
+ PICE_sprintf(tempDisplayRegs,"%.8X\n",CurrentEDI);
+ if(OldEDI!=CurrentEDI)
+ {
+ SetForegroundColor(COLOR_HILITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldEDI!=CurrentEDI)
+ {
+ ResetColor();
+ }
+
+ // EBP
+ Print(REGISTER_WINDOW,"EBP=");
+ PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEBP);
+ if(OldEBP!=CurrentEBP)
+ {
+ SetForegroundColor(COLOR_HILITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldEBP!=CurrentEBP)
+ {
+ ResetColor();
+ }
+
+ // ESP
+ Print(REGISTER_WINDOW," ESP=");
+ PICE_sprintf(tempDisplayRegs,"%.8X",CurrentESP);
+ if(OldESP!=CurrentESP)
+ {
+ SetForegroundColor(COLOR_HILITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldESP!=CurrentESP)
+ {
+ ResetColor();
+ }
+
+ // EIP
+ Print(REGISTER_WINDOW," EIP=");
+ PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEIP);
+ if(OldEIP!=CurrentEIP)
+ {
+ SetForegroundColor(COLOR_HILITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldEIP!=CurrentEIP)
+ {
+ ResetColor();
+ }
+
+ // EFL
+ Print(REGISTER_WINDOW," EFLAGS=");
+ PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEFL);
+ if(OldEFL!=CurrentEFL)
+ {
+ SetForegroundColor(COLOR_HILITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldEFL!=CurrentEFL)
+ {
+ ResetColor();
+ }
+
+ // visual flags
+ PICE_sprintf(tempDisplayRegs," %s\n",VisualizeFlags(CurrentEFL));
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+
+ // CS
+ Print(REGISTER_WINDOW,"CS=");
+ PICE_sprintf(tempDisplayRegs,"%.4X",CurrentCS);
+ if(OldCS!=CurrentCS)
+ {
+ SetForegroundColor(COLOR_HILITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldCS!=CurrentCS)
+ {
+ ResetColor();
+ }
+
+ // DS
+ Print(REGISTER_WINDOW," DS=");
+ PICE_sprintf(tempDisplayRegs,"%.4X",CurrentDS);
+ if(OldDS!=CurrentDS)
+ {
+ SetForegroundColor(COLOR_HILITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldDS!=CurrentDS)
+ {
+ ResetColor();
+ }
+
+ // ES
+ Print(REGISTER_WINDOW," ES=");
+ PICE_sprintf(tempDisplayRegs,"%.4X",CurrentES);
+ if(OldES!=CurrentES)
+ {
+ SetForegroundColor(COLOR_HILITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldES!=CurrentES)
+ {
+ ResetColor();
+ }
+
+ // FS
+ Print(REGISTER_WINDOW," FS=");
+ PICE_sprintf(tempDisplayRegs,"%.4X",CurrentFS);
+ if(OldFS!=CurrentFS)
+ {
+ SetForegroundColor(COLOR_HILITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldFS!=CurrentFS)
+ {
+ ResetColor();
+ }
+
+ // GS
+ Print(REGISTER_WINDOW," GS=");
+ PICE_sprintf(tempDisplayRegs,"%.4X",CurrentGS);
+ if(OldGS!=CurrentGS)
+ {
+ ResetColor();
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldGS!=CurrentGS)
+ {
+ ResetColor();
+ }
+
+ // SS
+ Print(REGISTER_WINDOW," SS=");
+ PICE_sprintf(tempDisplayRegs,"%.4X",CurrentSS);
+ if(OldSS!=CurrentSS)
+ {
+ SetForegroundColor(COLOR_HILITE);
+ }
+ Print(REGISTER_WINDOW,tempDisplayRegs);
+ if(OldSS!=CurrentSS)
+ {
+ ResetColor();
+ }
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// SaveOldRegs()
+//
+//*************************************************************************
+void SaveOldRegs(void)
+{
+
+ ENTER_FUNC();
+
+ OldEAX=CurrentEAX;
+ OldEBX=CurrentEBX;
+ OldECX=CurrentECX;
+ OldEDX=CurrentEDX;
+ OldESI=CurrentESI;
+ OldEDI=CurrentEDI;
+ OldEBP=CurrentEBP;
+ OldESP=CurrentESP;
+ OldEIP=CurrentEIP;
+ OldEFL=CurrentEFL;
+ OldCS=CurrentCS;
+ OldDS=CurrentDS;
+ OldES=CurrentES;
+ OldFS=CurrentFS;
+ OldGS=CurrentGS;
+ OldSS=CurrentSS;
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// GetKeyStatus()
+//
+//*************************************************************************
+UCHAR GetKeyStatus(void)
+{
+ UCHAR ucRet;
+ ucRet = inb_p((PUCHAR)(I8042_PHYSICAL_BASE + I8042_STATUS_REGISTER_OFFSET));
+ return ucRet;
+}
+
+//*************************************************************************
+// GetKeyData()
+//
+//*************************************************************************
+UCHAR GetKeyData(void)
+{
+ UCHAR ucRet;
+ ucRet = inb_p((PUCHAR)(I8042_PHYSICAL_BASE + I8042_DATA_REGISTER_OFFSET));
+ return ucRet;
+}
+
+//*************************************************************************
+// GetKeyPolled
+//
+//*************************************************************************
+UCHAR KeyboardGetKeyPolled(void)
+{
+ UCHAR ucKey;
+ UCHAR ucStatus;
+ static BOOLEAN bExtended = FALSE;
+
+ while(ucKey=0,(ucStatus=GetKeyStatus())&OUTPUT_BUFFER_FULL)
+ {
+ ucKey = 0;
+ ucKey = GetKeyData();
+
+ if(ucStatus&MOUSE_OUTPUT_BUFFER_FULL)
+ continue;
+
+ DPRINT((1,"GetKeyPolled(): key = %x bExtended=%s\n",ucKey,bExtended?"TRUE":"FALSE"));
+
+ if(SCANCODE_EXTENDED == ucKey)
+ {
+ DPRINT((1,"extended switched ON\n"));
+ bExtended = TRUE;
+ continue;
+ }
+ else
+ {
+ if(!(ucKey&0x80)) // keypress
+ {
+ switch(ucKey&0x7f)
+ {
+ case SCANCODE_L_CTRL:
+ case SCANCODE_R_CTRL:
+ if(!bExtended)
+ bControl=TRUE;
+ break;
+ case SCANCODE_L_SHIFT:
+ case SCANCODE_R_SHIFT:
+ if(!bExtended)
+ bShift=TRUE;
+ break;
+ case SCANCODE_L_ALT:
+ case SCANCODE_R_ALT:
+ if(!bExtended)
+ bAlt=TRUE;
+ break;
+ default:
+ DPRINT((0,"GetKeyPolled(): control = %u shift = %u alt = %u\n",bControl,bShift,bAlt));
+ return ucKey;
+ }
+ }
+ else
+ {
+ switch(ucKey&0x7f)
+ {
+ case SCANCODE_L_CTRL:
+ case SCANCODE_R_CTRL:
+ if(!bExtended)
+ bControl=FALSE;
+ break;
+ case SCANCODE_L_SHIFT:
+ case SCANCODE_R_SHIFT:
+ if(!bExtended)
+ bShift=FALSE;
+ break;
+ case SCANCODE_L_ALT:
+ case SCANCODE_R_ALT:
+ if(!bExtended)
+ bAlt=FALSE;
+ break;
+ }
+ }
+ }
+ bExtended=FALSE;
+ }
+
+ return ucKey;
+}
+
+//*************************************************************************
+// KeyboardFlushKeyboardQueue()
+//
+//*************************************************************************
+void KeyboardFlushKeyboardQueue(void)
+{
+ //__udelay(10);
+ KeStallExecutionProcessor(10);
+ while(GetKeyStatus()&OUTPUT_BUFFER_FULL)
+ {
+ GetKeyData();
+ //__udelay(10);
+ KeStallExecutionProcessor(10);
+ }
+}
+
+//*************************************************************************
+// CheckLoadAbort()
+//
+//*************************************************************************
+BOOLEAN CheckLoadAbort(void)
+{
+ULONG i;
+UCHAR ucKey;
+
+ MaskIrqs();
+
+ SaveGraphicsState();
+
+ FlushKeyboardQueue();
+
+ PrintLogo(TRUE);
+
+ for(i=0;i<5000;i++)
+ {
+ if(!(i%1000) )
+ {
+ PICE_sprintf(tempUtil,"\n LOAD WILL CONTINUE IN %u SEC (HIT 'C' TO CONTINUE OR ANY OTHER KEY TO ABORT)\n",5-i/1000);
+ Clear(REGISTER_WINDOW);
+ Print(REGISTER_WINDOW,tempUtil);
+ PrintLogo(TRUE);
+ }
+
+ ucKey = GetKeyPolled();
+
+ if(ucKey)
+ {
+ if((ucKey&0x7f)!=46)
+ {
+ RestoreGraphicsState();
+ UnmaskIrqs();
+ return FALSE;
+ }
+ else
+ goto load;
+ }
+ KeStallExecutionProcessor(1000);
+ }
+load:
+ Clear(REGISTER_WINDOW);
+ PrintLogo(TRUE);
+
+ tempUtil[0] = 0;
+ FlushKeyboardQueue();
+
+ RestoreGraphicsState();
+
+ UnmaskIrqs();
+
+ return TRUE;
+}
+
+
+
+
+//*************************************************************************
+// IntelStackWalk()
+//
+//*************************************************************************
+void IntelStackWalk(ULONG pc,ULONG ebp,ULONG esp)
+{
+ PULONG pFrame, pPrevFrame;
+ LPSTR pSymbolName;
+
+ DPRINT((0,"IntelStackWalk(): pc = %X ebp = %X esp = %X\n",pc,ebp,esp));
+
+ pFrame = pPrevFrame = (PULONG)ebp;
+
+ PutStatusText("EIP FRAME NAME\n");
+ while(1)
+ {
+ DPRINT((0,"IntelStackWalk(): pFrame = %X pPrevFrame = %X pc =%X\n",(ULONG)pFrame,(ULONG)pPrevFrame,pc));
+ if ( ( (ULONG)pFrame & 3 ) ||
+ ( (pFrame <= pPrevFrame) ) )
+ {
+ DPRINT((0,"IntelStackWalk(): pFrame is either unaligned or not less than previous\n"));
+ if( !IsRangeValid((ULONG)pFrame, sizeof(PVOID)*2) )
+ {
+ DPRINT((0,"IntelStackWalk(): pFrame not valid pointer!\n"));
+ break;
+ }
+ }
+
+ if((pSymbolName = FindFunctionByAddress(pc,NULL,NULL)) )
+ PICE_sprintf(tempUtil,"%08X %08X %s\n",pc, (ULONG)pFrame,pSymbolName);
+ else
+ PICE_sprintf(tempUtil,"%08X %08X\n",pc, (ULONG)pFrame);
+ Print(OUTPUT_WINDOW,tempUtil);
+ if(WaitForKey()==FALSE)break;
+
+ pc = pFrame[1];
+
+ pPrevFrame = pFrame;
+
+ pFrame = (PULONG)pFrame[0]; // proceed to next higher frame on stack
+ }
+}
+
+//*************************************************************************
+// FindPteForLinearAddress()
+//
+//*************************************************************************
+PULONG FindPteForLinearAddress(ULONG address)
+{
+ PULONG pPGD;
+ PULONG pPTE;
+ BOOLEAN bResult = FALSE;
+ PEPROCESS my_current = IoGetCurrentProcess();
+
+ ENTER_FUNC();
+
+ address &= (~(_PAGE_SIZE-1));
+
+ if(my_current)
+ {
+ pPGD = ADDR_TO_PDE(address);
+ if(pPGD && ((*pPGD)&_PAGE_PRESENT))
+ {
+ // not large page
+ if(!((*pPGD)&_PAGE_4M))
+ {
+ pPTE = ADDR_TO_PTE(address);
+ if(pPTE)
+ {
+ LEAVE_FUNC();
+ return pPTE;
+ }
+ }
+ // large page
+ else
+ {
+ LEAVE_FUNC();
+ return NULL;
+ }
+ }
+ }
+
+ LEAVE_FUNC();
+ return NULL;
+}
+
+//*************************************************************************
+// InvalidateLB()
+//
+//*************************************************************************
+void InvalidateLB(void)
+{
+ ENTER_FUNC();
+ __asm__ __volatile__
+ (
+ "wbinvd\n\t \
+ mov %%cr3,%%ecx\n\t \
+ mov %%ecx,%%cr3"
+ :::"ecx"
+ );
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// ReadPhysMem()
+//
+//*************************************************************************
+ULONG ReadPhysMem(ULONG Address,ULONG ulSize)
+{
+ ULONG Page = ((ULONG)TwoPagesForPhysMem+_PAGE_SIZE)&~(_PAGE_SIZE-1);
+ PULONG pPTE;
+ ULONG temp = 0;
+ ULONG oldPTE;
+
+ ENTER_FUNC();
+ DPRINT((0,"ReadPhysMem(%.8X,%u)\n",Address,ulSize));
+ DPRINT((0,"ReadPhysMem(): Page = %.8X\n",Page));
+ pPTE = (PULONG)FindPteForLinearAddress(Page);
+ DPRINT((0,"ReadPhysMem(): pPTE = %.8X\n",pPTE));
+ if(pPTE)
+ {
+ oldPTE = *pPTE;
+ DPRINT((0,"ReadPhysMem(): oldPTE = %.8X\n",oldPTE));
+ temp = (Address & ~(_PAGE_SIZE-1));
+ DPRINT((0,"ReadPhysMem(): page-aligned Address = %.8X\n",temp));
+ *pPTE = temp|0x1;
+ DPRINT((0,"ReadPhysMem(): new PTE = %.8X\n",*pPTE));
+ InvalidateLB();
+ switch(ulSize)
+ {
+ case sizeof(UCHAR): // BYTE
+ temp = *(PUCHAR)(Page + (Address & (_PAGE_SIZE-1)));
+ temp = (UCHAR)temp;
+ break;
+ case sizeof(USHORT): // WORD
+ temp = *(PUSHORT)(Page + (Address & (_PAGE_SIZE-1)));
+ temp = (USHORT)temp;
+ break;
+ case sizeof(ULONG): // DWORD
+ temp = *(PULONG)(Page + (Address & (_PAGE_SIZE-1)));
+ break;
+ }
+ *pPTE = oldPTE;
+ InvalidateLB();
+ }
+ LEAVE_FUNC();
+
+ return temp;
+}
+
+//*************************************************************************
+// WritePhysMem()
+//
+//*************************************************************************
+void WritePhysMem(ULONG Address,ULONG Datum,ULONG ulSize)
+{
+ ULONG Page = ((ULONG)TwoPagesForPhysMem+_PAGE_SIZE)&~(_PAGE_SIZE-1);
+ PULONG pPTE;
+ ULONG temp;
+ ULONG oldPTE;
+
+ pPTE = (PULONG)FindPteForLinearAddress(Page);
+ if(pPTE)
+ {
+ oldPTE = *pPTE;
+ temp = (Address & ~(_PAGE_SIZE-1));
+ *pPTE = temp | 0x3; // present and writable
+ InvalidateLB();
+ switch(ulSize)
+ {
+ case sizeof(UCHAR): // BYTE
+ *(PUCHAR)(Page + (Address & (_PAGE_SIZE-1))) = (UCHAR)Datum;
+ break;
+ case sizeof(USHORT): // WORD
+ *(PUSHORT)(Page + (Address & (_PAGE_SIZE-1))) = (USHORT)Datum;
+ break;
+ case sizeof(ULONG): // DWORD
+ *(PULONG)(Page + (Address & (_PAGE_SIZE-1))) = Datum;
+ break;
+ }
+ *pPTE = oldPTE;
+ InvalidateLB();
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
+{
+ unsigned long result = 0,value;
+
+ if (!base) {
+ base = 10;
+ if (*cp == '0') {
+ base = 8;
+ cp++;
+ if ((*cp == 'x') && PICE_isxdigit(cp[1])) {
+ cp++;
+ base = 16;
+ }
+ }
+ }
+ while (PICE_isxdigit(*cp) && (value = PICE_isdigit(*cp) ? *cp-'0' : (PICE_islower(*cp)
+ ? PICE_toupper(*cp) : *cp)-'A'+10) < base) {
+ result = result*base + value;
+ cp++;
+ }
+ if (endp)
+ *endp = (char *)cp;
+ return result;
+}
+
+long simple_strtol(const char *cp,char **endp,unsigned int base)
+{
+ if(*cp=='-')
+ return -simple_strtoul(cp+1,endp,base);
+ return simple_strtoul(cp,endp,base);
+}
+
+/* we use this so that we can do without the ctype library */
+#define is_digit(c) ((c) >= '0' && (c) <= '9')
+
+static int skip_atoi(const char **s)
+{
+ int i=0;
+
+ while (is_digit(**s))
+ i = i*10 + *((*s)++) - '0';
+ return i;
+}
+
+size_t PICE_strnlen(const char * s, size_t count)
+{
+ const char *sc;
+
+ for (sc = s; count-- && IsAddressValid((ULONG)sc) && *sc != '\0'; ++sc)
+ /* nothing */;
+ return sc - s;
+}
+
+
+#define NUM_ZEROPAD 1 /* pad with zero */
+#define NUM_SIGN 2 /* unsigned/signed long */
+#define NUM_PLUS 4 /* show plus */
+#define NUM_SPACE 8 /* space if plus */
+#define NUM_LEFT 16 /* left justified */
+#define NUM_SPECIAL 32 /* 0x */
+#define NUM_LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
+
+#define do_div(n,base) ({ \
+int __res; \
+__res = ((unsigned long) n) % (unsigned) base; \
+n = ((unsigned long) n) / (unsigned) base; \
+__res; })
+
+static char * PICE_number(char * str, long num, int base, int size, int precision
+ ,int type)
+{
+ char c,sign,tmp[66];
+ const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
+ int i;
+
+ if (type & NUM_LARGE)
+ digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ if (type & NUM_LEFT)
+ type &= ~NUM_ZEROPAD;
+ if (base < 2 || base > 36)
+ return 0;
+ c = (type & NUM_ZEROPAD) ? '0' : ' ';
+ sign = 0;
+ if (type & NUM_SIGN) {
+ if (num < 0) {
+ sign = '-';
+ num = -num;
+ size--;
+ } else if (type & NUM_PLUS) {
+ sign = '+';
+ size--;
+ } else if (type & NUM_SPACE) {
+ sign = ' ';
+ size--;
+ }
+ }
+ if (type & NUM_SPECIAL) {
+ if (base == 16)
+ size -= 2;
+ else if (base == 8)
+ size--;
+ }
+ i = 0;
+ if (num == 0)
+ tmp[i++]='0';
+ else while (num != 0)
+ tmp[i++] = digits[do_div(num,base)];
+ if (i > precision)
+ precision = i;
+ size -= precision;
+ if (!(type&(NUM_ZEROPAD+NUM_LEFT)))
+ while(size-->0)
+ *str++ = ' ';
+ if (sign)
+ *str++ = sign;
+ if (type & NUM_SPECIAL) {
+ if (base==8)
+ *str++ = '0';
+ else if (base==16) {
+ *str++ = '0';
+ *str++ = digits[33];
+ }
+ }
+ if (!(type & NUM_LEFT))
+ while (size-- > 0)
+ *str++ = c;
+ while (i < precision--)
+ *str++ = '0';
+ while (i-- > 0)
+ *str++ = tmp[i];
+ while (size-- > 0)
+ *str++ = ' ';
+ return str;
+}
+
+/* Forward decl. needed for IP address printing stuff... */
+int PICE_sprintf(char * buf, const char *fmt, ...);
+
+int PICE_vsprintf(char *buf, const char *fmt, va_list args)
+{
+ int len;
+ unsigned long num;
+ int i, base;
+ char * str;
+ const char *s;
+ const wchar_t *sw;
+
+ int flags; /* flags to PICE_number() */
+
+ int field_width; /* width of output field */
+ int precision; /* min. # of digits for integers; max
+ PICE_number of chars for from string */
+ int qualifier; /* 'h', 'l', or 'L' for integer fields */
+
+ for (str=buf ; *fmt ; ++fmt) {
+ if (*fmt != '%') {
+ *str++ = *fmt;
+ continue;
+ }
+
+ /* process flags */
+ flags = 0;
+ repeat:
+ ++fmt; /* this also skips first '%' */
+ switch (*fmt) {
+ case '-': flags |= NUM_LEFT; goto repeat;
+ case '+': flags |= NUM_PLUS; goto repeat;
+ case ' ': flags |= NUM_SPACE; goto repeat;
+ case '#': flags |= NUM_SPECIAL; goto repeat;
+ case '0': flags |= NUM_ZEROPAD; goto repeat;
+ }
+
+ /* get field width */
+ field_width = -1;
+ if (is_digit(*fmt))
+ field_width = skip_atoi(&fmt);
+ else if (*fmt == '*') {
+ ++fmt;
+ /* it's the next argument */
+ field_width = va_arg(args, int);
+ if (field_width < 0) {
+ field_width = -field_width;
+ flags |= NUM_LEFT;
+ }
+ }
+
+ /* get the precision */
+ precision = -1;
+ if (*fmt == '.') {
+ ++fmt;
+ if (is_digit(*fmt))
+ precision = skip_atoi(&fmt);
+ else if (*fmt == '*') {
+ ++fmt;
+ /* it's the next argument */
+ precision = va_arg(args, int);
+ }
+ if (precision < 0)
+ precision = 0;
+ }
+
+ /* get the conversion qualifier */
+ qualifier = -1;
+ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
+ qualifier = *fmt;
+ ++fmt;
+ }
+
+ /* default base */
+ base = 10;
+
+ switch (*fmt) {
+ case 'c':
+ if (!(flags & NUM_LEFT))
+ while (--field_width > 0)
+ *str++ = ' ';
+ *str++ = (unsigned char) va_arg(args, int);
+ while (--field_width > 0)
+ *str++ = ' ';
+ continue;
+
+ case 's':
+ s = va_arg(args, char *);
+ if (!s)
+ s = "<NULL>";
+
+ len = PICE_strnlen(s, precision);
+
+ if (!(flags & NUM_LEFT))
+ while (len < field_width--)
+ *str++ = ' ';
+ for (i = 0; i < len; ++i)
+ *str++ = *s++;
+ while (len < field_width--)
+ *str++ = ' ';
+ continue;
+
+ case 'S':
+ if (qualifier == 'h') {
+ /* print ascii string */
+ s = va_arg(args, char *);
+ if (s == NULL)
+ s = "<NULL>";
+
+ len = PICE_strlen (s);
+ if ((unsigned int)len > (unsigned int)precision)
+ len = precision;
+
+ if (!(flags & NUM_LEFT))
+ while (len < field_width--)
+ *str++ = ' ';
+ for (i = 0; i < len; ++i)
+ *str++ = *s++;
+ while (len < field_width--)
+ *str++ = ' ';
+ } else {
+ /* print unicode string */
+ sw = va_arg(args, wchar_t *);
+ if (sw == NULL)
+ sw = L"<NULL>";
+
+ len = wcslen (sw);
+ if ((unsigned int)len > (unsigned int)precision)
+ len = precision;
+
+ if (!(flags & NUM_LEFT))
+ while (len < field_width--)
+ *str++ = ' ';
+ for (i = 0; i < len; ++i)
+ *str++ = (unsigned char)(*sw++);
+ while (len < field_width--)
+ *str++ = ' ';
+ }
+ continue;
+
+ case 'p':
+ if (field_width == -1) {
+ field_width = 2*sizeof(void *);
+ flags |= NUM_ZEROPAD;
+ }
+ str = PICE_number(str,
+ (unsigned long) va_arg(args, void *), 16,
+ field_width, precision, flags);
+ continue;
+
+
+ case 'n':
+ if (qualifier == 'l') {
+ long * ip = va_arg(args, long *);
+ *ip = (str - buf);
+ } else {
+ int * ip = va_arg(args, int *);
+ *ip = (str - buf);
+ }
+ continue;
+
+ case '%':
+ *str++ = '%';
+ continue;
+
+ /* integer PICE_number formats - set up the flags and "break" */
+ case 'o':
+ base = 8;
+ break;
+
+ case 'X':
+ flags |= NUM_LARGE;
+ case 'x':
+ base = 16;
+ break;
+
+ case 'd':
+ case 'i':
+ flags |= NUM_SIGN;
+ case 'u':
+ break;
+
+ default:
+ *str++ = '%';
+ if (*fmt)
+ *str++ = *fmt;
+ else
+ --fmt;
+ continue;
+ }
+ if (qualifier == 'l')
+ num = va_arg(args, unsigned long);
+ else if (qualifier == 'h') {
+ num = (unsigned short) va_arg(args, int);
+ if (flags & NUM_SIGN)
+ num = (short) num;
+ } else if (flags & NUM_SIGN)
+ num = va_arg(args, int);
+ else
+ num = va_arg(args, unsigned int);
+ str = PICE_number(str, num, base, field_width, precision, flags);
+ }
+ *str = '\0';
+ return str-buf;
+}
+
+int PICE_sprintf(char * buf, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i = PICE_vsprintf(buf,fmt,args);
+ va_end(args);
+ return i;
+}
+
+//*************************************************************************
+// AsciiFromScan()
+//
+// Convert Scancode to ASCII
+//*************************************************************************
+UCHAR AsciiFromScan(UCHAR s)
+{
+ PSCANTOASCII table;
+ ULONG i;
+
+ ENTER_FUNC();
+
+ if (bShift)
+ {
+ table = GetKeyboardLayout()->shifted;
+ }
+ else if(bAlt)
+ {
+ table = GetKeyboardLayout()->alted;
+ }
+ else
+ {
+ table = GetKeyboardLayout()->normal;
+ }
+
+
+ if (table)
+ {
+ for(i=0;table[i].s != 0;i++)
+ {
+ if(table[i].s==s)
+ {
+ LEAVE_FUNC();
+ return table[i].a;
+ }
+ }
+ }
+
+ DPRINT((0,"AsciiFromScan(): no translation for key\n"));
+ LEAVE_FUNC();
+ return 0;
+}
+
+
+//*************************************************************************
+// AsciiToScan()
+//
+// Convert Scancode to ASCII
+//*************************************************************************
+UCHAR AsciiToScan(UCHAR s)
+{
+ PSCANTOASCII table;
+ ULONG i;
+
+ ENTER_FUNC();
+
+ if (bShift)
+ {
+ table = GetKeyboardLayout()->shifted;
+ }
+ else if(bAlt)
+ {
+ table = GetKeyboardLayout()->alted;
+ }
+ else
+ {
+ table = GetKeyboardLayout()->normal;
+ }
+
+ if (table)
+ {
+ for(i=0;table[i].s != 0;i++)
+ {
+ if(table[i].a==s)
+ {
+ LEAVE_FUNC();
+ return table[i].s;
+ }
+ }
+ }
+
+ DPRINT((0,"AsciiToScan(): no translation for ASCII code\n"));
+ LEAVE_FUNC();
+ return 0;
+}
+
+//************************************************************************
+// outportb()
+//
+//************************************************************************
+void outportb(PUCHAR port,UCHAR data)
+{
+ WRITE_PORT_UCHAR((PUCHAR)port, data);
+}
+
+void outb_p(UCHAR data, PUCHAR port)
+{
+ WRITE_PORT_UCHAR((PUCHAR)port, data);
+}
+
+VOID outl(ULONG data, PULONG port)
+{
+ WRITE_PORT_ULONG(port, data);
+}
+
+
+//************************************************************************
+// inportb()
+//
+//************************************************************************
+UCHAR inportb(PUCHAR port)
+{
+ return READ_PORT_UCHAR((PUCHAR)port);
+}
+
+UCHAR inb_p(PUCHAR port)
+{
+ return READ_PORT_UCHAR((PUCHAR)port);
+}
+
+ULONG inl(PULONG port)
+{
+ return READ_PORT_ULONG(port);
+}
+
+//*************************************************************************
+// EnablePassThrough()
+//
+// enable MDA passthrough on AGP chipset
+//*************************************************************************
+void EnablePassThrough(void)
+{
+ ULONG oldCF8,flags;
+
+ save_flags(flags);
+ cli();
+
+ oldCF8 = inl((PULONG)0xcf8);
+ outl(0x80000050,(PULONG)0xcf8);
+ outl(inl((PULONG)0xcfc)|0x00000020,(PULONG)0xcfc);
+ outl(oldCF8,(PULONG)0xcf8);
+
+ restore_flags(flags);
+}
+
+//***********************************************************************************
+// Pice_malloc - allocate memory from paged or non-paged pool
+//***********************************************************************************
+void * PICE_malloc( size_t numBytes, BOOLEAN fromPaged )
+{
+ void* res = ExAllocatePool( (fromPaged)?PagedPool:NonPagedPool, numBytes );
+ ASSERT(res);
+ return res;
+}
+
+//***********************************************************************************
+// PICE_free - free memory allocated by PICE_malloc
+//***********************************************************************************
+void PICE_free( void* p )
+{
+ ASSERT( p );
+ ExFreePool( p );
+}
+
+long PICE_read(HANDLE hFile, LPVOID lpBuffer, long lBytes)
+{
+ DWORD NumberOfBytesRead;
+ IO_STATUS_BLOCK iosb;
+
+ ASSERT( lpBuffer );
+
+ if (!NT_SUCCESS(NtReadFile(
+ (HANDLE) hFile,
+ NULL, NULL, NULL, &iosb,
+ (LPVOID) lpBuffer,
+ (DWORD) lBytes,
+ NULL,
+ NULL
+ )))
+ {
+ return -1;
+ }
+ NumberOfBytesRead = iosb.Information;
+ return NumberOfBytesRead;
+}
+
+HANDLE PICE_open (LPCWSTR lpPathName, int iReadWrite)
+{
+ DWORD dwAccessMask = 0;
+ DWORD dwShareMode = 0;
+ UNICODE_STRING TmpFileName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK StatusBlock;
+ HANDLE hfile;
+ NTSTATUS status;
+
+
+ DPRINT((0,"PICE_open: %S\n", lpPathName));
+
+ if ( (iReadWrite & OF_READWRITE ) == OF_READWRITE )
+ dwAccessMask = GENERIC_READ | GENERIC_WRITE;
+ else if ( (iReadWrite & OF_READ ) == OF_READ )
+ dwAccessMask = GENERIC_READ;
+ else if ( (iReadWrite & OF_WRITE ) == OF_WRITE )
+ dwAccessMask = GENERIC_WRITE;
+
+ if ((iReadWrite & OF_SHARE_COMPAT) == OF_SHARE_COMPAT )
+ dwShareMode = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE;
+ else if ((iReadWrite & OF_SHARE_DENY_NONE) == OF_SHARE_DENY_NONE)
+ dwShareMode = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE;
+ else if ((iReadWrite & OF_SHARE_DENY_READ) == OF_SHARE_DENY_READ)
+ dwShareMode = FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+ else if ((iReadWrite & OF_SHARE_DENY_WRITE) == OF_SHARE_DENY_WRITE )
+ dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE;
+ else if ((iReadWrite & OF_SHARE_EXCLUSIVE) == OF_SHARE_EXCLUSIVE)
+ dwShareMode = 0;
+
+ RtlInitUnicodeString (&TmpFileName, lpPathName);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &TmpFileName,
+ 0,
+ NULL,
+ NULL);
+
+ status = NtOpenFile( &hfile,
+ dwAccessMask,
+ &ObjectAttributes,
+ &StatusBlock, dwShareMode, FILE_NO_INTERMEDIATE_BUFFERING);
+ //BUG BUG check status!!!
+ if( !NT_SUCCESS( status ) ){
+ DPRINT((0,"PICE_open: NtOpenFile error: %x\n", status));
+ return 0;
+ }
+ return hfile;
+}
+
+int PICE_close (HANDLE hFile)
+{
+ if (NT_SUCCESS( ZwClose((HANDLE)hFile)))
+ {
+ return 0;
+ }
+ DPRINT((0,"ZwClose failed:\n"));
+ return -1;
+}
+
+size_t PICE_len( HANDLE hFile )
+{
+ FILE_STANDARD_INFORMATION fs;
+ IO_STATUS_BLOCK iosb;
+ NTSTATUS status;
+
+ status = ZwQueryInformationFile( hFile, &iosb, &fs, sizeof fs, FileStandardInformation );
+ if( !NT_SUCCESS( status ) ){
+ DPRINT((0,"PICE_len: ZwQueryInformationFile error: %x\n", status));
+ return 0;
+ }
+ //ASSERT(fs.EndOfFile.u.HighPart == 0);
+ return (size_t)fs.EndOfFile.u.LowPart;
+}
+
+/* From kernel32
+ * NOTE
+ * A raw converter for now. It assumes lpMultiByteStr is
+ * NEVER multi-byte (that is each input character is
+ * 8-bit ASCII) and is ALWAYS NULL terminated.
+ * FIXME-FIXME-FIXME-FIXME
+ */
+
+INT
+STDCALL
+PICE_MultiByteToWideChar (
+ UINT CodePage,
+ DWORD dwFlags,
+ LPCSTR lpMultiByteStr,
+ int cchMultiByte,
+ LPWSTR lpWideCharStr,
+ int cchWideChar
+ )
+{
+ int InStringLength = 0;
+ BOOL InIsNullTerminated = TRUE;
+ PCHAR r;
+ PWCHAR w;
+ int cchConverted;
+
+ /*
+ * Check the parameters.
+ */
+ if ( /* --- CODE PAGE --- */
+ ( (CP_ACP != CodePage)
+ && (CP_MACCP != CodePage)
+ && (CP_OEMCP != CodePage))
+ /* --- FLAGS --- */
+ /*|| (dwFlags ^ ( MB_PRECOMPOSED
+ | MB_COMPOSITE
+ | MB_ERR_INVALID_CHARS
+ | MB_USEGLYPHCHARS
+ )
+ )*/
+ /* --- INPUT BUFFER --- */
+ || (NULL == lpMultiByteStr)
+ )
+ {
+ DPRINT((0,"ERROR_INVALID_PARAMETER\n"));
+ return 0;
+ }
+ /*
+ * Compute the input buffer length.
+ */
+ if (-1 == cchMultiByte)
+ {
+ InStringLength = PICE_strlen(lpMultiByteStr);
+ }
+ else
+ {
+ InIsNullTerminated = FALSE;
+ InStringLength = cchMultiByte;
+ }
+ /*
+ * Does caller query for output
+ * buffer size?
+ */
+ if (0 == cchWideChar)
+ {
+ DPRINT((0,"ERROR_SUCCESS\n"));
+ return InStringLength;
+ }
+ /*
+ * Is space provided for the translated
+ * string enough?
+ */
+ if (cchWideChar < InStringLength)
+ {
+ DPRINT((0,"ERROR_INSUFFICIENT_BUFFER: cchWideChar: %d, InStringLength: %d\n", cchWideChar, InStringLength));
+ return 0;
+ }
+ /*
+ * Raw 8- to 16-bit conversion.
+ */
+ for ( cchConverted = 0,
+ r = (PCHAR) lpMultiByteStr,
+ w = (PWCHAR) lpWideCharStr;
+
+ ((*r) && (cchConverted < cchWideChar));
+
+ r++, w++,
+ cchConverted++
+ )
+ {
+ *w = (WCHAR) *r;
+ }
+ /*
+ * Is the input string NULL terminated?
+ */
+ if (TRUE == InIsNullTerminated)
+ {
+ *w = L'\0';
+ ++cchConverted;
+ }
+ /*
+ * Return how many characters we
+ * wrote in the output buffer.
+ */
+ return cchConverted;
+}
+
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ utils.h
+
+Abstract:
+
+ HEADER for utils.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+#include <stdarg.h>
+#include "../../../../ntoskrnl/include/internal/ps.h"
+#define __STR(x) #x
+#define STR(x) __STR(x)
+
+typedef enum {
+ kbDE,
+ kbUS,
+ kbDK,
+ kbMaximum
+} KeyboardLayout;
+
+// scancode to ASCII conversion
+typedef struct tagSCANTOASCII
+{
+ UCHAR s; // 0 terminates the table
+ UCHAR a;
+}SCANTOASCII, *PSCANTOASCII;
+
+typedef struct tagKEYBOARD_LAYOUT
+{
+ LPSTR name;
+ PSCANTOASCII normal;
+ PSCANTOASCII shifted;
+ PSCANTOASCII alted;
+} KEYBOARD_LAYOUT, *PKEYBOARD_LAYOUT;
+
+extern PKEYBOARD_LAYOUT CurrentKeyboard;
+
+typedef struct _FRAME
+{
+ ULONG error_code;
+ ULONG eip;
+ ULONG cs;
+ ULONG eflags;
+}FRAME;
+
+#define SHOW_FIELD_BYTE(ptr,field,wait)\
+{\
+ if(wait && WaitForKey()==FALSE)\
+ return TRUE;\
+ PICE_sprintf(tempCmd,#field" = %.2x\n",ptr->##field);\
+ Print(OUTPUT_WINDOW,tempCmd);\
+}
+
+#define SHOW_FIELD_WORD(ptr,field,wait)\
+{\
+ if(wait && WaitForKey()==FALSE)\
+ return TRUE;\
+ PICE_sprintf(tempCmd,#field" = %.4x\n",ptr->##field);\
+ Print(OUTPUT_WINDOW,tempCmd);\
+}
+
+#define SHOW_FIELD_DWORD(ptr,field,wait)\
+{\
+ if(wait && WaitForKey()==FALSE)\
+ return TRUE;\
+ PICE_sprintf(tempCmd,#field" = %.8x\n",ptr->##field);\
+ Print(OUTPUT_WINDOW,tempCmd);\
+}
+
+#define SHOW_FIELD_SEG_OFS(ptr,field1,field2,wait)\
+{\
+ if(wait && WaitForKey()==FALSE)\
+ return TRUE;\
+ PICE_sprintf(tempCmd,#field1":"#field2" = %.4x:%.8x\n",ptr->##field1,ptr->##field2);\
+ Print(OUTPUT_WINDOW,tempCmd);\
+}
+
+typedef struct _PCI_NUMBER
+{
+ union {
+ struct
+ {
+ ULONG res2 : 2;
+ ULONG reg : 6; // 64 regs per function
+ ULONG func : 3; // 8 functions per device
+ ULONG dev : 5; // 32 device per bus
+ ULONG bus : 8; // 256 buses
+ ULONG res1 : 7;
+ ULONG ce : 1; // 1 to enable
+ }bits;
+ ULONG AsUlong;
+ }u;
+}PCI_NUMBER;
+/*
+typedef struct _PCI_COMMON_CONFIG {
+ USHORT VendorID; // (ro)
+ USHORT DeviceID; // (ro)
+ USHORT Command; // Device control
+ USHORT Status;
+ UCHAR RevisionID; // (ro)
+ UCHAR ProgIf; // (ro)
+ UCHAR SubClass; // (ro)
+ UCHAR BaseClass; // (ro)
+ UCHAR CacheLineSize; // (ro+)
+ UCHAR LatencyTimer; // (ro+)
+ UCHAR HeaderType; // (ro)
+ UCHAR BIST; // Built in self test
+ ULONG BaseAddresses[6];
+ ULONG CIS;
+ USHORT SubVendorID;
+ USHORT SubSystemID;
+ ULONG ROMBaseAddress;
+ UCHAR CapabilitiesPtr;
+ UCHAR Reserved1[3];
+ ULONG Reserved2;
+ UCHAR InterruptLine; //
+ UCHAR InterruptPin; // (ro)
+ UCHAR MinimumGrant; // (ro)
+ UCHAR MaximumLatency; // (ro)
+}PCI_COMMON_CONFIG;
+*/
+
+typedef struct tagPageDir
+{
+ ULONG P :1;
+ ULONG RW :1;
+ ULONG US :1;
+ ULONG PWT :1;
+ ULONG PCD :1;
+ ULONG A :1;
+ ULONG dummy :1;
+ ULONG PS :1;
+ ULONG G :1;
+ ULONG Avail :3;
+ ULONG PTBase :20;
+}PAGEDIR,*PPAGEDIR;
+
+typedef struct tagGdt
+{
+ ULONG Limit_15_0 :16;
+ ULONG Base_15_0 :16;
+ ULONG Base_23_16 :8;
+ ULONG SegType :4;
+ ULONG DescType :1;
+ ULONG Dpl :2;
+ ULONG Present :1;
+ ULONG Limit_19_16 :4;
+ ULONG Avl :1;
+ ULONG Reserved :1;
+ ULONG DefOp :1;
+ ULONG Gran :1;
+ ULONG Base_31_24 :8;
+}GDT,*PGDT;
+
+typedef struct tagIdt
+{
+ ULONG Offset_15_0 :16;
+ ULONG Selector :16;
+ ULONG Reserved :8;
+ ULONG DescType :5;
+ ULONG Dpl :2;
+ ULONG Present :1;
+ ULONG Offset_31_16 :16;
+}IDT,*PIDT;
+
+typedef struct tagDESCRIPTOR
+{
+ USHORT Cpl :2; // current privilege level
+ USHORT Ti :1; // table index (GDT=0 LDT=1)
+ USHORT Val :13; // index into table
+}DESCRIPTOR,*PDESCRIPTOR;
+
+PKEYBOARD_LAYOUT GetKeyboardLayout();
+PKEYBOARD_LAYOUT SetKeyboardLayoutByName(LPSTR Name);
+void PICE_memset(void* p,unsigned char c,int sz);
+void PICE_memcpy(void* t,void* s,int sz);
+char *PICE_strrev(char *);
+ULONG PICE_strcmp(char* s1,char* s2);
+ULONG PICE_strcmpi(char* s1,char* s2);
+ULONG PICE_strncmpi(char* s1,char* s2,ULONG len);
+USHORT PICE_strlen(const char* s);
+char* PICE_strcat(char* s1,char* s2);
+BOOLEAN PICE_isprint(char c);
+char* PICE_strcpy(char* s1,char* s2);
+char* PICE_strncpy(char* s1,char* s2,int len);
+char* PICE_strchr(char* s,char c);
+int PICE_isdigit( int c );
+int PICE_isxdigit( int c );
+int PICE_islower( int c );
+int PICE_isalpha( int c );
+
+int PICE_sprintf(char * buf, const char *fmt, ...);
+int PICE_vsprintf(char *buf, const char *fmt, va_list args);
+
+BOOLEAN IsAddressValid(ULONG Addr);
+BOOLEAN IsAddressWriteable(ULONG Addr);
+BOOLEAN SetAddressWriteable(ULONG address,BOOLEAN bSet);
+BOOLEAN IsRangeValid(ULONG addr,ULONG Length);
+void IntelStackWalk(ULONG pc,ULONG ebp,ULONG esp);
+
+ULONG ReadPhysMem(ULONG Address,ULONG ulSize);
+void WritePhysMem(ULONG Address,ULONG Datum,ULONG ulSize);
+
+BOOLEAN IsRetAtEIP(void);
+BOOLEAN IsCallInstrAtEIP(void);
+
+ULONG GetLinearAddress(USHORT Segment,ULONG Offset);
+
+#define OUTPUT_BUFFER_FULL 0x01
+#define INPUT_BUFFER_FULL 0x02
+#define MOUSE_OUTPUT_BUFFER_FULL 0x20
+
+void ShowStoppedMsg(void);
+void ShowRunningMsg(void);
+
+void SetHardwareBreakPoints(void);
+void SetHardwareBreakPoint(ULONG ulAddress,ULONG ulReg);
+
+// this should be in disasm.h but someone misused the header files
+BOOLEAN Disasm(PULONG pOffset, PUCHAR pchDst);
+//////////////////////////////////////////////////////////////////
+
+//segments defined in \include\napi\i386\segment.h
+#define GLOBAL_CODE_SEGMENT (KERNEL_CS)
+#define GLOBAL_DATA_SEGMENT (KERNEL_DS)
+
+//#define OVR_CS .byte 0x2e
+//#define OVR_FS .byte 0x64
+
+void DisplayRegs(void);
+void SaveOldRegs(void);
+
+BOOLEAN CheckLoadAbort(void);
+
+UCHAR KeyboardGetKeyPolled(void);
+void KeyboardFlushKeyboardQueue(void);
+
+#define _PAGE_PRESENT 0x001
+#define _PAGE_RW 0x002
+#define _PAGE_USER 0x004
+#define _PAGE_PWT 0x008
+#define _PAGE_PCD 0x010
+#define _PAGE_ACCESSED 0x020
+#define _PAGE_DIRTY 0x040
+#define _PAGE_PSE 0x080
+#define _PAGE_4M _PAGE_PSE
+#define _PAGE_SIZE 0x1000
+
+
+UCHAR AsciiFromScan(UCHAR s);
+UCHAR AsciiToScan(UCHAR s);
+
+void outportb(PUCHAR port,UCHAR data);
+UCHAR inportb(PUCHAR port);
+
+void outb_p(UCHAR data, PUCHAR port);
+UCHAR inb_p(PUCHAR port);
+
+VOID outl(ULONG l, PULONG port);
+ULONG inl(PULONG port);
+
+
+#define save_flags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
+#define restore_flags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc")
+#define cli() __asm__ __volatile__("cli": : :"memory")
+#define sti() __asm__ __volatile__("sti": : :"memory")
+
+#ifdef NDEBUG
+#define ASSERT(x)
+#else
+#define ASSERT(x) if (!(x)) { DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__); KeBugCheck(0); }
+#endif
+
+//extern unsigned long sys_call_table[];
+
+//struct mm_struct *GetInitMm(void);
+
+PMADDRESS_SPACE my_init_mm;
+LIST_ENTRY* pPsProcessListHead;
+
+void EnablePassThrough(void);
+
+#define PAGEDPOOL (1)
+#define NONPAGEDPOOL (0)
+
+void * PICE_malloc( size_t numBytes, BOOLEAN fromPaged );
+void PICE_free( void* p );
+
+HANDLE PICE_open (LPCWSTR lpPathName, int iReadWrite);
+long PICE_read(HANDLE hFile, LPVOID lpBuffer, long lBytes);
+int PICE_close (HANDLE hFile);
+size_t PICE_len( HANDLE hFile );
+WCHAR * PICE_wcscpy(WCHAR * str1,const WCHAR * str2);
+INT
+STDCALL
+PICE_MultiByteToWideChar (
+ UINT CodePage,
+ DWORD dwFlags,
+ LPCSTR lpMultiByteStr,
+ int cchMultiByte,
+ LPWSTR lpWideCharStr,
+ int cchWideChar
+ );
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ vga.c
+
+Abstract:
+
+ VGA HW dependent draw routines
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+ Reactos Port by Eugene Ingerman
+
+Revision History:
+
+ 04-Aug-1998: created
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+////////////////////////////////////////////////////
+// INCLUDES
+////
+#include "remods.h"
+#include "precomp.h"
+
+//#include <asm/io.h>
+//#include <linux/ctype.h>
+
+
+////////////////////////////////////////////////////
+// PROTOTYPES
+////
+extern void pice_save_current_registers(void);
+extern void pice_restore_current_registers(void);
+extern void pice_set_mode_3_80x50(void);
+extern void pice_set_mode_3_80x25(void);
+
+extern UCHAR cGraphTable[8*256];
+
+// storage for original VGA font
+UCHAR cGraphTable2[16*256];
+
+////////////////////////////////////////////////////
+// DEFINES
+////
+#define VGA_EXTENDED // define this for 80x50 console mode
+
+#ifndef VGA_EXTENDED
+#define SCREEN_BUFFER_SIZE (80*25*2)
+#else
+#define SCREEN_BUFFER_SIZE (80*50*2)
+#endif
+
+/* Port addresses of control regs */
+#define MISCOUTPUT 0x3c2
+#define FEATURECONTROL 0x3da
+#define SEQUENCER 0x3c4
+#define CRTC 0x03d4
+#define GRAPHICS 0x3ce
+#define ATTRIBS 0x03c0
+#define PELADDRESSWRITE 0x3c8
+#define PELDATAREG 0x3c9
+
+/* Number of regs on the various controllers */
+
+#define MAXSEQ 5
+#define MAXCRTC 0x19
+#define MAXGRAPH 0x9
+#define MAXATTRIB 0x015
+
+////////////////////////////////////////////////////
+// GLOBALS
+////
+// used for HERCULES text and VGA text mode
+WINDOW wWindowVga[4]=
+#ifndef VGA_EXTENDED
+{
+ {1,3,1,0,FALSE},
+ {5,4,1,0,FALSE},
+ {10,9,1,0,FALSE},
+ {20,4,1,0,FALSE}
+};
+#else // VGA_EXTENDED
+{
+ {1,3,1,0,FALSE},
+ {5,4,1,0,FALSE},
+ {10,24,1,0,FALSE},
+ {35,14,1,0,FALSE}
+};
+#endif // VGA_EXTENDED
+
+PUCHAR pScreenBufferVga;
+PUCHAR pScreenBufferSaveVga = NULL;
+PUCHAR pScreenBufferTempVga;
+PUCHAR pScreenBufferHardwareVga;
+PUCHAR pFontBufferVga = NULL;
+
+UCHAR offset_a = 0;
+UCHAR offset_c = 0,offset_d = 0;
+UCHAR offset_e = 0,offset_f = 0;
+
+struct _attr
+{
+ union
+ {
+ struct
+ {
+
+ UCHAR fgcol : 4;
+ UCHAR bkcol : 3;
+ UCHAR blink : 1;
+ }bits;
+ UCHAR Asuchar;
+ }u;
+}attr;
+
+unsigned char oldgraphicsmode;
+unsigned char oldgraphicsmisc;
+unsigned char oldsqregmapmask;
+unsigned char oldsqregmemory;
+unsigned char oldgraphicssetresetenable;
+unsigned char oldgraphicsreadmapsel;
+
+unsigned char read_vga_reg(int port, int reg)
+{
+ outportb(port,reg);
+ return(inportb(port+1));
+}
+
+void write_vga_reg(int port, unsigned char reg, unsigned char value)
+{
+ outportb(port,reg);
+ outportb(port+1,value);
+}
+
+/* Registers within controllers */
+#define VREND 0x11
+#define GRREGSETRESET 0
+#define GRREGENABLESETRESET 1
+#define GRREGREADMAPSEL 4
+#define SQREGMAPMASK 2
+#define SQREGMEMORY 4
+#define GRREGWRMODE 5
+#define GRREGMISC 6
+
+void map_font_memory(void)
+{
+ oldgraphicssetresetenable = read_vga_reg(GRAPHICS, GRREGENABLESETRESET);
+ oldgraphicsmode = read_vga_reg(GRAPHICS, GRREGWRMODE);
+ oldgraphicsmisc = read_vga_reg(GRAPHICS, GRREGMISC);
+ oldgraphicsreadmapsel = read_vga_reg(GRAPHICS, GRREGREADMAPSEL);
+ oldsqregmapmask = read_vga_reg(SEQUENCER, SQREGMAPMASK);
+ oldsqregmemory = read_vga_reg(SEQUENCER, SQREGMEMORY);
+
+
+ /* Make sure set/reset enable is off */
+ write_vga_reg(GRAPHICS,GRREGENABLESETRESET,0);
+ /* Select read plane 2 */
+ write_vga_reg(GRAPHICS,GRREGREADMAPSEL,0x02);
+ /* Make sure write and read mode = 0 */
+ write_vga_reg(GRAPHICS,GRREGWRMODE,0x00);
+ /* Set mapping to 64K at a000:0 & turn off odd/even at the graphics reg */
+ write_vga_reg(GRAPHICS,GRREGMISC, 0x04);
+ /* Set sequencer plane to 2 */
+ write_vga_reg(SEQUENCER,SQREGMAPMASK, 0x04);
+ /* Turn off odd/even at the sequencer */
+ write_vga_reg(SEQUENCER,SQREGMEMORY, 0x07);
+}
+
+void unmap_font_memory(void)
+{
+ write_vga_reg(GRAPHICS,GRREGENABLESETRESET,oldgraphicssetresetenable);
+ write_vga_reg(GRAPHICS,GRREGWRMODE,oldgraphicsmode);
+ write_vga_reg(GRAPHICS,GRREGREADMAPSEL,oldgraphicsreadmapsel);
+ write_vga_reg(GRAPHICS,GRREGMISC, oldgraphicsmisc);
+ write_vga_reg(SEQUENCER,SQREGMAPMASK, oldsqregmapmask);
+ write_vga_reg(SEQUENCER,SQREGMEMORY, oldsqregmemory);
+}
+
+/* Font and palette constants */
+#define BYTESPERFONT 8
+#define FONTENTRIES 256
+#define FONTBUFFERSIZE 8192
+
+void save_font(UCHAR* graph_table)
+{
+ PUCHAR FontBase = pFontBufferVga;
+ int i,j;
+ map_font_memory();
+
+ for (i=0; i < FONTENTRIES; i++)
+ for (j=0; j < 16; j++)
+ graph_table[i*16+j] = FontBase[i*32+j];
+
+ unmap_font_memory();
+}
+
+void load_font(UCHAR* graph_table,int bEnter)
+{
+ PUCHAR FontBase = pFontBufferVga;
+ int i,j;
+ map_font_memory();
+
+ if(bEnter)
+ {
+#ifdef VGA_EXTENDED
+ for (i=0; i < FONTENTRIES; i++)
+ for (j=0; j < 8; j++)
+ FontBase[i*32+j] = graph_table[i*BYTESPERFONT+j];
+#else // VGA_EXTENDED
+ for (i=0; i < FONTENTRIES; i++)
+ for (j=0; j < 16; j++)
+ FontBase[i*32+j] = graph_table[i*BYTESPERFONT+(j/2)] << (j&1);
+#endif // VGA_EXTENDED
+ }
+ else
+ {
+ for (i=0; i < FONTENTRIES; i++)
+ for (j=0; j < 16; j++)
+ FontBase[i*32+j] = graph_table[i*16+j];
+ }
+
+ unmap_font_memory();
+}
+
+//*************************************************************************
+// SetForegroundColorVga()
+//
+//*************************************************************************
+void SetForegroundColorVga(ECOLORS col)
+{
+ attr.u.bits.fgcol = col;
+ attr.u.bits.blink = 0;
+}
+
+//*************************************************************************
+// SetBackgroundColorVga()
+//
+//*************************************************************************
+void SetBackgroundColorVga(ECOLORS col)
+{
+ attr.u.bits.bkcol = col;
+ attr.u.bits.blink = 0;
+}
+
+//*************************************************************************
+// PrintGrafVga()
+//
+//*************************************************************************
+void PrintGrafVga(ULONG x,ULONG y,UCHAR c)
+{
+ ((PUSHORT)pScreenBufferVga)[y*GLOBAL_SCREEN_WIDTH + x] = (USHORT)((attr.u.Asuchar<<8)|c);
+}
+
+//*************************************************************************
+// ShowCursor()
+//
+// show hardware cursor
+//*************************************************************************
+void ShowCursorVga(void)
+{
+ ENTER_FUNC();
+
+ bCursorEnabled=TRUE;
+
+ outb_p(0x0a,0x3d4);
+ outb_p(inb_p(0x3d5)&~0x20,0x3d5);
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// HideCursorVga()
+//
+// hide hardware cursor
+//*************************************************************************
+void HideCursorVga(void)
+{
+ ENTER_FUNC();
+ bCursorEnabled=FALSE;
+
+ outb_p(0x0a,0x3d4);
+ outb_p(inb_p(0x3d5)|0x20,0x3d5);
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// CopyLineTo()
+//
+// copy a line from src to dest
+//*************************************************************************
+void CopyLineToVga(USHORT dest,USHORT src)
+{
+ PUSHORT p = (PUSHORT)pScreenBufferVga;
+
+ ENTER_FUNC();
+
+ PICE_memcpy(&p[dest*GLOBAL_SCREEN_WIDTH],&p[src*GLOBAL_SCREEN_WIDTH],GLOBAL_SCREEN_WIDTH*sizeof(USHORT));
+
+ LEAVE_FUNC();
+}
+
+//*************************************************************************
+// InvertLineVga()
+//
+// invert a line on the screen
+//*************************************************************************
+void InvertLineVga(ULONG line)
+{
+ ULONG i;
+ PUSHORT p = (PUSHORT)pScreenBufferVga;
+ USHORT attr;
+
+ if(line < GLOBAL_SCREEN_HEIGHT)
+ {
+ attr = p[line*GLOBAL_SCREEN_WIDTH]>>8;
+ attr = ((attr & 0x07)<<4) | ((attr & 0xF0)>>4);
+ attr <<= 8;
+ for(i=0;i<GLOBAL_SCREEN_WIDTH;i++)
+ p[line*GLOBAL_SCREEN_WIDTH + i] = (p[line*GLOBAL_SCREEN_WIDTH + i] & 0x00FF) | attr;
+ }
+}
+
+//*************************************************************************
+// HatchLineVga()
+//
+// hatches a line on the screen
+//*************************************************************************
+void HatchLineVga(ULONG line)
+{
+ ULONG i;
+ PUSHORT p = (PUSHORT)pScreenBufferVga;
+
+ if(line < GLOBAL_SCREEN_HEIGHT)
+ {
+ for(i=0;i<GLOBAL_SCREEN_WIDTH;i++)
+ p[line*GLOBAL_SCREEN_WIDTH + i] = (p[line*GLOBAL_SCREEN_WIDTH + i] & 0xF0FF) | 0x0c00;
+ }
+}
+
+//*************************************************************************
+// ClrLineVga()
+//
+// clear a line on the screen
+//*************************************************************************
+void ClrLineVga(ULONG line)
+{
+ ULONG i;
+ PUSHORT p = (PUSHORT)pScreenBufferVga;
+
+ if(line < GLOBAL_SCREEN_HEIGHT)
+ {
+ for(i=0;i<GLOBAL_SCREEN_WIDTH;i++)
+ p[line*GLOBAL_SCREEN_WIDTH + i] = (USHORT)((attr.u.Asuchar<<8) | 0x20);
+ }
+}
+
+//*************************************************************************
+// PrintLogoVga()
+//
+//*************************************************************************
+void PrintLogoVga(BOOLEAN bShow)
+{
+ NOT_IMPLEMENTED();
+}
+
+//*************************************************************************
+// PrintCursorVga()
+//
+// emulate a blinking cursor block
+//*************************************************************************
+void PrintCursorVga(BOOLEAN bForce)
+{
+ static ULONG count=0;
+ USHORT charoffset;
+ UCHAR data;
+ ULONG x=wWindow[OUTPUT_WINDOW].usCurX,y=wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].usCurY;
+
+ if( count++>250 )
+ {
+ count=0;
+
+ charoffset = (y* GLOBAL_SCREEN_WIDTH + x);
+
+ outb_p(0x0e,0x3d4);
+ data=(UCHAR)((charoffset>>8)&0xFF);
+ outb_p(data,0x3d5);
+
+ outb_p(0x0f,0x3d4);
+ data=(UCHAR)(charoffset & 0xFF);
+ outb_p(data,0x3d5);
+ }
+}
+
+//*************************************************************************
+// SaveGraphicsVga()
+//
+//*************************************************************************
+void SaveGraphicsStateVga(void)
+{
+ UCHAR data;
+
+ // save current regs
+ pice_save_current_registers();
+
+ // unprotect crtc regs 0-7
+ outb_p(0x11,0x3d4);
+ data = inb_p(0x3d5);
+ outb_p(data & 0x7F,0x3d5);
+
+ // save current font
+ save_font(cGraphTable2);
+
+ // restore original regs
+#ifdef VGA_EXTENDED
+ pice_set_mode_3_80x50();
+#else
+ pice_set_mode_3_80x25();
+#endif
+
+ // load a font
+ load_font(cGraphTable,1);
+
+ // copy the screen content to temp area
+ PICE_memcpy(pScreenBufferTempVga,pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE);
+ // copy the console to the screen
+ PICE_memcpy(pScreenBufferHardwareVga,pScreenBufferVga,SCREEN_BUFFER_SIZE);
+ // save original pointer
+ pScreenBufferSaveVga = pScreenBufferVga;
+ // pScreenBufferVga now points to screen
+ pScreenBufferVga = pScreenBufferHardwareVga;
+}
+
+//*************************************************************************
+// RestoreGraphicsStateVga()
+//
+//*************************************************************************
+void RestoreGraphicsStateVga(void)
+{
+ UCHAR data;
+
+ // unprotect crtc regs 0-7
+ outb_p(0x11,0x3d4);
+ data = inb_p(0x3d5);
+ outb_p(data & 0x7F,0x3d5);
+
+ // restore original regs
+ pice_restore_current_registers();
+
+ // load a font
+ load_font(cGraphTable2,0);
+
+ pScreenBufferVga = pScreenBufferSaveVga;
+ // copy screen to the console
+ PICE_memcpy(pScreenBufferVga,pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE);
+ // copy the temp area to the screen
+ PICE_memcpy(pScreenBufferHardwareVga,pScreenBufferTempVga,SCREEN_BUFFER_SIZE);
+}
+
+//*************************************************************************
+// ConsoleInitVga()
+//
+// init terminal screen
+//*************************************************************************
+BOOLEAN ConsoleInitVga(void)
+{
+ BOOLEAN bResult = FALSE;
+ PUSHORT p;
+ PHYSICAL_ADDRESS FrameBuffer;
+ PHYSICAL_ADDRESS FontBuffer;
+
+
+ ENTER_FUNC();
+
+ ohandlers.CopyLineTo = CopyLineToVga;
+ ohandlers.PrintGraf = PrintGrafVga;
+ ohandlers.ClrLine = ClrLineVga;
+ ohandlers.InvertLine = InvertLineVga;
+ ohandlers.HatchLine = HatchLineVga;
+ ohandlers.PrintLogo = PrintLogoVga;
+ ohandlers.PrintCursor = PrintCursorVga;
+ ohandlers.SaveGraphicsState = SaveGraphicsStateVga;
+ ohandlers.RestoreGraphicsState = RestoreGraphicsStateVga;
+ ohandlers.ShowCursor = ShowCursorVga;
+ ohandlers.HideCursor = HideCursorVga;
+ ohandlers.SetForegroundColor = SetForegroundColorVga;
+ ohandlers.SetBackgroundColor = SetBackgroundColorVga;
+
+ ihandlers.GetKeyPolled = KeyboardGetKeyPolled;
+ ihandlers.FlushKeyboardQueue = KeyboardFlushKeyboardQueue;
+
+ SetWindowGeometry(wWindowVga);
+
+ GLOBAL_SCREEN_WIDTH = 80;
+#ifndef VGA_EXTENDED
+ GLOBAL_SCREEN_HEIGHT = 25;
+#else // VGA_EXTENDED
+ GLOBAL_SCREEN_HEIGHT = 50;
+#endif // VGA_EXTENDED
+
+ attr.u.Asuchar = 0x07;
+
+ // the real framebuffer
+ FrameBuffer.u.LowPart = 0xB8000;
+ pScreenBufferHardwareVga = MmMapIoSpace(FrameBuffer,SCREEN_BUFFER_SIZE,MmNonCached);
+
+ //The real font buffer
+ FontBuffer.u.LowPart = 0xA0000;
+ pFontBufferVga = MmMapIoSpace(FontBuffer,FONTBUFFERSIZE,MmNonCached);
+
+ // the console
+ pScreenBufferVga = PICE_malloc(SCREEN_BUFFER_SIZE,NONPAGEDPOOL);
+ // the save area
+ pScreenBufferTempVga = PICE_malloc(SCREEN_BUFFER_SIZE,NONPAGEDPOOL);
+
+ if(pScreenBufferVga)
+ {
+ DPRINT((0,"VGA memory phys. 0x000b0000 mapped to virt. 0x%x\n",pScreenBufferVga));
+
+ bResult = TRUE;
+
+ p = (PUSHORT)pScreenBufferVga;
+
+ PICE_memset(pScreenBufferVga,0x0,SCREEN_BUFFER_SIZE);
+
+ DPRINT((0,"VGA memory cleared!\n"));
+
+ EmptyRingBuffer();
+
+ DPRINT((0,"ConsoleInitVga() SUCCESS!\n"));
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+//*************************************************************************
+// ConsoleShutdownVga()
+//
+// exit terminal screen
+//*************************************************************************
+void ConsoleShutdownVga(void)
+{
+ ENTER_FUNC();
+
+ if(pScreenBufferVga)
+ {
+ PICE_free(pScreenBufferVga);
+ PICE_free(pScreenBufferTempVga);
+ MmUnmapIoSpace(pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE);
+ MmUnmapIoSpace(pFontBufferVga,FONTBUFFERSIZE);
+ }
+
+ LEAVE_FUNC();
+}
+
+
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ vga.h
+
+Abstract:
+
+ HEADER for vga.c
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+Revision History:
+
+ 15-Nov-2000: general cleanup of source files
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+BOOLEAN ConsoleInitVga(void);
+void ConsoleShutdownVga(void);
--- /dev/null
+;/*++
+;
+;Copyright (c) 1998-2001 Klaus P. Gerlicher
+;
+;Module Name:
+;
+; vga_utils.asm
+;
+;Abstract:
+;
+; assembler function for directly programming standard VGA
+;
+;Environment:
+;
+; LINUX 2.2.X
+; Kernel mode only
+;
+;Author:
+;
+; Klaus P. Gerlicher
+; Reactos Port by Eugene Ingerman
+;
+;Revision History:
+;
+; 30-Oct-2001: created
+;
+;Copyright notice:
+;
+; This file may be distributed under the terms of the GNU Public License.
+;
+;--*/
+
+global _pice_save_current_registers
+global _pice_restore_current_registers
+global _pice_set_mode_3_80x50
+global _pice_set_mode_3_80x25
+
+;****************************************************************************
+;* some assign's ************************************************************
+;****************************************************************************
+%assign VGA_CRT_REGISTERS 24
+%assign VGA_ATTRIBUTE_REGISTERS 21
+%assign VGA_GRAPHIC_REGISTERS 9
+%assign VGA_SEQUENCER_REGISTERS 5
+%assign VGA_MISC_REGISTERS 1
+
+%assign VGA_IO_BASE 03c0h
+%assign VGA_IO_SIZE 020h
+
+%assign VGA_ATTRIBUTE_INDEX 03c0h
+%assign VGA_ATTRIBUTE_DATA_WRITE 03c0h
+%assign VGA_ATTRIBUTE_DATA_READ 03c1h
+%assign VGA_MISC_DATA_WRITE 03c2h
+%assign VGA_SEQUENCER_INDEX 03c4h
+%assign VGA_SEQUENCER_DATA 03c5h
+%assign VGA_PEL_MASK 03c6h
+%assign VGA_PEL_INDEX_READ 03c7h
+%assign VGA_PEL_INDEX_WRITE 03c8h
+%assign VGA_PEL_DATA 03c9h
+%assign VGA_MISC_DATA_READ 03cch
+%assign VGA_GRAPHIC_INDEX 03ceh
+%assign VGA_GRAPHIC_DATA 03cfh
+%assign VGA_CRT_INDEX 03d4h
+%assign VGA_CRT_DATA 03d5h
+%assign VGA_INPUT_STATUS 03dah
+
+section .data
+pice_mode3_80x50_registers:
+; offsets 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18
+.crt: db 0x5f,0x4f,0x50,0x82,0x55,0x80,0xbf,0x1f,0x00,0x67,0x06,0x07,0x00,0x00,0x00,0x00,0x9c,0x8f,0x8f,0x28,0x1f,0x96,0xb9,0xa3,0xff
+.attribute db 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x08,0x00,0x0f,0x00,0x00
+.graphic: db 0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,0xff
+.sequencer: db 0x03,0x00,0x03,0x00,0x02 ; 9 bits per char
+;.sequencer: db 0x03,0x01,0x03,0x00,0x02 ; 8 bits per char
+.misc: db 0x67
+
+pice_mode3_80x25_registers:
+; offsets 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18
+.crt: db 0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x30,0xe8,0x9c,0x0e,0x8f,0x28,0x1f,0x96,0xb9,0xa3
+.attribute db 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x0c,0x00,0x0f,0x08,0x00
+.graphic: db 0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,0xff
+.sequencer: db 0x03,0x00,0x03,0x00,0x02
+.misc: db 0x67
+
+
+
+section .bss
+pice_current_registers:
+.crt: resb VGA_CRT_REGISTERS
+.attribute: resb VGA_ATTRIBUTE_REGISTERS
+.graphic: resb VGA_GRAPHIC_REGISTERS
+.sequencer: resb VGA_SEQUENCER_REGISTERS
+.misc: resb VGA_MISC_REGISTERS
+ align 4
+.colormap: resd 256
+
+;****************************************************************************
+;* pice_save_current_charset ************************************************
+;****************************************************************************
+section .text
+pice_address dd 0xc00a0000
+pice_save_current_charset:
+ xor dword ebx, ebx
+ call pice_select_read_plane
+ mov dword ecx, 04000h
+ mov dword esi, [pice_address]
+ mov dword edi, pice_charset_saved
+ cld
+ rep movsd
+ mov dword ebx, 00100h
+ call pice_select_read_plane
+ mov dword ecx, 04000h
+ mov dword esi, [pice_address]
+ mov dword edi, (pice_charset_saved + 010000h)
+ cld
+ rep movsd
+ mov dword ebx, 00200h
+ call pice_select_read_plane
+ mov dword ecx, 04000h
+ mov dword esi, [pice_address]
+ mov dword edi, (pice_charset_saved + 020000h)
+ cld
+ rep movsd
+ mov dword ebx, 00300h
+ call pice_select_read_plane
+ mov dword ecx, 04000h
+ mov dword esi, [pice_address]
+ mov dword edi, (pice_charset_saved + 030000h)
+ cld
+ rep movsd
+.end: ret
+
+
+
+;****************************************************************************
+;* pice_restore_current_charset ****************************************************
+;****************************************************************************
+section .text
+pice_restore_current_charset:
+ mov dword ebx, 00100h
+ call pice_select_write_plane
+ mov dword ecx, 04000h
+ mov dword esi, pice_charset_saved
+ mov dword edi, [pice_address]
+ cld
+ rep movsd
+ mov dword ebx, 00200h
+ call pice_select_write_plane
+ mov dword ecx, 04000h
+ mov dword esi, (pice_charset_saved + 010000h)
+ mov dword edi, [pice_address]
+ cld
+ rep movsd
+ mov dword ebx, 00400h
+ call pice_select_write_plane
+ mov dword ecx, 04000h
+ mov dword esi, (pice_charset_saved + 020000h)
+ mov dword edi, [pice_address]
+ cld
+ rep movsd
+ mov dword ebx, 00800h
+ call pice_select_write_plane
+ mov dword ecx, 04000h
+ mov dword esi, (pice_charset_saved + 030000h)
+ mov dword edi, [pice_address]
+ cld
+ rep movsd
+.end: ret
+
+;****************************************************************************
+;* pice_get_crt_registers **************************************************
+;****************************************************************************
+;* ebx=> pointer where to store crt registers
+;****************************************************************************
+section .text
+pice_get_crt_registers:
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_CRT_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_CRT_DATA
+ in byte al, dx
+ mov byte [ebx + ecx], al
+ inc dword ecx
+ cmp dword ecx, VGA_CRT_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_get_attribute_registers ********************************************
+;****************************************************************************
+;* ebx=> pointer where to store attribute registers
+;****************************************************************************
+section .text
+pice_get_attribute_registers:
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_INPUT_STATUS
+ in byte al, dx
+ mov dword edx, VGA_ATTRIBUTE_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_ATTRIBUTE_DATA_READ
+ in byte al, dx
+ mov byte [ebx + ecx], al
+ inc dword ecx
+ cmp dword ecx, VGA_ATTRIBUTE_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_get_graphic_registers **********************************************
+;****************************************************************************
+;* ebx=> pointer where to store graphics registers
+;****************************************************************************
+section .text
+pice_get_graphic_registers:
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ in byte al, dx
+ mov byte [ebx + ecx], al
+ inc dword ecx
+ cmp dword ecx, VGA_GRAPHIC_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_get_sequencer_registers ********************************************
+;****************************************************************************
+;* ebx=> pointer where to store sequencer registers
+;****************************************************************************
+section .text
+pice_get_sequencer_registers:
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_SEQUENCER_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ in byte al, dx
+ mov byte [ebx + ecx], al
+ inc dword ecx
+ cmp dword ecx, VGA_SEQUENCER_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_get_misc_registers *************************************************
+;****************************************************************************
+;* ebx=> pointer where to store misc register
+;****************************************************************************
+section .text
+pice_get_misc_registers:
+ mov dword edx, VGA_MISC_DATA_READ
+ in byte al, dx
+ mov byte [ebx], al
+ ret
+
+
+
+;****************************************************************************
+;* pice_get_colormap *******************************************************
+;****************************************************************************
+;* ebx=> pointer where to store colormap
+;****************************************************************************
+section .text
+pice_get_colormap:
+ xor dword ecx, ecx
+ xor dword eax, eax
+ mov dword edx, VGA_PEL_INDEX_READ
+ out word dx, al
+ mov dword edx, VGA_PEL_DATA
+.loop: in byte al, dx
+ shl dword eax, 8
+ in byte al, dx
+ shl dword eax, 8
+ in byte al, dx
+ mov dword [ebx + 4 * ecx], eax
+ inc dword ecx
+ test byte cl, cl
+ jnz .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_set_crt_registers **************************************************
+;****************************************************************************
+;* ebx=> pointer to stored crt registers
+;****************************************************************************
+section .text
+pice_set_crt_registers:
+
+ ;deprotect CRT registers 0 - 7
+
+ mov dword edx, VGA_CRT_INDEX
+ mov byte al, 011h
+ out word dx, al
+ mov dword edx, VGA_CRT_DATA
+ in byte al, dx
+ and byte al, 07fh
+ out word dx, al
+
+ ;write to the registers
+
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_CRT_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_CRT_DATA
+ mov byte al, [ebx + ecx]
+ out word dx, al
+ inc dword ecx
+ cmp dword ecx, VGA_CRT_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_set_attribute_registers ********************************************
+;****************************************************************************
+;* ebx=> pointer to stored attibute registers
+;****************************************************************************
+section .text
+pice_set_attribute_registers:
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_INPUT_STATUS
+ in byte al, dx
+ mov dword edx, VGA_ATTRIBUTE_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_ATTRIBUTE_DATA_WRITE
+ mov byte al, [ebx + ecx]
+ out word dx, al
+ inc dword ecx
+ cmp dword ecx, VGA_ATTRIBUTE_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_set_graphic_registers **********************************************
+;****************************************************************************
+;* ebx=> pointer to stored graphic registers
+;****************************************************************************
+section .text
+pice_set_graphic_registers:
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ mov byte al, [ebx + ecx]
+ out word dx, al
+ inc dword ecx
+ cmp dword ecx, VGA_GRAPHIC_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_set_sequencer_registers ********************************************
+;****************************************************************************
+;* ebx=> pointer to stored sequencer registers
+;****************************************************************************
+section .text
+pice_set_sequencer_registers:
+
+ ;synchronous reset on
+
+ mov dword edx, VGA_SEQUENCER_INDEX
+ xor dword eax, eax
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ inc dword eax
+ out word dx, al
+
+ ;write to the registers
+
+ mov dword edx, VGA_SEQUENCER_INDEX
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ mov byte al, [ebx + 1]
+ or byte al, 020h
+ out word dx, al
+ mov dword ecx, 2
+.loop: mov dword edx, VGA_SEQUENCER_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ mov byte al, [ebx + ecx]
+ out word dx, al
+ inc dword ecx
+ cmp dword ecx, VGA_SEQUENCER_REGISTERS
+ jb .loop
+
+ ;synchronous reset off
+
+ mov dword edx, VGA_SEQUENCER_INDEX
+ xor dword eax, eax
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ mov byte al, 3
+ out word dx, al
+ ret
+
+
+
+;****************************************************************************
+;* pice_set_misc_registers *************************************************
+;****************************************************************************
+;* ebx=> pointer to stored misc register
+;****************************************************************************
+section .text
+pice_set_misc_registers:
+ mov dword edx, VGA_MISC_DATA_WRITE
+ mov byte al, [ebx]
+ out word dx, al
+ ret
+
+
+
+;****************************************************************************
+;* pice_set_colormap *******************************************************
+;****************************************************************************
+;* ebx=> pointer to stored colormap
+;****************************************************************************
+section .text
+pice_set_colormap:
+ xor dword ecx, ecx
+ xor dword eax, eax
+ mov dword edx, VGA_PEL_INDEX_WRITE
+ out word dx, al
+ mov dword edx, VGA_PEL_DATA
+.loop: mov dword eax, [ebx + 4 * ecx]
+ rol dword eax, 16
+ out word dx, al
+ rol dword eax, 8
+ out word dx, al
+ rol dword eax, 8
+ out word dx, al
+ inc dword ecx
+ test byte cl, cl
+ jnz .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_screen_on **********************************************************
+;****************************************************************************
+section .text
+pice_screen_on:
+
+ ;turn on the screen
+
+ mov dword edx, VGA_SEQUENCER_INDEX
+ mov byte al, 1
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ in byte al, dx
+ and byte al, 0dfh
+ out word dx, al
+
+ ;enable video output
+
+ mov dword edx, VGA_INPUT_STATUS
+ in byte al, dx
+ mov dword edx, VGA_ATTRIBUTE_DATA_WRITE
+ mov byte al, 020h
+ out word dx, al
+ ret
+
+;****************************************************************************
+;* pice_select_write_plane *************************************************
+;****************************************************************************
+;* bl==> write mode
+;* bh==> write plane
+;****************************************************************************
+section .text
+pice_select_write_plane:
+ and dword ebx, 00f03h
+
+ ;enable set/reset = 0
+
+ mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, 1
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ xor dword eax, eax
+ out word dx, al
+
+ ;logical operation = none, rotate = 0
+
+ mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, 3
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ xor dword eax, eax
+ out word dx, al
+
+ ;select write mode
+
+ mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, 5
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ in byte al, dx
+ and byte al, 0fch
+ or byte al, bl
+ out word dx, al
+
+ ;bitmask = 0ffh
+
+ mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, 8
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ mov byte al, 0ffh
+ out word dx, al
+
+ ;select write plane
+
+ mov dword edx, VGA_SEQUENCER_INDEX
+ mov byte al, 2
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ mov byte al, bh
+ out word dx, al
+ ret
+
+
+
+;****************************************************************************
+;* pice_select_read_plane **************************************************
+;****************************************************************************
+;* bl==> read mode
+;* bh==> read plane
+;****************************************************************************
+section .text
+pice_select_read_plane:
+ and dword ebx, 00301h
+ shl byte bl, 3
+
+ ;select read mode
+
+ mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, 5
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ in byte al, dx
+ and byte al, 0f7h
+ or byte al, bl
+ out word dx, al
+
+ ;select read plane
+
+ mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, 4
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ mov byte al, bh
+ out word dx, al
+ ret
+
+
+
+;****************************************************************************
+;* pice_save_current_registers **********************************************
+;****************************************************************************
+section .text
+_pice_save_current_registers:
+ push esi
+ push edi
+ push ebx
+
+; call pice_save_current_charset
+
+.crt: mov dword ebx, pice_current_registers.crt
+ call pice_get_crt_registers
+
+.attribute: mov dword ebx, pice_current_registers.attribute
+ call pice_get_attribute_registers
+
+.graphic: mov dword ebx, pice_current_registers.graphic
+ call pice_get_graphic_registers
+
+.sequencer: mov dword ebx, pice_current_registers.sequencer
+ call pice_get_sequencer_registers
+
+.misc: mov dword ebx, pice_current_registers.misc
+ call pice_get_misc_registers
+
+.colormap: mov dword ebx, pice_current_registers.colormap
+ call pice_get_colormap
+
+ pop ebx
+ pop edi
+ pop esi
+.end: ret
+
+;****************************************************************************
+;* pice_restore_current_registers *******************************************
+;****************************************************************************
+section .text
+_pice_restore_current_registers:
+ push esi
+ push edi
+ push ebx
+
+; call pice_restore_current_charset
+
+.misc: mov dword ebx, pice_current_registers.misc
+ call pice_set_misc_registers
+
+.crt: mov dword ebx, pice_current_registers.crt
+ call pice_set_crt_registers
+
+.attribute: mov dword ebx, pice_current_registers.attribute
+ call pice_set_attribute_registers
+
+.graphic: mov dword ebx, pice_current_registers.graphic
+ call pice_set_graphic_registers
+
+.sequencer: mov dword ebx, pice_current_registers.sequencer
+ call pice_set_sequencer_registers
+
+.screen_on: call pice_screen_on
+
+.colormap: mov dword ebx, pice_current_registers.colormap
+ call pice_set_colormap
+
+ pop ebx
+ pop edi
+ pop esi
+
+.end: ret
+
+
+;****************************************************************************
+;* pice_set_mode_3_80x50*****************************************************
+;****************************************************************************
+section .text
+_pice_set_mode_3_80x50:
+ push esi
+ push edi
+ push ebx
+
+.crt: mov dword ebx, pice_mode3_80x50_registers.crt
+ call pice_set_crt_registers
+
+.attribute: mov dword ebx, pice_mode3_80x50_registers.attribute
+ call pice_set_attribute_registers
+
+.graphic: mov dword ebx, pice_mode3_80x50_registers.graphic
+ call pice_set_graphic_registers
+
+.sequencer: mov dword ebx, pice_mode3_80x50_registers.sequencer
+ call pice_set_sequencer_registers
+
+.misc: mov dword ebx, pice_mode3_80x50_registers.misc
+ call pice_set_misc_registers
+
+.screen_on: call pice_screen_on
+
+;.colormap: mov dword ebx, pice_current_registers.colormap
+; call pice_set_colormap
+
+ pop ebx
+ pop edi
+ pop esi
+
+.end: ret
+
+;****************************************************************************
+;* pice_set_mode_3_80x25*****************************************************
+;****************************************************************************
+section .text
+_pice_set_mode_3_80x25:
+ push esi
+ push edi
+ push ebx
+
+.crt: mov dword ebx, pice_mode3_80x25_registers.crt
+ call pice_set_crt_registers
+
+.attribute: mov dword ebx, pice_mode3_80x25_registers.attribute
+ call pice_set_attribute_registers
+
+.graphic: mov dword ebx, pice_mode3_80x25_registers.graphic
+ call pice_set_graphic_registers
+
+.sequencer: mov dword ebx, pice_mode3_80x25_registers.sequencer
+ call pice_set_sequencer_registers
+
+.misc: mov dword ebx, pice_mode3_80x25_registers.misc
+ call pice_set_misc_registers
+
+.screen_on: call pice_screen_on
+
+;.colormap: mov dword ebx, pice_current_registers.colormap
+; call pice_set_colormap
+
+ pop ebx
+ pop edi
+ pop esi
+
+.end: ret
+
+;****************************************************************************
+;* uninitialized data *******************************************************
+;****************************************************************************
+section .bss
+ alignb 4
+pice_charset_saved: resb 040000h
+
+
--- /dev/null
+# sample
++vga
+\\SystemRoot\symbols\pice.dbg
+\\SystemRoot\symbols\ntoskrnl.dbg
--- /dev/null
+This is some preliminary information on using PICE. I am planning to write
+a detailed manual later.
+
+BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA
+
+ PICE for Reactos is in early beta stage of development. It still has many bugs.
+
+BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA-BETA
+
+
+PICE is a kernel debugger that was ported for Reactos (the original Linux
+project by Klaus P. Gerlicher and Goran Devic may be found here:
+http://pice.sourceforge.net).
+
+Installation and use:
+
+1. PICE is loaded like a regular device driver. The only limitation - it must
+be loaded after keyboard.sys driver. You should add:
+
+ LdrLoadAutoConfigDriver( L"pice.sys" );
+
+in ntoskrnl/ldr/loader.c after the line loading keyboard driver.
+
+2. You should copy pice.cfg and ntoskrnl.sym to \SystemRoot\symbols directory
+of Reactos.
+
+3. If you want to add symbolic information you should use loader.exe to
+create .dbg file from the unstrippped version of exe or driver:
+For example:
+pice\loader\loader.exe -t ntoskrnl.nostrip.exe
+
+After that copy .dbg file to \SystemRoot\symbols and add a line to pice.cfg:
+\\SystemRoot\symbols\ntoskrnl.dbg.
+
+Pice will load the symbols during boot. For large .dbg files it may take a
+while (ntoskrnl.dbg is ~3Mb). You may find that loading time under bochs is
+quite slow, although otherwise performance should be fine.
+
+Key combination to break into debugger is CTRL-D.
+You may need to press CTRL button upon return from the debugger if you get
+"funny" symbols when you type.
+
+List of commands:
+
+gdt display current global descriptor table
+idt display current interrupt descriptor table
+x return to Reactos
+t single step one instruction
+vma displays VMAs
+h list help on commands
+page dump page directories
+proc list all processes
+dd display dword memory
+db display byte memory
+u disassemble at address
+mod displays all modules
+bpx set code breakpoint
+bl list breakpoints
+bc clear breakpoints
+ver display pICE version and state information
+hboot hard boot the system
+cpu display CPU special registers
+stack display call stack
+. unassemble at current instruction
+p single step over call
+i single step into call
+locals display local symbols
+table display loaded symbol tables
+file display source files in symbol table
+sym list known symbol information
+? evaluate an expression (global symbols only)
+src sets disassembly mode
+wc change size of code window
+wd change size of data window
+r sets or displays registers
+cls clear output window
+pci show PCI devices
+next advance EIP to next instruction
+i3here catch INT 3s
+layout sets keyboard layout
+syscall displays syscall (table)
+altkey set alternate break key
+addr show/set address contexts
+
+[CTRL/SHIFT/ALT] arrow up/down
+TAB
+
+Not implemented yet:
+
+dpd display dword physical memory
+code toggle code display
+peek peek at physical memory
+poke poke to physical memory
+phys show all mappings for linear address
+timers show all active timers
+
+TODO:
+1. Evaluation of pointers.
+2. Virtual breakpoints
+3. Unimplemented commands.
+4. Video mode switching (to debug gdi applications).
+
+
+Enjoy,
+Eugene
+
+
--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ shared.h
+
+Abstract:
+
+ shared stuff between module and loader
+
+Environment:
+
+ LINUX 2.2.X
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+
+ reactos port by:
+ Eugene Ingerman
+
+Revision History:
+
+ 13-Nov-1999: created
+ 15-Nov-2000: general cleanup of source files
+
+ 10/20/2001: porting to reactos begins
+
+Copyright notice:
+
+ This file may be distributed under the terms of the GNU Public License.
+
+--*/
+
+//#include <ntddk.h>
+//#include <winnt.h>
+
+//temporary
+#ifndef CTL_CODE
+#define CTL_CODE(Dev, Func, Meth, Acc) ( ((Dev)<<16) | ((Acc)<<14) | ((Func)<<2) | (Meth))
+// IOCTL Parameter buffering methods
+#define METHOD_BUFFERED 0
+#define METHOD_IN_DIRECT 1
+#define METHOD_OUT_DIRECT 2
+#define METHOD_NEITHER 3
+
+// IOCTL File access type
+#define FILE_ANY_ACCESS 0
+#define FILE_READ_ACCESS 1
+#define FILE_WRITE_ACCESS 2
+#endif
+
+// define custom device type
+#define PICE_DEVICE_DEBUGGER 64787
+
+#define PICE_IOCTL_LOAD CTL_CODE(PICE_DEVICE_DEBUGGER, 2049, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define PICE_IOCTL_UNLOAD CTL_CODE(PICE_DEVICE_DEBUGGER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define PICE_IOCTL_RELOAD CTL_CODE(PICE_DEVICE_DEBUGGER, 2051, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define PICE_IOCTL_BREAK CTL_CODE(PICE_DEVICE_DEBUGGER, 2052, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define PICE_IOCTL_STATUS CTL_CODE(PICE_DEVICE_DEBUGGER, 2053, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+
+typedef struct _DEBUGGER_STATUS_BLOCK
+{
+ char filename[256];
+}DEBUGGER_STATUS_BLOCK,*PDEBUGGER_STATUS_BLOCK;
+
+#define MAGIC_ULONG( ch0, ch1, ch2, ch3 ) \
+ ( (ULONG)(UCHAR)(ch0) | \
+ ( (ULONG)(UCHAR)(ch1) << 8 ) | \
+ ( (ULONG)(UCHAR)(ch2) << 16 ) | \
+ ( (ULONG)(UCHAR)(ch3) << 24 ) )
+
+#define PICE_MAGIC MAGIC_ULONG('P','I','C','E')
+
+#define DEBUG_MODULE_NAME_LEN 32
+typedef struct _PICE_SYMBOLFILE_HEADER
+{
+ ULONG magic;
+ WCHAR name[DEBUG_MODULE_NAME_LEN];
+ ULONG ulOffsetToHeaders,ulSizeOfHeader;
+ ULONG ulOffsetToGlobals,ulSizeOfGlobals;
+ ULONG ulOffsetToGlobalsStrings,ulSizeOfGlobalsStrings;
+ ULONG ulOffsetToStabs,ulSizeOfStabs;
+ ULONG ulOffsetToStabsStrings,ulSizeOfStabsStrings;
+ ULONG ulOffsetToSrcFiles,ulNumberOfSrcFiles;
+}PICE_SYMBOLFILE_HEADER;
+
+typedef struct _STAB_ENTRY
+{
+ unsigned long n_strx;
+ unsigned char n_type;
+ unsigned char n_other;
+ unsigned short n_desc;
+ unsigned long n_value;
+}STAB_ENTRY,*PSTAB_ENTRY;
+
+typedef struct _PICE_SYMBOLFILE_SOURCE
+{
+ char filename[256];
+ ULONG ulOffsetToNext;
+}PICE_SYMBOLFILE_SOURCE;
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// serial stuff
+typedef struct _SERIAL_PACKET_HEADER
+{
+ ULONG packet_size;
+ ULONG packet_header_chksum;
+ ULONG packet_chksum;
+}SERIAL_PACKET_HEADER,*PSERIAL_PACKET_HEADER;
+
+typedef struct _SERIAL_PACKET
+{
+ SERIAL_PACKET_HEADER header;
+ UCHAR data[1];
+}SERIAL_PACKET,*PSERIAL_PACKET;
+
+#define ACK (0)
+
+typedef enum _ECOLORS
+{
+ BLACK = 0,
+ BLUE,
+ GREEN,
+ TURK,
+ RED,
+ VIOLET,
+ BROWN,
+ LTGRAY,
+ GRAY,
+ LTBLUE,
+ LT_GREEN,
+ LTTURK,
+ LTRED,
+ LTVIOLET,
+ YELLOW,
+ WHITE
+}ECOLORS;
+
+typedef struct _SERIAL_DATA_PACKET
+{
+ UCHAR type;
+ UCHAR data[1];
+}SERIAL_DATA_PACKET,*PSERIAL_DATA_PACKET;
+
+#define PACKET_TYPE_CLRLINE (0)
+typedef struct _SERIAL_DATA_PACKET_CLRLINE
+{
+ UCHAR type;
+ ECOLORS fgcol,bkcol;
+ UCHAR line;
+}SERIAL_DATA_PACKET_CLRLINE,*PSERIAL_DATA_PACKET_CLRLINE;
+
+#define PACKET_TYPE_PRINT (1)
+typedef struct _SERIAL_DATA_PACKET_PRINT
+{
+ UCHAR type;
+ UCHAR x;
+ UCHAR y;
+ ECOLORS fgcol,bkcol;
+ UCHAR string[1];
+}SERIAL_DATA_PACKET_PRINT,*PSERIAL_DATA_PACKET_PRINT;
+
+#define PACKET_TYPE_CONNECT (2)
+typedef struct _SERIAL_DATA_PACKET_CONNECT
+{
+ UCHAR type;
+ UCHAR xsize,ysize;
+}SERIAL_DATA_PACKET_CONNECT,*PSERIAL_DATA_PACKET_CONNECT;
+
+#define PACKET_TYPE_CURSOR (3)
+typedef struct _SERIAL_DATA_PACKET_CURSOR
+{
+ UCHAR type;
+ UCHAR state,x,y;
+}SERIAL_DATA_PACKET_CURSOR,*PSERIAL_DATA_PACKET_CURSOR;
+
+#define PACKET_TYPE_INVERTLINE (4)
+typedef struct _SERIAL_DATA_PACKET_INVERTLINE
+{
+ UCHAR type;
+ UCHAR line;
+}SERIAL_DATA_PACKET_INVERTLINE,*PSERIAL_DATA_PACKET_INVERTLINE;
+
+#define PACKET_TYPE_POLL (5)
+typedef struct _SERIAL_DATA_PACKET_POLL
+{
+ UCHAR type;
+ USHORT major_version,minor_version,build_number;
+}SERIAL_DATA_PACKET_POLL,*PSERIAL_DATA_PACKET_POLL;
+
+// END of serial stuff
+///////////////////////////////////////////////////////////////////////////////////
+
+
+// EOF
--- /dev/null
+/*
+ * pnpdump - PnP BIOS information dumper
+ */
+
+#include <windows.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <conio.h>
+
+#include <ntddk.h>
+
+#include <pshpack1.h>
+
+typedef struct _CM_PNP_BIOS_DEVICE_NODE
+{
+ USHORT Size;
+ UCHAR Node;
+ ULONG ProductId;
+ UCHAR DeviceType[3];
+ USHORT DeviceAttributes;
+} CM_PNP_BIOS_DEVICE_NODE,*PCM_PNP_BIOS_DEVICE_NODE;
+
+typedef struct _CM_PNP_BIOS_INSTALLATION_CHECK
+{
+ UCHAR Signature[4]; // $PnP (ascii)
+ UCHAR Revision;
+ UCHAR Length;
+ USHORT ControlField;
+ UCHAR Checksum;
+ ULONG EventFlagAddress; // Physical address
+ USHORT RealModeEntryOffset;
+ USHORT RealModeEntrySegment;
+ USHORT ProtectedModeEntryOffset;
+ ULONG ProtectedModeCodeBaseAddress;
+ ULONG OemDeviceId;
+ USHORT RealModeDataBaseAddress;
+ ULONG ProtectedModeDataBaseAddress;
+} CM_PNP_BIOS_INSTALLATION_CHECK, *PCM_PNP_BIOS_INSTALLATION_CHECK;
+
+#include <poppack.h>
+
+typedef struct _PNP_ID_NAME_
+{
+ char *PnpId;
+ char *DeviceName;
+} PNP_ID_NAME, *PPNP_ID_NAME;
+
+
+static char Hex[] = "0123456789ABCDEF";
+
+static PNP_ID_NAME PnpName[] =
+{
+ /* Interrupt Controllers */
+ {"PNP0000", "AT Interrupt Controller"},
+ {"PNP0001", "EISA Interrupt Controller"},
+ {"PNP0002", "MCA Interrupt Controller"},
+ {"PNP0003", "APIC"},
+ {"PNP0004", "Cyrix SLiC MP Interrupt Controller"},
+
+ /* Timers */
+ {"PNP0100", "AT Timer"},
+ {"PNP0101", "EISA Timer"},
+ {"PNP0102", "MCA Timer"},
+
+ /* DMA Controllers */
+ {"PNP0200", "AT DMA Controller"},
+ {"PNP0201", "EISA DMA Controller"},
+ {"PNP0202", "MCA DMA Controller"},
+
+ /* Keyboards */
+ {"PNP0300", "IBM PC/XT Keyboard (83 keys)"},
+ {"PNP0301", "IBM PC/AT Keyboard (86 keys)"},
+ {"PNP0302", "IBM PC/XT Keyboard (84 keys)"},
+ {"PNP0303", "IBM Enhanced (101/102 keys)"},
+ {"PNP0304", "Olivetti Keyboard (83 keys)"},
+ {"PNP0305", "Olivetti Keyboard (102 keys)"},
+ {"PNP0306", "Olivetti Keyboard (86 keys)"},
+ {"PNP0307", "Microsoft Windows(R) Keyboard"},
+ {"PNP0308", "General Input Device Emulation Interface (GIDEI) legacy"},
+ {"PNP0309", "Olivetti Keyboard (A101/102 key)"},
+ {"PNP030A", "AT&T 302 keyboard"},
+ {"PNP030B", "Reserved by Microsoft"},
+ {"PNP0320", "Japanese 101-key keyboard"},
+ {"PNP0321", "Japanese AX keyboard"},
+ {"PNP0322", "Japanese 106-key keyboard A01"},
+ {"PNP0323", "Japanese 106-key keyboard 002/003"},
+ {"PNP0324", "Japanese 106-key keyboard 001"},
+ {"PNP0325", "Japanese Toshiba Desktop keyboard"},
+ {"PNP0326", "Japanese Toshiba Laptop keyboard"},
+ {"PNP0327", "Japanese Toshiba Notebook keyboard"},
+ {"PNP0340", "Korean 84-key keyboard"},
+ {"PNP0341", "Korean 86-key keyboard"},
+ {"PNP0342", "Korean Enhanced keyboard"},
+ {"PNP0343", "Korean Enhanced keyboard 101b"},
+ {"PNP0343", "Korean Enhanced keyboard 101c"},
+ {"PNP0344", "Korean Enhanced keyboard 103"},
+
+ /* Parallel Ports */
+ {"PNP0400", "Standard LPT printer port"},
+ {"PNP0401", "ECP printer port"},
+
+ /* Serial Ports */
+ {"PNP0500", "Standard PC COM port"},
+ {"PNP0501", "16550A-compatible COM port"},
+ {"PNP0510", "Generic IRDA-compatible port"},
+
+ /* Harddisk Controllers */
+ {"PNP0600", "Generic ESDI/ATA/IDE harddisk controller"},
+ {"PNP0601", "Plus Hardcard II"},
+ {"PNP0602", "Plus Hardcard IIXL/EZ"},
+ {"PNP0603", "Generic IDE supporting Microsoft Device Bay Specification"},
+
+ /* Floppy Controllers */
+ {"PNP0700", "PC standard floppy disk controller"},
+ {"PNP0701", "Standard floppy controller supporting MS Device Bay Specification"},
+
+ /* obsolete devices */
+ {"PNP0800", "Microsoft Sound System compatible device"},
+
+ /* Display Adapters */
+ {"PNP0900", "VGA Compatible"},
+ {"PNP0901", "Video Seven VRAM/VRAM II/1024i"},
+ {"PNP0902", "8514/A Compatible"},
+ {"PNP0903", "Trident VGA"},
+ {"PNP0904", "Cirrus Logic Laptop VGA"},
+ {"PNP0905", "Cirrus Logic VGA"},
+ {"PNP0906", "Tseng ET4000"},
+ {"PNP0907", "Western Digital VGA"},
+ {"PNP0908", "Western Digital Laptop VGA"},
+ {"PNP0909", "S3 Inc. 911/924"},
+ {"PNP090A", "ATI Ultra Pro/Plus (Mach 32)"},
+ {"PNP090B", "ATI Ultra (Mach 8)"},
+ {"PNP090C", "XGA Compatible"},
+ {"PNP090D", "ATI VGA Wonder"},
+ {"PNP090E", "Weitek P9000 Graphics Adapter"},
+ {"PNP090F", "Oak Technology VGA"},
+ {"PNP0910", "Compaq QVision"},
+ {"PNP0911", "XGA/2"},
+ {"PNP0912", "Tseng Labs W32/W32i/W32p"},
+ {"PNP0913", "S3 Inc. 801/928/964"},
+ {"PNP0914", "Cirrus Logic 5429/5434 (memory mapped)"},
+ {"PNP0915", "Compaq Advanced VGA (AVGA)"},
+ {"PNP0916", "ATI Ultra Pro Turbo (Mach64)"},
+ {"PNP0917", "Reserved by Microsoft"},
+ {"PNP0918", "Matrox MGA"},
+ {"PNP0919", "Compaq QVision 2000"},
+ {"PNP091A", "Tseng W128"},
+ {"PNP0930", "Chips & Technologies Super VGA"},
+ {"PNP0931", "Chips & Technologies Accelerator"},
+ {"PNP0940", "NCR 77c22e Super VGA"},
+ {"PNP0941", "NCR 77c32blt"},
+ {"PNP09FF", "Plug and Play Monitors (VESA DDC)"},
+
+ /* Peripheral Buses */
+ {"PNP0A00", "ISA Bus"},
+ {"PNP0A01", "EISA Bus"},
+ {"PNP0A02", "MCA Bus"},
+ {"PNP0A03", "PCI Bus"},
+ {"PNP0A04", "VESA/VL Bus"},
+ {"PNP0A05", "Generic ACPI Bus"},
+ {"PNP0A06", "Generic ACPI Extended-IO Bus (EIO bus)"},
+
+ /* System devices */
+ {"PNP0800", "AT-style speaker sound"},
+ {"PNP0B00", "AT Real-Time Clock"},
+ {"PNP0C00", "Plug and Play BIOS (only created by the root enumerator)"},
+ {"PNP0C01", "System Board"},
+ {"PNP0C02", "General Plug and Play motherboard registers."},
+ {"PNP0C03", "Plug and Play BIOS Event Notification Interrupt"},
+ {"PNP0C04", "Math Coprocessor"},
+ {"PNP0C05", "APM BIOS (Version independent)"},
+ {"PNP0C06", "Reserved for identification of early Plug and Play BIOS implementation"},
+ {"PNP0C07", "Reserved for identification of early Plug and Play BIOS implementation"},
+ {"PNP0C08", "ACPI system board hardware"},
+ {"PNP0C09", "ACPI Embedded Controller"},
+ {"PNP0C0A", "ACPI Control Method Battery"},
+ {"PNP0C0B", "ACPI Fan"},
+ {"PNP0C0C", "ACPI power button device"},
+ {"PNP0C0D", "ACPI lid device"},
+ {"PNP0C0E", "ACPI sleep button device"},
+ {"PNP0C0F", "PCI interrupt link device"},
+ {"PNP0C10", "ACPI system indicator device"},
+ {"PNP0C11", "ACPI thermal zone"},
+ {"PNP0C12", "Device Bay Controller"},
+
+ /* PCMCIA Controllers */
+ {"PNP0E00", "Intel 82365-Compatible PCMCIA Controller"},
+ {"PNP0E01", "Cirrus Logic CL-PD6720 PCMCIA Controller"},
+ {"PNP0E02", "VLSI VL82C146 PCMCIA Controller"},
+ {"PNP0E03", "Intel 82365-compatible CardBus controller"},
+
+ /* Mice */
+ {"PNP0F00", "Microsoft Bus Mouse"},
+ {"PNP0F01", "Microsoft Serial Mouse"},
+ {"PNP0F02", "Microsoft InPort Mouse"},
+ {"PNP0F03", "Microsoft PS/2-style Mouse"},
+ {"PNP0F04", "Mouse Systems Mouse"},
+ {"PNP0F05", "Mouse Systems 3-Button Mouse (COM2)"},
+ {"PNP0F06", "Genius Mouse (COM1)"},
+ {"PNP0F07", "Genius Mouse (COM2)"},
+ {"PNP0F08", "Logitech Serial Mouse"},
+ {"PNP0F09", "Microsoft BallPoint Serial Mouse"},
+ {"PNP0F0A", "Microsoft Plug and Play Mouse"},
+ {"PNP0F0B", "Microsoft Plug and Play BallPoint Mouse"},
+ {"PNP0F0C", "Microsoft-compatible Serial Mouse"},
+ {"PNP0F0D", "Microsoft-compatible InPort-compatible Mouse"},
+ {"PNP0F0E", "Microsoft-compatible PS/2-style Mouse"},
+ {"PNP0F0F", "Microsoft-compatible Serial BallPoint-compatible Mouse"},
+ {"PNP0F10", "Texas Instruments QuickPort Mouse"},
+ {"PNP0F11", "Microsoft-compatible Bus Mouse"},
+ {"PNP0F12", "Logitech PS/2-style Mouse"},
+ {"PNP0F13", "PS/2 Port for PS/2-style Mice"},
+ {"PNP0F14", "Microsoft Kids Mouse"},
+ {"PNP0F15", "Logitech bus mouse"},
+ {"PNP0F16", "Logitech SWIFT device"},
+ {"PNP0F17", "Logitech-compatible serial mouse"},
+ {"PNP0F18", "Logitech-compatible bus mouse"},
+ {"PNP0F19", "Logitech-compatible PS/2-style Mouse"},
+ {"PNP0F1A", "Logitech-compatible SWIFT Device"},
+ {"PNP0F1B", "HP Omnibook Mouse"},
+ {"PNP0F1C", "Compaq LTE Trackball PS/2-style Mouse"},
+ {"PNP0F1D", "Compaq LTE Trackball Serial Mouse"},
+ {"PNP0F1E", "Microsoft Kids Trackball Mouse"},
+ {"PNP0F1F", "Reserved by Microsoft Input Device Group"},
+ {"PNP0F20", "Reserved by Microsoft Input Device Group"},
+ {"PNP0F21", "Reserved by Microsoft Input Device Group"},
+ {"PNP0F22", "Reserved by Microsoft Input Device Group"},
+ {"PNP0F23", "Reserved by Microsoft Input Device Group"},
+ {"PNP0FFF", "Reserved by Microsoft Systems"},
+
+ /* List Terminator */
+ {NULL, NULL}
+};
+
+
+/* FUNCTIONS ****************************************************************/
+
+static char *
+GetDeviceName(char *PnpId)
+{
+ PPNP_ID_NAME IdName;
+
+ IdName = PnpName;
+ while (IdName->PnpId != NULL)
+ {
+ if (!strcmp(IdName->PnpId, PnpId))
+ return IdName->DeviceName;
+
+ IdName++;
+ }
+
+ return "Unknown Device";
+}
+
+
+LONG
+GetPnpKey(PHKEY PnpKey)
+{
+ LONG lError;
+ char szBuffer[80];
+ HKEY hAdapterKey;
+ HKEY hBusKey;
+ DWORD dwBus;
+ DWORD dwType;
+ DWORD dwSize;
+
+ *PnpKey = 0;
+
+ lError = RegOpenKey(HKEY_LOCAL_MACHINE,
+ "HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter",
+ &hAdapterKey);
+ if (lError != ERROR_SUCCESS)
+ return 0;
+
+ /* Enumerate buses */
+ for (dwBus = 0; ; dwBus++)
+ {
+ sprintf(szBuffer, "%lu", dwBus);
+
+ lError = RegOpenKey(hAdapterKey,
+ szBuffer,
+ &hBusKey);
+ if (lError != ERROR_SUCCESS)
+ {
+ RegCloseKey(hAdapterKey);
+ return lError;
+ }
+
+ dwSize = 80;
+ lError = RegQueryValueEx(hBusKey,
+ "Identifier",
+ NULL,
+ &dwType,
+ (LPBYTE)szBuffer,
+ &dwSize);
+ if (lError != ERROR_SUCCESS)
+ {
+ RegCloseKey(hBusKey);
+ RegCloseKey(hAdapterKey);
+ return lError;
+ }
+
+ if (dwType == REG_SZ && stricmp(szBuffer, "pnp bios") == 0)
+ {
+ *PnpKey = hBusKey;
+ RegCloseKey(hAdapterKey);
+ return ERROR_SUCCESS;
+ }
+
+ RegCloseKey(hBusKey);
+ }
+
+ return 1;
+}
+
+
+static VOID
+PnpDecodeIrq(unsigned char *Ptr)
+{
+ USHORT IrqMask;
+ int i;
+
+ IrqMask = *Ptr;
+ Ptr++;
+ IrqMask |= (*Ptr << 8);
+
+ printf(" IRQs:");
+
+ for (i = 0; i < 16; i++)
+ {
+ if (IrqMask & (1 << i))
+ {
+ printf(" %u", i);
+ }
+ }
+
+ printf("\n");
+}
+
+
+static VOID
+PnpDecodeDma(unsigned char *Ptr)
+{
+ unsigned char DmaChannel;
+ unsigned char DmaStatus;
+ int i;
+
+ DmaChannel = *Ptr;
+ Ptr++;
+ DmaStatus = *Ptr;
+
+ printf(" DMAs:");
+
+ for (i = 0; i < 8; i++)
+ {
+ if (DmaChannel & (1 << i))
+ {
+ printf(" %u", i);
+ }
+ }
+
+ printf("\n");
+}
+
+
+static VOID
+PnpDecodeIoPort(unsigned char *Ptr)
+{
+ USHORT MinBase;
+ USHORT MaxBase;
+ UCHAR Align;
+ UCHAR Length;
+
+ // Info = *Ptr;
+ Ptr++;
+ MinBase = *Ptr;
+ Ptr++;
+ MinBase += (*Ptr << 8);
+ Ptr++;
+ MaxBase = *Ptr;
+ Ptr++;
+ MaxBase += (*Ptr << 8);
+ Ptr++;
+ Align = *Ptr;
+ Ptr++;
+ Length = *Ptr;
+
+ printf(" I/O Port descriptor\n");
+ printf(" MinBase 0x%x MaxBase 0x%x Align %u Length %u\n",
+ MinBase, MaxBase, Align, Length);
+}
+
+
+static VOID
+PnpDecodeFixedIoPort(unsigned char *Ptr)
+{
+ USHORT IoPort;
+ UCHAR Length;
+
+ IoPort = *Ptr;
+ Ptr++;
+ IoPort += (*Ptr << 8);
+ Ptr++;
+ Length = *Ptr;
+
+ printf(" Fixed I/O Port descriptor\n");
+ printf(" PortBase 0x%hx Length 0x%x\n",
+ IoPort, Length);
+
+#if 0
+ if (Length == 1)
+ {
+ printf(" Fixed location I/O Port descriptor: 0x%x\n",
+ IoPort);
+ }
+ else
+ {
+ printf(" Fixed location I/O Port descriptor: 0x%x - 0x%x\n",
+ IoPort,
+ IoPort + Length - 1);
+ }
+#endif
+}
+
+
+static VOID
+PnpDecodeMemory16(unsigned char *Ptr)
+{
+ UCHAR Info;
+ USHORT MinBase;
+ USHORT MaxBase;
+ USHORT Align;
+ USHORT Length;
+
+ Info = *Ptr;
+ Ptr++;
+
+ MinBase = *Ptr;
+ Ptr++;
+ MinBase += (*Ptr << 8);
+ Ptr++;
+
+ MaxBase = *Ptr;
+ Ptr++;
+ MaxBase += (*Ptr << 8);
+ Ptr++;
+
+ Align = *Ptr;
+ Ptr++;
+ Align += (*Ptr << 8);
+ Ptr++;
+
+ Length = *Ptr;
+ Ptr++;
+ Length += (*Ptr << 8);
+
+ printf(" 16-Bit memory range descriptor\n");
+ printf(" MinBase 0x%hx MaxBase 0x%hx Align 0x%hx Length 0x%hx Flags 0x%02x\n",
+ MinBase, MaxBase, Align,Length, Info);
+}
+
+
+static VOID
+PnpDecodeMemory32(unsigned char *Ptr)
+{
+ UCHAR Info;
+ ULONG MinBase;
+ ULONG MaxBase;
+ ULONG Align;
+ ULONG Length;
+
+ Info = *Ptr;
+ Ptr++;
+
+ MinBase = *Ptr;
+ Ptr++;
+ MinBase += (*Ptr << 8);
+ Ptr++;
+ MinBase += (*Ptr << 16);
+ Ptr++;
+ MinBase += (*Ptr << 24);
+ Ptr++;
+
+ MaxBase = *Ptr;
+ Ptr++;
+ MaxBase += (*Ptr << 8);
+ Ptr++;
+ MaxBase += (*Ptr << 16);
+ Ptr++;
+ MaxBase += (*Ptr << 24);
+ Ptr++;
+
+ Align = *Ptr;
+ Ptr++;
+ Align += (*Ptr << 8);
+ Ptr++;
+ Align += (*Ptr << 16);
+ Ptr++;
+ Align += (*Ptr << 24);
+ Ptr++;
+
+ Length = *Ptr;
+ Ptr++;
+ Length += (*Ptr << 8);
+ Ptr++;
+ Length += (*Ptr << 16);
+ Ptr++;
+ Length += (*Ptr << 24);
+
+ printf(" 32-Bit memory range descriptor\n");
+ printf(" MinBase 0x%lx MaxBase 0x%lx Align 0x%lx Length 0x%lx Flags 0x%02x\n",
+ MinBase, MaxBase, Align,Length, Info);
+}
+
+
+static VOID
+PnpDecodeFixedMemory(unsigned char *Ptr)
+{
+ UCHAR Info;
+ ULONG Base;
+ ULONG Length;
+
+ Info = *Ptr;
+ Ptr++;
+
+ Base = *Ptr;
+ Ptr++;
+ Base += (*Ptr << 8);
+ Ptr++;
+ Base += (*Ptr << 16);
+ Ptr++;
+ Base += (*Ptr << 24);
+ Ptr++;
+
+ Length = *Ptr;
+ Ptr++;
+ Length += (*Ptr << 8);
+ Ptr++;
+ Length += (*Ptr << 16);
+ Ptr++;
+ Length += (*Ptr << 24);
+
+ printf(" 32-Bit fixed location memory range descriptor\n");
+ printf(" Base 0x%lx Length 0x%lx Flags 0x%02x\n",
+ Base, Length, Info);
+}
+
+
+void PrintDeviceData (PCM_PNP_BIOS_DEVICE_NODE DeviceNode)
+{
+ char PnpId[8];
+ unsigned char *Ptr;
+ unsigned int TagSize;
+ unsigned int TagType;
+
+ unsigned char Id[4];
+
+ printf ("Node: %x Size %hu (0x%hx)\n",
+ DeviceNode->Node,
+ DeviceNode->Size,
+ DeviceNode->Size);
+
+ memcpy(Id, &DeviceNode->ProductId, 4);
+
+ PnpId[0] = ((Id[0] >> 2) & 0x1F) + 0x40;
+ PnpId[1] = ((Id[0] << 3) & 0x18) +
+ ((Id[1] >> 5) & 0x07) + 0x40;
+ PnpId[2] = (Id[1] & 0x1F) + 0x40;
+
+ PnpId[3] = Hex[(Id[2] >> 4) & 0xF];
+ PnpId[4] = Hex[Id[2] & 0x0F];
+
+ PnpId[5] = Hex[(Id[3] >> 4) & 0x0F];
+ PnpId[6] = Hex[Id[3] & 0x0F];
+ PnpId[7] = 0;
+
+ printf(" '%s' (%s)\n",
+ PnpId, GetDeviceName(PnpId));
+
+ if (DeviceNode->Size > sizeof(CM_PNP_BIOS_DEVICE_NODE))
+ {
+ Ptr = (unsigned char *)(DeviceNode + 1);
+ while (TRUE)
+ {
+ if (*Ptr & 0x80)
+ {
+ TagType = *Ptr & 0x7F;
+ Ptr++;
+ TagSize = *Ptr;
+ Ptr++;
+ TagSize += (*Ptr << 16);
+ Ptr++;
+
+
+ switch (TagType)
+ {
+ case 1:
+ PnpDecodeMemory16(Ptr);
+ break;
+
+ case 5:
+ PnpDecodeMemory32(Ptr);
+ break;
+
+ case 6:
+ PnpDecodeFixedMemory(Ptr);
+ break;
+
+ default:
+ printf(" Large tag: type %u size %u\n",
+ TagType,
+ TagSize);
+ break;
+ }
+ }
+ else
+ {
+ TagType = (*Ptr >> 3) & 0x0F;
+ TagSize = *Ptr & 0x07;
+ Ptr++;
+
+ switch (TagType)
+ {
+ case 2:
+ printf(" Logical device ID\n");
+ break;
+
+ case 3:
+ printf(" Compatible device ID\n");
+ break;
+
+ case 4:
+ PnpDecodeIrq(Ptr);
+ break;
+
+ case 5:
+ PnpDecodeDma(Ptr);
+ break;
+
+ case 8:
+ PnpDecodeIoPort(Ptr);
+ break;
+
+ case 9:
+ PnpDecodeFixedIoPort(Ptr);
+ break;
+
+ case 0x0F: /* end tag */
+ break;
+
+ default:
+ printf(" Small tag: type %u size %u\n",
+ TagType,
+ TagSize);
+ break;
+ }
+
+ /* end tag */
+ if (TagType == 0x0F)
+ break;
+ }
+
+ Ptr = Ptr + TagSize;
+ }
+ }
+}
+
+
+int main (int argc, char *argv[])
+{
+ LONG lError;
+ HKEY hPnpKey;
+ DWORD dwType;
+ DWORD dwSize;
+ BOOL Ask;
+ PCM_FULL_RESOURCE_DESCRIPTOR lpBuffer;
+ PCM_PNP_BIOS_INSTALLATION_CHECK lpPnpInst;
+ PCM_PNP_BIOS_DEVICE_NODE lpDevNode;
+ DWORD dwDataSize;
+ DWORD dwResourceSize;
+
+ hPnpKey = 0;
+
+ Ask = TRUE;
+ if (argc >1 && (!strcmp(argv[1],"/S") || !strcmp(argv[1],"/s")))
+ {
+ Ask = FALSE;
+ }
+
+ if (argc >1 && !strcmp(argv[1],"/?"))
+ {
+ printf("This utility prints the PnP-nodes from the registry\n");
+ printf("\"/s\" prevents the \"Press any key\"\n\n");
+ return 0;
+ }
+
+ lError = GetPnpKey(&hPnpKey);
+ if (lError != ERROR_SUCCESS)
+ {
+ printf("Failed to get PnP-BIOS key\n");
+ return 0;
+ }
+
+ if (hPnpKey != 0)
+ {
+ printf("Found PnP-BIOS key\n");
+ }
+
+ /* Allocate buffer */
+ dwSize = 2048;
+ lpBuffer = malloc(dwSize);
+ if (lpBuffer == NULL)
+ {
+ printf("Error: malloc() failed\n");
+ RegCloseKey(hPnpKey);
+ return 0;
+ }
+
+ do
+ {
+ lError = RegQueryValueEx(hPnpKey,
+ "Configuration Data",
+ NULL,
+ &dwType,
+ (LPBYTE)lpBuffer,
+ &dwSize);
+ if (lError == ERROR_MORE_DATA)
+ {
+ lpBuffer = realloc(lpBuffer, dwSize);
+ if (lpBuffer == NULL)
+ {
+ printf("Error: realloc() of %u bytes failed\n", (unsigned) dwSize);
+ RegCloseKey(hPnpKey);
+ return 0;
+ }
+ }
+ }
+ while (lError == ERROR_MORE_DATA);
+ if (lError != ERROR_SUCCESS)
+ {
+ printf("Failed to read 'Configuration Data' value\n");
+ free(lpBuffer);
+ RegCloseKey(hPnpKey);
+ return 0;
+ }
+
+// printf ("Data size: %lu\n", dwSize);
+
+ RegCloseKey(hPnpKey);
+
+// printf("Resource count %lu\n", lpBuffer->PartialResourceList.Count);
+
+ if (lpBuffer->PartialResourceList.Count == 0)
+ {
+ printf("Invalid resource count!\n");
+ free(lpBuffer);
+ return 0;
+ }
+
+// printf("lpBuffer %p\n", lpBuffer);
+
+ dwResourceSize = lpBuffer->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize;
+// printf("ResourceSize: %lu\n", dwResourceSize);
+
+ lpPnpInst = (PCM_PNP_BIOS_INSTALLATION_CHECK)
+ ((ULONG_PTR)(&lpBuffer->PartialResourceList.PartialDescriptors[0]) +
+ sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
+
+// printf("lpPnpInst %p\n", lpPnpInst);
+
+ printf("Signature '%.4s'\n", lpPnpInst->Signature);
+ if (strncmp((PCHAR)lpPnpInst->Signature, "$PnP", 4))
+ {
+ printf("Error: Invalid PnP signature\n");
+ free(lpBuffer);
+ return 0;
+ }
+
+// printf("InstCheck length: %lu\n", lpPnpInst->Length);
+
+ dwDataSize = sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
+ lpDevNode = (PCM_PNP_BIOS_DEVICE_NODE)((DWORD)lpPnpInst + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
+
+ if (lpDevNode->Size == 0)
+ {
+ printf("Error: Device node size is zero!\n");
+ return 0;
+ }
+
+#if 0
+ printf("Node: %x Size %hu (0x%hx)\n",
+ lpDevNode->Node,
+ lpDevNode->Size,
+ lpDevNode->Size);
+
+ printf("Done.\n");
+return 0;
+#endif
+
+
+ while (dwDataSize < dwResourceSize)
+ {
+ if (lpDevNode->Size == 0)
+ break;
+
+ printf("Node: %x Size %hu (0x%hx)\n",
+ lpDevNode->Node,
+ lpDevNode->Size,
+ lpDevNode->Size);
+
+ dwDataSize += lpDevNode->Size;
+ lpDevNode = (PCM_PNP_BIOS_DEVICE_NODE)((DWORD)lpDevNode + lpDevNode->Size);
+ }
+
+ if (Ask)
+ {
+ printf("\n Press any key...\n");
+ getch();
+ }
+ else
+ {
+ printf("\n");
+ }
+
+ dwDataSize = sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
+ lpDevNode = (PCM_PNP_BIOS_DEVICE_NODE)((DWORD)lpPnpInst + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
+
+ while (dwDataSize < dwResourceSize)
+ {
+ if (lpDevNode->Size == 0)
+ break;
+
+ PrintDeviceData(lpDevNode);
+
+ if (Ask)
+ {
+ printf("\n Press any key...\n");
+ getch();
+ }
+ else
+ {
+ printf("\n");
+ }
+
+ dwDataSize += lpDevNode->Size;
+ lpDevNode = (PCM_PNP_BIOS_DEVICE_NODE)((DWORD)lpDevNode + lpDevNode->Size);
+ }
+
+ free(lpBuffer);
+
+ return 0;
+}
+
+/* EOF */
--- /dev/null
+/*
+ *
+ * ReactOS ps - process list console viewer
+ *
+ * ps.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ Thanks to Filip Navara patch for fixing the Xp crash problem.
+*/
+
+#define NTOS_MODE_USER
+#define WIN32_NO_STATUS
+#include <windows.h>
+#include <ndk/ntndk.h>
+
+typedef struct _SYSTEM_THREADS
+ {
+ LARGE_INTEGER KernelTime;
+ LARGE_INTEGER UserTime;
+ LARGE_INTEGER CreateTime;
+ ULONG WaitTime;
+ PVOID StartAddress;
+ CLIENT_ID ClientId;
+ KPRIORITY Priority;
+ LONG BasePriority;
+ ULONG ContextSwitches;
+ ULONG ThreadState;
+ ULONG WaitReason;
+ } SYSTEM_THREADS, *PSYSTEM_THREADS;
+
+ typedef struct _SYSTEM_PROCESSES
+ {
+ ULONG NextEntryOffset;
+ ULONG NumberOfThreads;
+ LARGE_INTEGER SpareLi1;
+ LARGE_INTEGER SpareLi2;
+ LARGE_INTEGER SpareLi3;
+ LARGE_INTEGER CreateTime;
+ LARGE_INTEGER UserTime;
+ LARGE_INTEGER KernelTime;
+ UNICODE_STRING ImageName;
+ KPRIORITY BasePriority;
+ HANDLE UniqueProcessId;
+ HANDLE InheritedFromUniqueProcessId;
+ ULONG HandleCount;
+ ULONG SessionId;
+ ULONG PageDirectoryFrame;
+
+ /*
+ * This part corresponds to VM_COUNTERS_EX.
+ * NOTE: *NOT* THE SAME AS VM_COUNTERS!
+ */
+ ULONG PeakVirtualSize;
+ ULONG VirtualSize;
+ ULONG PageFaultCount;
+ ULONG PeakWorkingSetSize;
+ ULONG WorkingSetSize;
+ ULONG QuotaPeakPagedPoolUsage;
+ ULONG QuotaPagedPoolUsage;
+ ULONG QuotaPeakNonPagedPoolUsage;
+ ULONG QuotaNonPagedPoolUsage;
+ ULONG PagefileUsage;
+ ULONG PeakPagefileUsage;
+ ULONG PrivateUsage;
+
+ /* This part corresponds to IO_COUNTERS */
+ LARGE_INTEGER ReadOperationCount;
+ LARGE_INTEGER WriteOperationCount;
+ LARGE_INTEGER OtherOperationCount;
+ LARGE_INTEGER ReadTransferCount;
+ LARGE_INTEGER WriteTransferCount;
+ LARGE_INTEGER OtherTransferCount;
+
+ SYSTEM_THREADS Threads [1];
+ } SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
+
+
+// x00000000 00000000 000:00:00 000:00:00 ()
+static char title[] = "P PID PPID KTime UTime NAME\n";
+static char title1[] = "t TID KTime UTime State WaitResson\n";
+static char title2[] = "w PID Hwnd WndStile TID WndName\n";
+
+
+struct status {
+ DWORD state;
+ const char desc[10];
+} thread_stat[8 + 1] = {
+ {0, "Init "},
+ {1, "Ready "},
+ {2, "Running "},
+ {3, "Standby "},
+ {4, "Terminated"},
+ {5, "Wait "},
+ {6, "Transition"},
+ {7, "Unknown "},
+ {-1," ? "}
+};
+
+struct waitres {
+ DWORD state;
+ char desc[17];
+} waitreason[35 + 1] = {
+ {0, "Executive "},
+ {1, "FreePage "},
+ {2, "PageIn "},
+ {3, "PoolAllocation "},
+ {4, "DelayExecution "},
+ {5, "Suspended "},
+ {6, "UserRequest "},
+ {7, "WrExecutive "},
+ {8, "WrFreePage "},
+ {9, "WrPageIn "},
+ {10,"WrPoolAllocation "},
+ {11,"WrDelayExecution "},
+ {12,"WrSuspended "},
+ {13,"WrUserRequest "},
+ {14,"WrEventPair "},
+ {15,"WrQueue "},
+ {16,"WrLpcReceive "},
+ {17,"WrLpcReply "},
+ {18,"WrVirtualMemory "},
+ {19,"WrPageOut "},
+ {20,"WrRendezvous "},
+ {21,"Spare2 "},
+ {22,"WrGuardedMutex "},
+ {23,"Spare4 "},
+ {24,"Spare5 "},
+ {25,"Spare6 "},
+ {26,"WrKernel "},
+ {27,"WrResource "},
+ {28,"WrPushLock "},
+ {29,"WrMutex "},
+ {30,"WrQuantumEnd "},
+ {31,"WrDispatchInt "},
+ {32,"WrPreempted "},
+ {33,"WrYieldExecution "},
+ {34,"MaximumWaitReason"},
+ {-1," ? "}
+};
+
+static BOOL CALLBACK
+EnumThreadProc(HWND hwnd, LPARAM lp)
+{
+ DWORD r, pid, tid;
+ LONG style;
+ HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
+ char buf[256];
+
+ GetWindowText(hwnd, (LPTSTR)lp, 30);
+
+ if(hwnd != 0)
+ {
+ style = GetWindowLong(hwnd, GWL_STYLE);
+
+ tid = GetWindowThreadProcessId(hwnd, &pid);
+
+ wsprintf (buf,"w%8d %8x %08x %8d %s\n",pid, hwnd , style, tid, lp );
+ WriteFile(stdout, buf, lstrlen(buf), &r, NULL);
+ }
+ return (TRUE);
+}
+
+int main()
+{
+ DWORD r;
+ ANSI_STRING astring;
+ HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
+ PSYSTEM_PROCESSES SystemProcesses = NULL;
+ PSYSTEM_PROCESSES CurrentProcess;
+ ULONG BufferSize, ReturnSize;
+ NTSTATUS Status;
+ char buf[256];
+ char buf1[256];
+
+ WriteFile(stdout, title, lstrlen(title), &r, NULL);
+ WriteFile(stdout, title1, lstrlen(title1), &r, NULL);
+ WriteFile(stdout, title2, lstrlen(title2), &r, NULL);
+
+ /* Get process information. */
+ BufferSize = 0;
+ do
+ {
+ BufferSize += 0x10000;
+ SystemProcesses = HeapAlloc(GetProcessHeap(), 0, BufferSize);
+ Status = NtQuerySystemInformation(SystemProcessInformation,
+ SystemProcesses, BufferSize,
+ &ReturnSize);
+ if (Status == STATUS_INFO_LENGTH_MISMATCH)
+ HeapFree(GetProcessHeap(), 0, SystemProcesses);
+ } while (Status == STATUS_INFO_LENGTH_MISMATCH);
+
+ /* If querying system information failed, bail out. */
+ if (!NT_SUCCESS(Status))
+ return 1;
+
+ /* For every process print the information. */
+ CurrentProcess = SystemProcesses;
+ while (CurrentProcess->NextEntryOffset != 0)
+ {
+ int hour, hour1, thour, thour1;
+ unsigned char minute, minute1, tmin, tmin1;
+ unsigned char seconds, seconds1, tsec, tsec1;
+
+ unsigned int ti;
+ LARGE_INTEGER ptime;
+
+ ptime.QuadPart = CurrentProcess->KernelTime.QuadPart;
+ hour = (ptime.QuadPart / (10000000LL * 3600LL));
+ minute = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
+ seconds = (ptime.QuadPart / 10000000LL) % 60LL;
+
+ ptime.QuadPart = CurrentProcess->UserTime.QuadPart;
+ hour1 = (ptime.QuadPart / (10000000LL * 3600LL));
+ minute1 = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
+ seconds1 = (ptime.QuadPart / 10000000LL) % 60LL;
+
+ RtlUnicodeStringToAnsiString(&astring, &CurrentProcess->ImageName, TRUE);
+
+ wsprintf(buf,"P%8d %8d %3d:%02d:%02d %3d:%02d:%02d ProcName: %s\n",
+ CurrentProcess->UniqueProcessId, CurrentProcess->InheritedFromUniqueProcessId,
+ hour, minute, seconds, hour1, minute1, seconds1,
+ astring.Buffer);
+ WriteFile(stdout, buf, lstrlen(buf), &r, NULL);
+
+ RtlFreeAnsiString(&astring);
+
+ for (ti = 0; ti < CurrentProcess->NumberOfThreads; ti++)
+ {
+ struct status *statt;
+ struct waitres *waitt;
+ char szWindowName[30] = {" "};
+
+ ptime = CurrentProcess->Threads[ti].KernelTime;
+ thour = (ptime.QuadPart / (10000000LL * 3600LL));
+ tmin = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
+ tsec = (ptime.QuadPart / 10000000LL) % 60LL;
+
+ ptime = CurrentProcess->Threads[ti].UserTime;
+ thour1 = (ptime.QuadPart / (10000000LL * 3600LL));
+ tmin1 = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
+ tsec1 = (ptime.QuadPart / 10000000LL) % 60LL;
+
+ statt = thread_stat;
+ while (statt->state != CurrentProcess->Threads[ti].ThreadState && statt->state >= 0)
+ statt++;
+
+ waitt = waitreason;
+ while (waitt->state != CurrentProcess->Threads[ti].WaitReason && waitt->state >= 0)
+ waitt++;
+
+ wsprintf (buf1,
+ "t% %8d %3d:%02d:%02d %3d:%02d:%02d %s %s\n",
+ CurrentProcess->Threads[ti].ClientId.UniqueThread,
+ thour, tmin, tsec, thour1, tmin1, tsec1,
+ statt->desc , waitt->desc);
+ WriteFile(stdout, buf1, lstrlen(buf1), &r, NULL);
+
+ EnumThreadWindows(PtrToUlong(CurrentProcess->Threads[ti].ClientId.UniqueThread),
+ (WNDENUMPROC) EnumThreadProc,
+ (LPARAM)(LPTSTR) szWindowName );
+ }
+
+ CurrentProcess = (PSYSTEM_PROCESSES)((ULONG_PTR)CurrentProcess +
+ (ULONG_PTR)CurrentProcess->NextEntryOffset);
+ }
+ return (0);
+}
--- /dev/null
+/* $Id$
+ *
+ * ReactOS ps - process list console viewer
+ *
+ * ps.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <windows.h>
+#include <tlhelp32.h>
+
+static char* title = " PID PARENT TIME NAME\n";
+char buf[256];
+
+int main()
+{
+ DWORD r;
+ HANDLE pl;
+ PROCESSENTRY32 pe;
+ HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ WriteFile(stdout, title, lstrlen(title), &r, NULL);
+ pl = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ pe.dwSize = sizeof(PROCESSENTRY32);
+ pe.th32ParentProcessID = 0;
+
+ if (Process32First(pl, &pe)) do {
+ int hour;
+ int minute;
+ WORD fatdate;
+ WORD fattime;
+ HANDLE p = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe.th32ProcessID);
+ FILETIME cr;
+ FILETIME ex;
+ FILETIME kt;
+ FILETIME ut;
+ GetProcessTimes(p, &cr, &ex, &kt, &ut);
+ FileTimeToDosDateTime(&cr, &fatdate, &fattime);
+ hour = (fattime & 0xf800) >> 11;
+ minute = (fattime & 0x07e0) >> 5;
+ wsprintf(buf,"%08X %08X %2d:%02d %s\n", pe.th32ProcessID, pe.th32ParentProcessID, hour, minute, pe.szExeFile);
+ WriteFile(stdout, buf, lstrlen(buf), &r, NULL);
+ CloseHandle(p);
+ pe.th32ParentProcessID = 0;
+ } while (Process32Next(pl, &pe));
+
+ CloseHandle(pl);
+}
+/*
+BOOL
+STDCALL
+FileTimeToDosDateTime(
+ CONST FILETIME *lpFileTime,
+ LPWORD lpFatDate,
+ LPWORD lpFatTime
+ );
+ */
--- /dev/null
+<module name="ps" type="win32cui" installbase="bin" installname="ps.exe">
+ <include base="ps">.</include>
+ <define name="__USE_W32API" />
+ <library>user32</library>
+ <library>kernel32</library>
+ <library>ntdll</library>
+ <file>ps.c</file>
+</module>
\ No newline at end of file
--- /dev/null
+/*
+ * ReactOS RosPerf - ReactOS GUI performance test program
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <windows.h>
+#include <wingdi.h>
+#include "rosperf.h"
+
+typedef struct _ALPHABLEND_CONTEXT {
+ HDC BitmapDc;
+ HBITMAP Bitmap;
+} ALPHABLEND_CONTEXT, *PALPHABLEND_CONTEXT;
+
+unsigned
+AlphaBlendInit(void **Context, PPERF_INFO PerfInfo, unsigned Reps)
+{
+ PALPHABLEND_CONTEXT ctx = HeapAlloc(GetProcessHeap(), 0, sizeof (ALPHABLEND_CONTEXT));
+ INT x, y;
+
+ ctx->BitmapDc = CreateCompatibleDC(PerfInfo->BackgroundDc);
+ ctx->Bitmap = CreateCompatibleBitmap(PerfInfo->BackgroundDc, PerfInfo->WndWidth, PerfInfo->WndHeight);
+ SelectObject(ctx->BitmapDc, ctx->Bitmap);
+
+ for (y = 0; y < PerfInfo->WndHeight; y++)
+ {
+ for (x = 0; x < PerfInfo->WndWidth; x++)
+ {
+ SetPixel(ctx->BitmapDc, x, y, RGB(0xff, 0x00, 0x00));
+ }
+ }
+
+ *Context = ctx;
+
+ return Reps;
+}
+
+void
+AlphaBlendCleanup(void *Context, PPERF_INFO PerfInfo)
+{
+ PALPHABLEND_CONTEXT ctx = Context;
+ DeleteDC(ctx->BitmapDc);
+ DeleteObject(ctx->Bitmap);
+ HeapFree(GetProcessHeap(), 0, ctx);
+}
+
+
+ULONG
+DbgPrint(
+ IN PCSTR Format,
+ IN ...);
+
+void
+AlphaBlendProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps)
+{
+ PALPHABLEND_CONTEXT ctx = Context;
+ unsigned Rep;
+ BLENDFUNCTION BlendFunc = { AC_SRC_OVER, 0, 0, 0 };
+
+ for (Rep = 0; Rep < Reps; Rep++)
+ {
+ BlendFunc.SourceConstantAlpha = 255 * Rep / Reps;
+#if 0
+ PatBlt(PerfInfo->BackgroundDc, 0, 0, PerfInfo->WndWidth, PerfInfo->WndHeight, PATCOPY);
+#endif
+ if (!AlphaBlend(PerfInfo->BackgroundDc, 0, 0, PerfInfo->WndWidth, PerfInfo->WndHeight,
+ ctx->BitmapDc, 0, 0, PerfInfo->WndWidth, PerfInfo->WndHeight,
+ BlendFunc))
+ {
+ DbgPrint("AlphaBlend failed (0x%lx)\n", GetLastError());
+ }
+ }
+}
+
+/* EOF */
--- /dev/null
+/*
+ * ReactOS RosPerf - ReactOS GUI performance test program
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <windows.h>
+#include "rosperf.h"
+
+void
+FillProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps)
+{
+ unsigned Rep;
+
+ for (Rep = 0; Rep < Reps; Rep++)
+ {
+ PatBlt((Rep & 0x100) ? PerfInfo->BackgroundDc : PerfInfo->ForegroundDc, 0, 0,
+ PerfInfo->WndWidth, PerfInfo->WndHeight, PATCOPY);
+ }
+}
+
+void
+FillSmallProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps)
+{
+#define SMALL_SIZE 16
+ unsigned Rep;
+ int x, y;
+
+ x = 0;
+ y = 0;
+
+ for (Rep = 0; Rep < Reps; Rep++)
+ {
+ PatBlt((Rep & 0x10000) ? PerfInfo->BackgroundDc : PerfInfo->ForegroundDc, x, y,
+ SMALL_SIZE, SMALL_SIZE, PATCOPY);
+ x += SMALL_SIZE + 1;
+ if (PerfInfo->WndWidth < x + SMALL_SIZE)
+ {
+ x = 0;
+ y += SMALL_SIZE + 1;
+ if (PerfInfo->WndHeight < y + SMALL_SIZE)
+ {
+ y = 0;
+ }
+ }
+ }
+}
+/* EOF */
--- /dev/null
+/*
+ * ReactOS RosPerf - ReactOS GUI performance test program
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <windows.h>
+#include "rosperf.h"
+
+void
+LinesProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps)
+{
+ unsigned Rep;
+ int Dest;
+ HDC Dc;
+
+ for (Rep = 0; Rep < Reps; )
+ {
+ Dc = (Rep & 0x1000) ? PerfInfo->BackgroundDc : PerfInfo->ForegroundDc;
+
+ for (Dest = 2; Dest < PerfInfo->WndHeight && Rep < Reps; Rep++, Dest += 2)
+ {
+ MoveToEx(Dc, 0, 0, NULL);
+ LineTo(Dc, PerfInfo->WndWidth, Dest);
+ }
+
+ for (Dest = PerfInfo->WndWidth - 2; 0 <= Dest && Rep < Reps; Rep++, Dest -= 2)
+ {
+ MoveToEx(Dc, PerfInfo->WndWidth, 0, NULL);
+ LineTo(Dc, Dest, PerfInfo->WndHeight);
+ }
+
+ for (Dest = PerfInfo->WndHeight - 2; 0 <= Dest && Rep < Reps; Rep++, Dest -= 2)
+ {
+ MoveToEx(Dc, PerfInfo->WndWidth, PerfInfo->WndHeight, NULL);
+ LineTo(Dc, 0, Dest);
+ }
+
+ for (Dest = 2; Dest < PerfInfo->WndWidth && Rep < Reps; Rep++, Dest += 2)
+ {
+ MoveToEx(Dc, 0, PerfInfo->WndHeight, NULL);
+ LineTo(Dc, Dest, 0);
+ }
+ }
+}
+
+void
+LinesHorizontalProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps)
+{
+ unsigned Rep;
+ int y;
+ HDC Dc;
+
+ for (Rep = 0; Rep < Reps; )
+ {
+ Dc = (Rep & 0x10000) ? PerfInfo->BackgroundDc : PerfInfo->ForegroundDc;
+
+ for (y = 0; y < PerfInfo->WndHeight && Rep < Reps; Rep++, y += 3)
+ {
+ MoveToEx(Dc, 0, y, NULL);
+ LineTo(Dc, PerfInfo->WndWidth, y);
+ }
+ }
+}
+
+void
+LinesVerticalProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps)
+{
+ unsigned Rep;
+ int x;
+ HDC Dc;
+
+ for (Rep = 0; Rep < Reps; )
+ {
+ Dc = (Rep & 0x1000) ? PerfInfo->BackgroundDc : PerfInfo->ForegroundDc;
+
+ for (x = 0; x < PerfInfo->WndWidth && Rep < Reps; Rep++, x += 3)
+ {
+ MoveToEx(Dc, x, 0, NULL);
+ LineTo(Dc, x, PerfInfo->WndHeight);
+ }
+ }
+}
+
+/* EOF */
--- /dev/null
+/*
+ * ReactOS RosPerf - ReactOS GUI performance test program
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * Ideas copied from x11perf:
+ *
+ * Copyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Digital not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+#include <reactos/buildno.h>
+
+#include "rosperf.h"
+
+#define MAINWND_WIDTH 400
+#define MAINWND_HEIGHT 400
+
+static HWND LabelWnd;
+
+unsigned
+NullInit(void **Context, PPERF_INFO PerfInfo, unsigned Reps)
+{
+ *Context = NULL;
+
+ return Reps;
+}
+
+void
+NullCleanup(void *Context, PPERF_INFO PerfInfo)
+{
+}
+
+static void
+ProcessMessages(void)
+{
+ MSG Msg;
+
+ while (PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (WM_QUIT == Msg.message)
+ {
+ exit(Msg.wParam);
+ }
+ TranslateMessage(&Msg);
+ DispatchMessageW(&Msg);
+ }
+}
+
+static void
+ClearWindow(PPERF_INFO PerfInfo)
+{
+ InvalidateRect(PerfInfo->Wnd, NULL, TRUE);
+ UpdateWindow(PerfInfo->Wnd);
+}
+
+static unsigned
+CalibrateTest(PTEST Test, PPERF_INFO PerfInfo)
+{
+#define GOAL 2500 /* Try to get up to 2.5 seconds */
+#define ENOUGH 2000 /* But settle for 2.0 seconds */
+#define TICK 10 /* Assume clock not faster than .01 seconds */
+
+ unsigned Reps, DidReps; /* Reps desired, reps performed */
+ unsigned Exponent;
+ void *Context;
+ DWORD StartTick;
+ DWORD Duration;
+
+ /* Attempt to get an idea how long each rep lasts by getting enough
+ reps to last more than ENOUGH. Then scale that up to the number of
+ seconds desired.
+
+ If init call to test ever fails, return False and test will be skipped.
+ */
+
+ Reps = 1;
+ for (;;)
+ {
+ ClearWindow(PerfInfo);
+ DidReps = (*Test->Init)(&Context, PerfInfo, Reps);
+ ProcessMessages();
+ if (0 == DidReps)
+ {
+ return 0;
+ }
+ StartTick = GetTickCount();
+ (*Test->Proc)(Context, PerfInfo, Reps);
+ Duration = GetTickCount() - StartTick;
+ (*Test->PassCleanup) (Context, PerfInfo);
+ (*Test->Cleanup)(Context, PerfInfo);
+ ProcessMessages();
+
+ if (DidReps != Reps)
+ {
+ /* The test can't do the number of reps as we asked for.
+ Give up */
+ return DidReps;
+ }
+ /* Did we go long enough? */
+ if (ENOUGH <= Duration)
+ {
+ break;
+ }
+
+ /* Don't let too short a clock make new reps wildly high */
+ if (Duration <= TICK)
+ {
+ Reps *= 10;
+ }
+ else
+ {
+ /* Try to get up to GOAL seconds. */
+ Reps = (int)(GOAL * (double) Reps / (double) Duration) + 1;
+ }
+ }
+
+ Reps = (int) ((double) PerfInfo->Seconds * 1000.0 * (double) Reps / (double) Duration) + 1;
+
+ /* Now round reps up to 1 digit accuracy, so we don't get stupid-looking
+ numbers of repetitions. */
+ Reps--;
+ Exponent = 1;
+ while (9 < Reps)
+ {
+ Reps /= 10;
+ Exponent *= 10;
+ }
+ Reps = (Reps + 1) * Exponent;
+
+ return Reps;
+}
+
+static void
+DisplayStatus(HWND Label, LPCWSTR Message, LPCWSTR Test, int Try)
+{
+ WCHAR Status[128];
+
+ snwprintf(Status, sizeof(Status) / sizeof(Status[0]), L"%d %s %s", Try, Message, Test);
+ SetWindowTextW(Label, Status);
+ InvalidateRect(Label, NULL, TRUE);
+ UpdateWindow(Label);
+}
+
+static double
+RoundTo3Digits(double d)
+{
+ /* It's kind of silly to print out things like ``193658.4/sec'' so just
+ junk all but 3 most significant digits. */
+
+ double exponent, sign;
+
+ exponent = 1.0;
+ /* the code below won't work if d should happen to be non-positive. */
+ if (d < 0.0)
+ {
+ d = -d;
+ sign = -1.0;
+ }
+ else
+ {
+ sign = 1.0;
+ }
+
+ if (1000.0 <= d)
+ {
+ do
+ {
+ exponent *= 10.0;
+ }
+ while (1000.0 <= d / exponent);
+ d = (double)((int)(d / exponent + 0.5));
+ d *= exponent;
+ }
+ else
+ {
+ if (0.0 != d)
+ {
+ while (d * exponent < 100.0)
+ {
+ exponent *= 10.0;
+ }
+ }
+ d = (double)((int)(d * exponent + 0.5));
+ d /= exponent;
+ }
+
+ return d * sign;
+}
+
+static void
+ReportTimes(DWORD Time, int Reps, LPCWSTR Label, BOOL Average)
+{
+ double MSecsPerObj, ObjsPerSec;
+
+ if (0 != Time)
+ {
+ MSecsPerObj = (double) Time / (double) Reps;
+ ObjsPerSec = (double) Reps * 1000.0 / (double) Time;
+
+ /* Round obj/sec to 3 significant digits. Leave msec untouched, to
+ allow averaging results from several repetitions. */
+ ObjsPerSec = RoundTo3Digits(ObjsPerSec);
+
+ wprintf(L"%7d %s @ %8.4f msec (%8.1f/sec): %s\n",
+ Reps, Average ? L"trep" : L"reps", MSecsPerObj, ObjsPerSec, Label);
+ }
+ else
+ {
+ wprintf(L"%6d %sreps @ 0.0 msec (unmeasurably fast): %s\n",
+ Reps, Average ? L"t" : L"", Label);
+ }
+
+}
+
+static void
+ProcessTest(PTEST Test, PPERF_INFO PerfInfo)
+{
+ unsigned Reps;
+ unsigned Repeat;
+ void *Context;
+ DWORD StartTick;
+ DWORD Time, TotalTime;
+
+ DisplayStatus(LabelWnd, L"Calibrating", Test->Label, 0);
+ Reps = CalibrateTest(Test, PerfInfo);
+ if (0 == Reps)
+ {
+ return;
+ }
+
+ Reps = Test->Init(&Context, PerfInfo, Reps);
+ if (0 == Reps)
+ {
+ return;
+ }
+ TotalTime = 0;
+ for (Repeat = 0; Repeat < PerfInfo->Repeats; Repeat++)
+ {
+ DisplayStatus(LabelWnd, L"Testing", Test->Label, Repeat + 1);
+ ClearWindow(PerfInfo);
+ StartTick = GetTickCount();
+ (*Test->Proc)(Context, PerfInfo, Reps);
+ Time = GetTickCount() - StartTick;
+ ProcessMessages();
+ TotalTime += Time;
+ ReportTimes(Time, Reps, Test->Label, FALSE);
+ (*Test->PassCleanup)(Context, PerfInfo);
+ ProcessMessages();
+ }
+ (*Test->Cleanup)(Context, PerfInfo);
+ ReportTimes(TotalTime, Repeat * Reps, Test->Label, TRUE);
+ ProcessMessages();
+}
+
+static void
+PrintOSVersion(void)
+{
+#define BUFSIZE 160
+ OSVERSIONINFOEXW VersionInfo;
+ BOOL OsVersionInfoEx;
+ HKEY hKey;
+ WCHAR ProductType[BUFSIZE];
+ DWORD BufLen;
+ LONG Ret;
+ unsigned RosVersionLen;
+ LPWSTR RosVersion;
+
+ /* Try calling GetVersionEx using the OSVERSIONINFOEX structure.
+ * If that fails, try using the OSVERSIONINFO structure. */
+
+ ZeroMemory(&VersionInfo, sizeof(OSVERSIONINFOEXW));
+ VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
+
+ OsVersionInfoEx = GetVersionExW((OSVERSIONINFOW *) &VersionInfo);
+ if (! OsVersionInfoEx)
+ {
+ VersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+ if (! GetVersionExW((OSVERSIONINFOW *) &VersionInfo))
+ {
+ return;
+ }
+ }
+
+ RosVersion = VersionInfo.szCSDVersion + wcslen(VersionInfo.szCSDVersion) + 1;
+ RosVersionLen = sizeof(VersionInfo.szCSDVersion) / sizeof(VersionInfo.szCSDVersion[0]) -
+ (RosVersion - VersionInfo.szCSDVersion);
+ if (7 <= RosVersionLen && 0 == _wcsnicmp(RosVersion, L"ReactOS", 7))
+ {
+ wprintf(L"Running on %s\n", RosVersion);
+ return;
+ }
+
+ switch (VersionInfo.dwPlatformId)
+ {
+ /* Test for the Windows NT product family. */
+ case VER_PLATFORM_WIN32_NT:
+
+ /* Test for the specific product. */
+ if (5 == VersionInfo.dwMajorVersion && 2 == VersionInfo.dwMinorVersion)
+ {
+ wprintf(L"Running on Microsoft Windows Server 2003, ");
+ }
+ else if (5 == VersionInfo.dwMajorVersion && 1 == VersionInfo.dwMinorVersion)
+ {
+ wprintf(L"Running on Microsoft Windows XP ");
+ }
+ else if (5 == VersionInfo.dwMajorVersion && 0 == VersionInfo.dwMinorVersion)
+ {
+ wprintf(L"Running on Microsoft Windows 2000 ");
+ }
+ else if (VersionInfo.dwMajorVersion <= 4 )
+ {
+ wprintf(L"Running on Microsoft Windows NT ");
+ }
+
+ /* Test for specific product on Windows NT 4.0 SP6 and later. */
+ if (OsVersionInfoEx)
+ {
+ /* Test for the workstation type. */
+ if (VER_NT_WORKSTATION == VersionInfo.wProductType)
+ {
+ if (4 == VersionInfo.dwMajorVersion)
+ {
+ wprintf(L"Workstation 4.0 ");
+ }
+ else if (0 != (VersionInfo.wSuiteMask & VER_SUITE_PERSONAL))
+ {
+ wprintf(L"Home Edition ");
+ }
+ else
+ {
+ wprintf(L"Professional ");
+ }
+ }
+
+ /* Test for the server type. */
+ else if (VER_NT_SERVER == VersionInfo.wProductType ||
+ VER_NT_DOMAIN_CONTROLLER == VersionInfo.wProductType)
+ {
+ if (5 == VersionInfo.dwMajorVersion && 2 == VersionInfo.dwMinorVersion)
+ {
+ if (0 != (VersionInfo.wSuiteMask & VER_SUITE_DATACENTER))
+ {
+ wprintf(L"Datacenter Edition ");
+ }
+ else if (0 != (VersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE))
+ {
+ wprintf(L"Enterprise Edition ");
+ }
+ else if (VER_SUITE_BLADE == VersionInfo.wSuiteMask)
+ {
+ wprintf(L"Web Edition ");
+ }
+ else
+ {
+ wprintf(L"Standard Edition ");
+ }
+ }
+
+ else if (5 == VersionInfo.dwMajorVersion && 0 == VersionInfo.dwMinorVersion)
+ {
+ if (0 != (VersionInfo.wSuiteMask & VER_SUITE_DATACENTER))
+ {
+ wprintf(L"Datacenter Server ");
+ }
+ else if (0 != (VersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE))
+ {
+ wprintf(L"Advanced Server " );
+ }
+ else
+ {
+ wprintf(L"Server " );
+ }
+ }
+
+ else /* Windows NT 4.0 */
+ {
+ if (0 != (VersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE))
+ {
+ wprintf(L"Server 4.0, Enterprise Edition ");
+ }
+ else
+ {
+ wprintf(L"Server 4.0 ");
+ }
+ }
+ }
+ }
+ else /* Test for specific product on Windows NT 4.0 SP5 and earlier */
+ {
+ BufLen = BUFSIZE;
+
+ Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
+ 0, KEY_QUERY_VALUE, &hKey);
+ if (ERROR_SUCCESS != Ret)
+ {
+ return;
+ }
+
+ Ret = RegQueryValueExW(hKey, L"ProductType", NULL, NULL,
+ (LPBYTE) ProductType, &BufLen);
+ if (ERROR_SUCCESS != Ret || BUFSIZE < BufLen)
+ {
+ return;
+ }
+
+ RegCloseKey(hKey);
+
+ if (0 == lstrcmpiW(L"WINNT", ProductType))
+ {
+ wprintf(L"Workstation ");
+ }
+ else if (0 == lstrcmpiW(L"LANMANNT", ProductType))
+ {
+ wprintf(L"Server ");
+ }
+ else if (0 == lstrcmpiW(L"SERVERNT", ProductType))
+ {
+ wprintf(L"Advanced Server ");
+ }
+
+ wprintf(L"%d.%d ", VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion);
+ }
+
+ /* Display service pack (if any) and build number. */
+
+ if (4 == VersionInfo.dwMajorVersion &&
+ 0 == lstrcmpiW(VersionInfo.szCSDVersion, L"Service Pack 6"))
+ {
+ /* Test for SP6 versus SP6a. */
+ Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009",
+ 0, KEY_QUERY_VALUE, &hKey);
+ if (ERROR_SUCCESS == Ret)
+ {
+ wprintf(L"Service Pack 6a (Build %d)\n", VersionInfo.dwBuildNumber & 0xFFFF);
+ }
+ else /* Windows NT 4.0 prior to SP6a */
+ {
+ wprintf(L"%s (Build %d)\n",
+ VersionInfo.szCSDVersion,
+ VersionInfo.dwBuildNumber & 0xFFFF);
+ }
+
+ RegCloseKey(hKey);
+ }
+ else /* not Windows NT 4.0 */
+ {
+ wprintf(L"%s (Build %d)\n",
+ VersionInfo.szCSDVersion,
+ VersionInfo.dwBuildNumber & 0xFFFF);
+ }
+
+
+ break;
+
+ /* Test for the Windows Me/98/95. A bit silly since we're using Unicode... */
+ case VER_PLATFORM_WIN32_WINDOWS:
+
+ if (4 == VersionInfo.dwMajorVersion && 0 == VersionInfo.dwMinorVersion)
+ {
+ wprintf(L"Running on Microsoft Windows 95 ");
+ if (L'C' == VersionInfo.szCSDVersion[1] || L'B' == VersionInfo.szCSDVersion[1])
+ {
+ wprintf(L"OSR2");
+ }
+ }
+
+ else if (4 == VersionInfo.dwMajorVersion && 10 == VersionInfo.dwMinorVersion)
+ {
+ wprintf(L"Running on Microsoft Windows 98 ");
+ if (L'A' == VersionInfo.szCSDVersion[1])
+ {
+ wprintf(L"SE");
+ }
+ }
+
+ else if (4 == VersionInfo.dwMajorVersion && 90 == VersionInfo.dwMinorVersion)
+ {
+ wprintf(L"Running on Microsoft Windows Millennium Edition");
+ }
+ wprintf(L"\n");
+ break;
+
+ case VER_PLATFORM_WIN32s: /* Even silier... */
+
+ wprintf(L"Running on Microsoft Win32s\n");
+ break;
+ }
+}
+
+static void
+PrintAppVersion(void)
+{
+ wprintf(L"RosPerf %S (Build %S)\n", KERNEL_VERSION_STR, KERNEL_VERSION_BUILD_STR);
+}
+
+static void
+PrintDisplayInfo(void)
+{
+ HDC Dc;
+
+ Dc = GetDC(NULL);
+ if (NULL == Dc)
+ {
+ return;
+ }
+
+ wprintf(L"Display settings %d * %d * %d\n", GetDeviceCaps(Dc, HORZRES),
+ GetDeviceCaps(Dc, VERTRES), GetDeviceCaps(Dc, BITSPIXEL) * GetDeviceCaps(Dc, PLANES));
+
+ ReleaseDC(NULL, Dc);
+}
+
+static void
+PrintStartupInfo(void)
+{
+ PrintAppVersion();
+ PrintOSVersion();
+ PrintDisplayInfo();
+}
+
+static LRESULT CALLBACK
+MainWndProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ PAINTSTRUCT Ps;
+ HDC Dc;
+ LRESULT Result;
+
+ switch (Msg)
+ {
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ Result = 0;
+ break;
+
+ case WM_PAINT:
+ Dc = BeginPaint(Wnd, &Ps);
+ EndPaint (Wnd, &Ps);
+ Result = 0;
+ break;
+
+ default:
+ Result = DefWindowProcW(Wnd, Msg, wParam, lParam);
+ break;
+ }
+
+ return Result;
+}
+
+static LRESULT CALLBACK
+LabelWndProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ PAINTSTRUCT Ps;
+ HDC Dc;
+ RECT ClientRect, WindowRect;
+ TEXTMETRICW Tm;
+ LRESULT Result;
+ WCHAR Title[80];
+
+ switch (Msg)
+ {
+ case WM_CREATE:
+ /* Make text fit */
+ Dc = GetDC(Wnd);
+ if (NULL != Dc && GetClientRect(Wnd, &ClientRect) && GetWindowRect(Wnd, &WindowRect)
+ && GetTextMetricsW(Dc, &Tm))
+ {
+ if (Tm.tmHeight != ClientRect.bottom)
+ {
+ SetWindowPos(Wnd, NULL, 0, 0, WindowRect.right - WindowRect.left,
+ (WindowRect.bottom - WindowRect.top) + (Tm.tmHeight - ClientRect.bottom),
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER);
+ }
+ }
+ if (NULL != Dc)
+ {
+ ReleaseDC(Wnd, Dc);
+ }
+ Result = DefWindowProcW(Wnd, Msg, wParam, lParam);
+ break;
+
+ case WM_PAINT:
+ Dc = BeginPaint(Wnd, &Ps);
+ GetWindowTextW(Wnd, Title, sizeof(Title) / sizeof(Title[0]));
+ TextOutW(Dc, 0, 0, Title, wcslen(Title));
+ EndPaint (Wnd, &Ps);
+ Result = 0;
+ break;
+
+ default:
+ Result = DefWindowProcW(Wnd, Msg, wParam, lParam);
+ break;
+ }
+
+ return Result;
+}
+
+static HWND
+CreatePerfWindows(HINSTANCE hInstance, PPERF_INFO PerfInfo)
+{
+ WNDCLASSW wc;
+ HWND MainWnd;
+
+ wc.lpszClassName = L"RosPerfMain";
+ wc.lpfnWndProc = MainWndProc;
+ wc.style = 0;
+ wc.hInstance = hInstance;
+ wc.hIcon = LoadIconW(NULL, (LPCWSTR) IDI_APPLICATION);
+ wc.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
+ wc.hbrBackground = CreateSolidBrush(PerfInfo->BackgroundColor);
+ wc.lpszMenuName = NULL;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ if (RegisterClassW(&wc) == 0)
+ {
+ fwprintf(stderr, L"Failed to register RosPerfMain (last error %d)\n",
+ GetLastError());
+ return NULL;
+ }
+
+ wc.lpszClassName = L"RosPerfLabel";
+ wc.lpfnWndProc = LabelWndProc;
+ wc.style = 0;
+ wc.hInstance = hInstance;
+ wc.hIcon = LoadIconW(NULL, (LPCWSTR) IDI_APPLICATION);
+ wc.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
+ wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
+ wc.lpszMenuName = NULL;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ if (RegisterClassW(&wc) == 0)
+ {
+ fwprintf(stderr, L"Failed to register RosPerfLabel (last error %d)\n",
+ GetLastError());
+ return NULL;
+ }
+
+ MainWnd = CreateWindowW(L"RosPerfMain",
+ L"ReactOS performance test",
+ WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 0,
+ 0,
+ MAINWND_WIDTH,
+ MAINWND_HEIGHT,
+ NULL,
+ NULL,
+ hInstance,
+ NULL);
+ if (NULL == MainWnd)
+ {
+ fwprintf(stderr, L"Failed to create main window (last error %d)\n",
+ GetLastError());
+ return NULL;
+ }
+
+ LabelWnd = CreateWindowW(L"RosPerfLabel",
+ L"",
+ WS_POPUP | WS_THICKFRAME | WS_VISIBLE,
+ 0,
+ MAINWND_HEIGHT + 10,
+ MAINWND_WIDTH,
+ 20,
+ MainWnd,
+ NULL,
+ hInstance,
+ NULL);
+ if (NULL == LabelWnd)
+ {
+ fwprintf(stderr, L"Failed to create label window (last error 0x%lX)\n",
+ GetLastError());
+ return NULL;
+ }
+
+ SetActiveWindow(MainWnd);
+
+ return MainWnd;
+}
+
+static BOOL
+ProcessCommandLine(PPERF_INFO PerfInfo, unsigned *TestCount, PTEST *Tests)
+{
+ int ArgC, Arg;
+ LPWSTR *ArgV;
+ LPWSTR EndPtr;
+ PTEST AllTests;
+ BOOL *DoTest;
+ BOOL DoAll;
+ unsigned AllTestCount, i, j;
+
+ ArgV = CommandLineToArgvW(GetCommandLineW(), &ArgC);
+ if (NULL == ArgV)
+ {
+ fwprintf(stderr, L"CommandLineToArgvW failed\n");
+ return FALSE;
+ }
+
+ GetTests(&AllTestCount, &AllTests);
+ DoTest = malloc(AllTestCount * sizeof(BOOL));
+ if (NULL == DoTest)
+ {
+ fwprintf(stderr, L"Out of memory\n");
+ return FALSE;
+ }
+ DoAll = TRUE;
+
+ for (Arg = 1; Arg < ArgC; Arg++)
+ {
+ if (L'/' == ArgV[Arg][0] || L'-' == ArgV[Arg][0])
+ {
+ if (0 == _wcsicmp(ArgV[Arg] + 1, L"repeat"))
+ {
+ if (ArgC <= Arg + 1)
+ {
+ fwprintf(stderr, L"%s needs a repeat count\n", ArgV[Arg]);
+ free(DoTest);
+ GlobalFree(ArgV);
+ return FALSE;
+ }
+ Arg++;
+ PerfInfo->Repeats = wcstoul(ArgV[Arg], &EndPtr, 0);
+ if (L'\0' != *EndPtr || (long) PerfInfo->Repeats <= 0 || ULONG_MAX == PerfInfo->Repeats)
+ {
+ fwprintf(stderr, L"Invalid repeat count %s\n", ArgV[Arg]);
+ free(DoTest);
+ GlobalFree(ArgV);
+ return FALSE;
+ }
+ }
+ else if (0 == _wcsicmp(ArgV[Arg] + 1, L"seconds"))
+ {
+ if (ArgC <= Arg + 1)
+ {
+ fwprintf(stderr, L"%s needs a number of seconds\n", ArgV[Arg]);
+ free(DoTest);
+ GlobalFree(ArgV);
+ return FALSE;
+ }
+ Arg++;
+ PerfInfo->Seconds = wcstoul(ArgV[Arg], &EndPtr, 0);
+ if (L'\0' != *EndPtr || (long) PerfInfo->Seconds < 0 || ULONG_MAX == PerfInfo->Seconds)
+ {
+ fwprintf(stderr, L"Invalid duration %s\n", ArgV[Arg]);
+ free(DoTest);
+ GlobalFree(ArgV);
+ return FALSE;
+ }
+ }
+ else
+ {
+ fwprintf(stderr, L"Unrecognized option %s\n", ArgV[Arg]);
+ free(DoTest);
+ GlobalFree(ArgV);
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (DoAll)
+ {
+ for (i = 0; i < AllTestCount; i++)
+ {
+ DoTest[i] = FALSE;
+ }
+ DoAll = FALSE;
+ }
+ for (i = 0; i < AllTestCount; i++)
+ {
+ if (0 == _wcsicmp(ArgV[Arg], AllTests[i].Option))
+ {
+ DoTest[i] = TRUE;
+ break;
+ }
+ }
+ if (AllTestCount <= i)
+ {
+ fwprintf(stderr, L"Unrecognized test %s\n", ArgV[Arg]);
+ free(DoTest);
+ GlobalFree(ArgV);
+ return FALSE;
+ }
+ }
+ }
+
+ GlobalFree(ArgV);
+
+ if (DoAll)
+ {
+ for (i = 0; i < AllTestCount; i++)
+ {
+ DoTest[i] = TRUE;
+ }
+ }
+
+ *TestCount = 0;
+ for (i = 0; i < AllTestCount; i++)
+ {
+ if (DoTest[i])
+ {
+ (*TestCount)++;
+ }
+ }
+ *Tests = malloc(*TestCount * sizeof(TEST));
+ if (NULL == *Tests)
+ {
+ fwprintf(stderr, L"Out of memory\n");
+ free(DoTest);
+ return FALSE;
+ }
+ j = 0;
+ for (i = 0; i < AllTestCount; i++)
+ {
+ if (DoTest[i])
+ {
+ (*Tests)[j] = AllTests[i];
+ j++;
+ }
+ }
+ free(DoTest);
+
+ return TRUE;
+}
+
+int WINAPI
+WinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpszCmdLine,
+ int nCmdShow)
+{
+ PTEST Tests;
+ unsigned TestCount;
+ unsigned CurrentTest;
+ RECT Rect;
+ PERF_INFO PerfInfo;
+
+ PrintStartupInfo();
+
+ PerfInfo.Seconds = 15;
+ PerfInfo.Repeats = 4;
+ PerfInfo.ForegroundColor = RGB(0, 0, 0);
+ PerfInfo.BackgroundColor = RGB(255, 255, 255);
+
+ if (! ProcessCommandLine(&PerfInfo, &TestCount, &Tests))
+ {
+ exit(1);
+ }
+
+ PerfInfo.Wnd = CreatePerfWindows(hInstance, &PerfInfo);
+ if (NULL == PerfInfo.Wnd)
+ {
+ exit(1);
+ }
+
+ GetClientRect(PerfInfo.Wnd, &Rect);
+ PerfInfo.WndWidth = Rect.right - Rect.left;
+ PerfInfo.WndHeight = Rect.bottom - Rect.top;
+ PerfInfo.ForegroundDc = GetDC(PerfInfo.Wnd);
+ PerfInfo.BackgroundDc = GetDC(PerfInfo.Wnd);
+ if (NULL == PerfInfo.ForegroundDc || NULL == PerfInfo.BackgroundDc)
+ {
+ fwprintf(stderr, L"Failed to create device contexts (last error %d)\n",
+ GetLastError());
+ exit(1);
+ }
+ SelectObject(PerfInfo.ForegroundDc, CreateSolidBrush(PerfInfo.ForegroundColor));
+ SelectObject(PerfInfo.ForegroundDc, CreatePen(PS_SOLID, 0, PerfInfo.ForegroundColor));
+ SelectObject(PerfInfo.BackgroundDc, CreateSolidBrush(PerfInfo.BackgroundColor));
+ SelectObject(PerfInfo.BackgroundDc, CreatePen(PS_SOLID, 0, PerfInfo.BackgroundColor));
+
+ ProcessMessages();
+
+ /* Move cursor out of the way */
+ GetWindowRect(LabelWnd, &Rect);
+ SetCursorPos(Rect.right, Rect.bottom);
+
+ for (CurrentTest = 0; CurrentTest < TestCount; CurrentTest++)
+ {
+ wprintf(L"\n");
+ ProcessTest(Tests + CurrentTest, &PerfInfo);
+ }
+
+ GlobalFree(Tests);
+
+ return 0;
+}
+
+/* EOF */
--- /dev/null
+/*
+ * ReactOS RosPerf - ReactOS GUI performance test program
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef ROSPERF_H_INCLUDED
+#define ROSPERF_H_INCLUDED
+
+typedef struct tagPERF_INFO
+{
+ HWND Wnd;
+ unsigned Seconds;
+ unsigned Repeats;
+ COLORREF ForegroundColor;
+ COLORREF BackgroundColor;
+ HDC ForegroundDc;
+ HDC BackgroundDc;
+ INT WndWidth;
+ INT WndHeight;
+} PERF_INFO, *PPERF_INFO;
+
+typedef unsigned (*INITTESTPROC)(void **Context, PPERF_INFO PerfInfo, unsigned Reps);
+typedef void (*TESTPROC)(void *Context, PPERF_INFO PerfInfo, unsigned Reps);
+typedef void (*CLEANUPTESTPROC)(void *Context, PPERF_INFO PerfInfo);
+
+typedef struct tagTEST
+{
+ LPCWSTR Option;
+ LPCWSTR Label;
+ INITTESTPROC Init;
+ TESTPROC Proc;
+ CLEANUPTESTPROC PassCleanup;
+ CLEANUPTESTPROC Cleanup;
+} TEST, *PTEST;
+
+void GetTests(unsigned *TestCount, PTEST *Tests);
+
+/* Tests */
+unsigned NullInit(void **Context, PPERF_INFO PerfInfo, unsigned Reps);
+void NullCleanup(void *Context, PPERF_INFO PerfInfo);
+
+void FillProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps);
+void FillSmallProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps);
+
+void LinesHorizontalProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps);
+void LinesVerticalProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps);
+void LinesProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps);
+
+void TextProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps);
+
+unsigned AlphaBlendInit(void **Context, PPERF_INFO PerfInfo, unsigned Reps);
+void AlphaBlendCleanup(void *Context, PPERF_INFO PerfInfo);
+void AlphaBlendProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps);
+
+#endif /* ROSPERF_H_INCLUDED */
+
+/* EOF */
--- /dev/null
+#define REACTOS_STR_FILE_DESCRIPTION "ReactOS performance tester\0"
+#define REACTOS_STR_INTERNAL_NAME "rosperf\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "rosperf.exe\0"
+#include <reactos/version.rc>
--- /dev/null
+<module name="rosperf" type="win32cui" installbase="system32" installname="rosperf.exe">
+ <include base="rosperf">.</include>
+ <define name="__USE_W32API" />
+ <define name="UNICODE" />
+ <define name="WINVER">0x0500</define>
+ <library>version</library>
+ <library>msimg32</library>
+ <library>gdi32</library>
+ <library>user32</library>
+ <library>kernel32</library>
+ <library>ntdll</library>
+ <file>rosperf.c</file>
+ <file>lines.c</file>
+ <file>fill.c</file>
+ <file>text.c</file>
+ <file>alphablend.c</file>
+ <file>testlist.c</file>
+ <file>rosperf.rc</file>
+</module>
--- /dev/null
+/*
+ * ReactOS RosPerf - ReactOS GUI performance test program
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <windows.h>
+#include "rosperf.h"
+
+static TEST TestList[] =
+ {
+ { L"fill", L"Fill", NullInit, FillProc, NullCleanup, NullCleanup },
+ { L"smallfill", L"Small Fill", NullInit, FillSmallProc, NullCleanup, NullCleanup },
+ { L"hlines", L"Horizontal Lines", NullInit, LinesHorizontalProc, NullCleanup, NullCleanup },
+ { L"vlines", L"Vertical Lines", NullInit, LinesVerticalProc, NullCleanup, NullCleanup },
+ { L"lines", L"Lines", NullInit, LinesProc, NullCleanup, NullCleanup },
+ { L"text", L"Text", NullInit, TextProc, NullCleanup, NullCleanup },
+ { L"alpha", L"Alpha Blend", AlphaBlendInit, AlphaBlendProc, NullCleanup, AlphaBlendCleanup }
+ };
+
+
+void
+GetTests(unsigned *TestCount, PTEST *Tests)
+ {
+ *TestCount = sizeof(TestList) / sizeof(TEST);
+ *Tests = TestList;
+ }
+
+/* EOF */
--- /dev/null
+/*
+ * ReactOS RosPerf - ReactOS GUI performance test program
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <windows.h>
+#include "rosperf.h"
+
+void
+TextProc(void *Context, PPERF_INFO PerfInfo, unsigned Reps)
+{
+ unsigned Rep;
+ int y;
+ HDC Dc = NULL;
+ HFONT hfFont = GetStockObject(DEFAULT_GUI_FONT);
+
+ for (Rep = 0; Rep < Reps; )
+ {
+ Dc = (Rep & 0x10000) ? PerfInfo->BackgroundDc : PerfInfo->ForegroundDc;
+ SelectObject(Dc, hfFont);
+
+ for (y = 0; y < PerfInfo->WndHeight && Rep < Reps; Rep++, y += 15)
+ {
+ TextOut(Dc, 0, y, L"AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz:?<>0123456789", 66);
+ }
+ InvalidateRect(PerfInfo->Wnd, NULL, TRUE);
+ UpdateWindow(PerfInfo->Wnd);
+ }
+}
+
+/* EOF */
--- /dev/null
+//
+// EnumDirs.h
+//
+
+#ifndef __ENUMDIRS_H
+#define __ENUMDIRS_H
+
+//#include "win.h"
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+typedef BOOL (*MYENUMDIRSPROC) ( PWIN32_FIND_DATA, long );
+BOOL EnumDirs ( const TCHAR* szDirectory, const TCHAR* szFileSpec, MYENUMDIRSPROC pProc, long lParam );
+
+#endif//__ENUMDIRS_H
--- /dev/null
+//
+// EnumDirs.cpp
+//
+
+#include "EnumDirs.h"
+#include <stdio.h>
+
+#if defined(UNDER_CE) && !defined(assert)
+#define assert(x)
+#endif
+
+BOOL EnumDirs ( const TCHAR* szDirectory_, const TCHAR* szFileSpec, MYENUMDIRSPROC pProc, long lParam )
+{
+ assert ( szDirectory_ && szFileSpec && pProc );
+ TCHAR szDirectory[MAX_PATH+1];
+ TCHAR szSearchPath[MAX_PATH+1];
+ TCHAR szTemp[MAX_PATH+1];
+ _tcscpy ( szDirectory, szDirectory_ );
+ if ( szDirectory[_tcslen(szDirectory)-1] != '\\' )
+ _tcscat ( szDirectory, _T("\\") );
+ _sntprintf ( szSearchPath, _MAX_PATH, _T("%s%s"), szDirectory, szFileSpec );
+ WIN32_FIND_DATA wfd;
+ HANDLE hfind = FindFirstFile ( szSearchPath, &wfd );
+ if ( hfind == INVALID_HANDLE_VALUE )
+ return TRUE;
+ do
+ {
+ if ( !_tcscmp ( wfd.cFileName, _T(".") ) || !_tcscmp ( wfd.cFileName, _T("..") ) )
+ continue;
+ _sntprintf ( szTemp, _MAX_PATH, _T("%s%s"), szDirectory, wfd.cFileName );
+ if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+ {
+ if ( !pProc ( &wfd, lParam ) )
+ {
+ FindClose ( hfind );
+ return FALSE;
+ }
+ }
+ } while ( FindNextFile ( hfind, &wfd ) );
+ FindClose ( hfind );
+ return TRUE;
+}
--- /dev/null
+//
+// EnumFiles.h
+//
+
+#ifndef ENUMFILES_H
+#define ENUMFILES_H
+
+typedef BOOL (*MYENUMFILESPROC) ( PWIN32_FIND_DATA, const TCHAR*, long );
+BOOL EnumFilesInDirectory ( const TCHAR* szDirectory, const TCHAR* szFileSpec, MYENUMFILESPROC pProc, long lParam, BOOL bSubsToo, BOOL bSubsMustMatchFileSpec = FALSE );
+
+#endif//ENUMFILES_H
--- /dev/null
+//
+// EnumFilesImpl.h
+//
+
+#include "EnumFiles.h"
+#include "FixLFN.h"
+#include "safestr.h"
+#ifndef UNDER_CE
+#include <direct.h>
+#endif//UNDER_CE
+#include <stdio.h>
+
+BOOL EnumFilesInDirectory ( const TCHAR* szDirectory_, const TCHAR* szFileSpec, MYENUMFILESPROC pProc, long lParam, BOOL bSubsToo, BOOL bSubsMustMatchFileSpec )
+{
+ TCHAR szDirectory[MAX_PATH+1];
+ TCHAR szSearchPath[MAX_PATH+1];
+ TCHAR szTemp[MAX_PATH+1];
+
+ if ( safestrlen(szDirectory_) > MAX_PATH || !szFileSpec || !pProc )
+ return FALSE;
+ if ( szDirectory_ )
+ _tcscpy ( szDirectory, szDirectory_ );
+ else
+#ifdef UNDER_CE
+ _tcscpy ( szDirectory, _T("") );
+#else//UNDER_CE
+ getcwd ( szDirectory, sizeof(szDirectory)-1 );
+#endif//UNDER_CE
+ int dirlen = _tcslen(szDirectory);
+ if ( dirlen > 0 && szDirectory[dirlen-1] != '\\' )
+ _tcscat ( szDirectory, _T("\\") );
+
+ // first search for all files in directory that match szFileSpec...
+ _sntprintf ( szSearchPath, sizeof(szSearchPath)-1, _T("%s%s"), szDirectory, szFileSpec );
+ WIN32_FIND_DATA wfd;
+ HANDLE hfind = FindFirstFile ( szSearchPath, &wfd );
+ if ( hfind != INVALID_HANDLE_VALUE )
+ {
+ do
+ {
+ if ( !_tcscmp ( wfd.cFileName, _T(".") ) || !_tcscmp ( wfd.cFileName, _T("..") ) )
+ continue;
+ if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+ {
+ if ( !bSubsMustMatchFileSpec )
+ continue;
+ _sntprintf ( szTemp, sizeof(szTemp)-1, _T("%s%s"), szDirectory, wfd.cFileName );
+ if ( bSubsToo )
+ {
+ if ( !EnumFilesInDirectory ( szTemp, szFileSpec, pProc, lParam, bSubsToo, bSubsMustMatchFileSpec ) )
+ {
+ FindClose ( hfind );
+ return FALSE;
+ }
+ }
+ }
+ _sntprintf ( szTemp, sizeof(szTemp)-1, _T("%s%s"), szDirectory, wfd.cFileName );
+ FixLFN(szTemp,szTemp);
+ if ( !pProc ( &wfd, szTemp, lParam ) )
+ {
+ FindClose ( hfind );
+ return FALSE;
+ }
+ } while ( FindNextFile ( hfind, &wfd ) );
+ FindClose ( hfind );
+ }
+ if ( !bSubsToo || bSubsMustMatchFileSpec )
+ return TRUE;
+
+ // now search for all subdirectories...
+ _sntprintf ( szSearchPath, sizeof(szSearchPath)-1, _T("%s*.*"), szDirectory );
+ hfind = FindFirstFile ( szSearchPath, &wfd );
+ if ( hfind != INVALID_HANDLE_VALUE )
+ {
+ do
+ {
+ if ( !_tcscmp ( wfd.cFileName, _T(".") ) || !_tcscmp ( wfd.cFileName, _T("..") ) )
+ continue;
+ if ( !(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
+ continue;
+ _sntprintf ( szTemp, sizeof(szTemp)-1, _T("%s%s"), szDirectory, wfd.cFileName );
+ if ( FALSE == EnumFilesInDirectory ( szTemp, szFileSpec, pProc, lParam, bSubsToo, bSubsMustMatchFileSpec ) )
+ {
+ FindClose ( hfind );
+ return FALSE;
+ }
+ } while ( FindNextFile ( hfind, &wfd ) );
+ FindClose ( hfind );
+ }
+
+ return TRUE;
+}
--- /dev/null
+// File.cpp
+// This file is (C) 2002-2003 Royce Mitchell III and released under the BSD license
+
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif//_MSC_VER
+
+#include "File.h"
+
+bool File::open ( const char* filename, const char* mode )
+{
+ close();
+ _f = fopen ( filename, mode );
+ return _f != 0;
+}
+
+std::string File::getline ( bool strip_crlf /*= false*/ )
+{
+ std::string s = "";
+ char buf[256];
+ for ( ;; )
+ {
+ *buf = 0;
+ fgets ( buf, sizeof(buf)-1, _f );
+ if ( !*buf )
+ break;
+ s += buf;
+ if ( strchr ( "\r\n", buf[strlen(buf)-1] ) )
+ break;
+ }
+ if ( strip_crlf )
+ {
+ char* p = strpbrk ( &s[0], "\r\n" );
+ if ( p )
+ {
+ *p = '\0';
+ s.resize ( p-&s[0] );
+ }
+ }
+ return s;
+}
+
+// this function searches for the next end-of-line and puts all data it
+// finds until then in the 'line' parameter.
+//
+// call continuously until the function returns false ( no more data )
+bool File::next_line ( std::string& line, bool strip_crlf )
+{
+ line = getline(strip_crlf);
+ // indicate that we're done *if*:
+ // 1) there's no more data, *and*
+ // 2) we're at the end of the file
+ return line.size()>0 || !eof();
+}
+
+/*
+example usage:
+
+bool mycallback ( const std::string& line, int line_number, long lparam )
+{
+ std::cout << line << std::endl;
+ return true; // continue enumeration
+}
+
+File f ( "file.txt", "rb" ); // open file for binary read-only ( i.e. "rb" )
+f.enum_lines ( mycallback, 0, true );
+*/
+
+bool File::enum_lines ( bool (*callback)(const std::string& line, int line_number, long lparam), long lparam, bool strip_crlf )
+{
+ int line_number = 0;
+ for ( ;; )
+ {
+ std::string s = getline(strip_crlf);
+ line_number++;
+ if ( !s.size() )
+ {
+ if ( eof() )
+ return true;
+ else
+ continue;
+ }
+ if ( !(*callback) ( s, line_number, lparam ) )
+ return false;
+ }
+}
+
+size_t File::length()
+{
+#ifdef WIN32
+ return _filelength ( _fileno(_f) );
+#elif defined(UNIX)
+ struct stat file_stat;
+ verify(fstat(fileno(_f), &file_stat) == 0);
+ return file_stat.st_size;
+#endif
+}
+
+void File::close()
+{
+ if ( _f )
+ {
+ fclose(_f);
+ _f = 0;
+ }
+}
+
+/*static*/ bool File::LoadIntoString ( std::string& s, const char* filename )
+{
+ File in ( filename, "rb" );
+ if ( !in.isopened() )
+ return false;
+ size_t len = in.length();
+ s.resize ( len + 1 );
+ if ( !in.read ( &s[0], len ) )
+ return false;
+ s[len] = '\0';
+ s.resize ( len );
+ return true;
+}
+
+/*static*/ bool File::SaveFromString ( const char* filename, const std::string& s, bool binary )
+{
+ File out ( filename, binary ? "wb" : "w" );
+ if ( !out.isopened() )
+ return false;
+ out.write ( s.c_str(), s.size() );
+ return true;
+}
--- /dev/null
+// File.h
+// This file is (C) 2002-2003 Royce Mitchell III and released under the BSD license
+
+#ifndef FILE_H
+#define FILE_H
+
+#ifdef WIN32
+# include <io.h>
+#elif defined(UNIX)
+# include <sys/stat.h>
+# include <unistd.h>
+#endif
+#include <string>
+
+class File
+{
+public:
+ File() : _f(0)
+ {
+ }
+
+ File ( const char* filename, const char* mode ) : _f(0)
+ {
+ open ( filename, mode );
+ }
+
+ ~File()
+ {
+ close();
+ }
+
+ bool open ( const char* filename, const char* mode );
+
+ bool seek ( long offset )
+ {
+ return !fseek ( _f, offset, SEEK_SET );
+ }
+
+ int get()
+ {
+ return fgetc ( _f );
+ }
+
+ bool put ( int c )
+ {
+ return fputc ( c, _f ) != EOF;
+ }
+
+ std::string getline ( bool strip_crlf = false );
+
+ // this function searches for the next end-of-line and puts all data it
+ // finds until then in the 'line' parameter.
+ //
+ // call continuously until the function returns false ( no more data )
+ bool next_line ( std::string& line, bool strip_crlf );
+
+ /*
+ example usage:
+
+ bool mycallback ( const std::string& line, int line_number, long lparam )
+ {
+ std::cout << line << std::endl;
+ return true; // continue enumeration
+ }
+
+ File f ( "file.txt", "rb" ); // open file for binary read-only ( i.e. "rb" )
+ f.enum_lines ( mycallback, 0, true );
+ */
+
+ bool enum_lines ( bool (*callback)(const std::string& line, int line_number, long lparam), long lparam, bool strip_crlf );
+
+ bool read ( void* data, unsigned len )
+ {
+ return len == fread ( data, 1, len, _f );
+ }
+
+ bool write ( const void* data, unsigned len )
+ {
+ return len == fwrite ( data, 1, len, _f );
+ }
+
+ size_t length();
+
+ void close();
+
+ bool isopened()
+ {
+ return _f != 0;
+ }
+
+ bool eof()
+ {
+ return feof(_f) ? true : false;
+ }
+
+ FILE* operator * ()
+ {
+ return _f;
+ }
+
+ static bool LoadIntoString ( std::string& s, const char* filename );
+ static bool SaveFromString ( const char* filename, const std::string& s, bool binary );
+
+private:
+ File(const File&) {}
+ const File& operator = ( const File& ) { return *this; }
+
+ FILE * _f;
+};
+
+#endif//FILE_H
--- /dev/null
+//
+// FixLFN.h
+//
+
+#ifndef __FIXLFN_H
+#define __FIXLFN_H
+
+#include <string.h>
+#include <tchar.h>
+#include <shellapi.h>
+
+inline int FixLFN ( const TCHAR* pBadFileName, TCHAR* pGoodFileName )
+{
+ SHFILEINFO sfi;
+ TCHAR* p;
+
+ DWORD dwResult = SHGetFileInfo ( pBadFileName, 0, &sfi, sizeof(sfi), SHGFI_DISPLAYNAME );
+ if ( dwResult )
+ {
+ if ( pGoodFileName != pBadFileName )
+ _tcscpy ( pGoodFileName, pBadFileName );
+ if ( (p = _tcsrchr ( pGoodFileName, '\\' )) )
+ _tcscpy ( p+1, sfi.szDisplayName );
+ else if ( (p = _tcsrchr ( pGoodFileName, '/' )) )
+ _tcscpy ( p+1, sfi.szDisplayName );
+ else
+ _tcscpy ( pGoodFileName, sfi.szDisplayName );
+ }
+ return dwResult;
+}
+
+#endif//__FIXLFN_H
--- /dev/null
+// Header.h
+
+#ifndef HEADER_H
+#define HEADER_H
+
+#include "Symbol.h"
+
+class Header
+{
+public:
+ std::string filename;
+ std::vector<std::string> includes, libc_includes, pragmas;
+ std::vector<Symbol*> symbols;
+ bool done, externc;
+
+ std::vector<std::string> ifs, ifspreproc;
+
+ Header ( const std::string& filename_ )
+ : filename(filename_)
+ {
+ done = false;
+ externc = false;
+ }
+};
+
+#endif//HEADER_H
--- /dev/null
+// Symbol.h
+
+#ifndef SYMBOL_H
+#define SYMBOL_H
+
+#include "Type.h"
+
+class Symbol
+{
+public:
+ Type type;
+ std::vector<std::string> names;
+ std::vector<std::string> dependencies;
+ std::vector<std::string> ifs;
+ std::string definition;
+};
+
+#endif//SYMBOL_H
--- /dev/null
+// Type.h
+
+#ifndef TYPE_H
+#define TYPE_H
+
+typedef enum
+{
+ T_UNKNOWN = -1,
+ T_IGNORED_STATEMENT,
+ T_TIDENT,
+ T_MACRO,
+ T_DEFINE,
+ T_VARIABLE,
+ T_FUNCTION,
+ T_FUNCTION_PTR,
+ T_IF,
+ T_WHILE,
+ T_DO,
+ T_STRUCT
+} Type;
+
+#endif//TYPE_H
--- /dev/null
+//
+// assert.h
+//
+
+#ifndef __ASSERT_H
+#define __ASSERT_H
+
+#ifndef _MFC_VER
+#ifdef _WIN32_WCE
+
+#else//_WIN32_WCE
+ #include <assert.h>
+#endif//_WIN32_WCE
+#endif
+
+#ifndef ASSERT
+ #ifdef _DEBUG
+ #include <crtdbg.h>
+ #include <stdio.h> // _snprintf
+ //#ifndef WINVER
+ #ifdef _CONSOLE
+ #define ASSERT(x) if(!(x)){printf("ASSERT FAILURE: (%s) at %s:%i\n", #x, __FILE__, __LINE__); _CrtDbgBreak(); }
+ #else//_CONSOLE/WINVER
+ #define ASSERT(x) if(!(x)){char stmp_assert[1024+1]; _snprintf(stmp_assert,1024,"ASSERT FAILURE: (%s) at %s:%i\n",#x,__FILE__,__LINE__); ::MessageBox(NULL,stmp_assert,"Assertion Failure",MB_OK|MB_ICONSTOP); _CrtDbgBreak(); }
+ #endif//_CONSOLE/WINVER
+ #else//_DEBUG
+ #define ASSERT(x)
+ #endif//_DEBUG
+#endif//ASSERT
+
+#undef VERIFY
+#ifdef _DEBUG
+ #define VERIFY(x) ASSERT(x)
+#else//_DEBUG
+ #define VERIFY(x) x
+#endif//_DEBUG
+
+// code for ASSERTing in Release mode...
+#ifdef RELEASE_ASSERT
+ #undef ASSERT
+ #include <stdio.h>
+ #define ASSERT(x) if ( !(x) ) { char s[1024+1]; _snprintf(s,1024,"ASSERTION FAILURE:\n%s\n\n%s: line %i", #x, __FILE__, __LINE__ ); ::MessageBox(NULL,s,"Assertion Failure",MB_OK|MB_ICONERROR); }
+ #undef VERIFY
+ #define VERIFY ASSERT
+#endif//RELEASE_ASSERT
+
+#endif//__ASSERT_H
--- /dev/null
+// binary2cstr.cpp
+
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif//_MSC_VER
+
+#include "binary2cstr.h"
+
+using std::string;
+
+string binary2cstr ( const string& src )
+{
+ string dst;
+ for ( int i = 0; i < src.size(); i++ )
+ {
+ char c = src[i];
+ switch ( c )
+ {
+ case '\n':
+ dst += "\\n";
+ break;
+ case '\r':
+ dst += "\\r";
+ break;
+ case '\t':
+ dst += "\\t";
+ break;
+ case '\v':
+ dst += "\\v";
+ break;
+ case '\"':
+ dst += "\x22";
+ break;
+ default:
+ if ( isprint ( c ) )
+ dst += c;
+ else
+ {
+ dst += "\\x";
+ char tmp[16];
+ _snprintf ( tmp, sizeof(tmp)-1, "%02X", (unsigned)(unsigned char)c );
+ tmp[sizeof(tmp)-1] = '\0';
+ dst += tmp;
+ }
+ break;
+ }
+ }
+ return dst;
+}
\ No newline at end of file
--- /dev/null
+// binary2cstr.h
+
+#ifndef BINARY2CSTR_H
+#define BINARY2CSTR_H
+
+#include <string>
+
+std::string binary2cstr ( const std::string& src );
+
+#endif//BINARY2CSTR_H
--- /dev/null
+accctrl.h
+aclapi.h
+ascii.h
+base.h
+basetsd.h
+coff.h
+d3d.h
+d3dcaps.h
+d3dtypes.h
+ddentry.h
+ddraw.h
+debug.h
+defines.h
+devices.h
+epsapi.h
+errors.h
+excpt.h
+fmifs.h
+funcs.h
+getopt.h
+icmpapi.h
+ipexport.h
+iphlpapi.h
+ipifcons.h
+iprtrmib.h
+iptypes.h
+messages.h
+mmddk.h
+ndis.h
+ntddk.h
+ntos.h
+ntsecapi.h
+pe.h
+richedit.h
+roscfg.h
+roskrnl.h
+schemadef.h
+snmp.h
+sockets.h
+structs.h
+syssetup.h
+tchar.h
+tgetopt.h
+tmschema.h
+unicode.h
+uxtheme.h
+wdm.h
+wincrypt.h
+windows.h
+winsock2.h
+ws2spi.h
+wsahelp.h
+afd\shared.h
+csrss\csrss.h
+ddk\af_irda.h
+ddk\ccfuncs.h
+ddk\cctypes.h
+ddk\class2.h
+ddk\cmtypes.h
+ddk\d3dhal.h
+ddk\d3dnthal.h
+ddk\dbgfuncs.h
+ddk\ddrawi.h
+ddk\ddrawint.h
+ddk\defines.h
+ddk\exfuncs.h
+ddk\extypes.h
+ddk\fsfuncs.h
+ddk\fstypes.h
+ddk\halfuncs.h
+ddk\ioctrl.h
+ddk\iodef.h
+ddk\iofuncs.h
+ddk\iotypes.h
+ddk\kedef.h
+ddk\kefuncs.h
+ddk\ketypes.h
+ddk\ldrfuncs.h
+ddk\miniport.h
+ddk\mmfuncs.h
+ddk\mmtypes.h
+ddk\ntbootvid.h
+ddk\ntdd8042.h
+ddk\ntddbeep.h
+ddk\ntddblue.h
+ddk\ntddk.h
+ddk\ntddkbd.h
+ddk\ntddmou.h
+ddk\ntddscsi.h
+ddk\ntddser.h
+ddk\ntddvid.h
+ddk\ntdef.h
+ddk\ntifs.h
+ddk\obfuncs.h
+ddk\pnpfuncs.h
+ddk\pnptypes.h
+ddk\pofuncs.h
+ddk\potypes.h
+ddk\psfuncs.h
+ddk\pstypes.h
+ddk\scsi.h
+ddk\sefuncs.h
+ddk\setypes.h
+ddk\srb.h
+ddk\status.h
+ddk\structs.h
+ddk\types.h
+ddk\winddi.h
+ddk\i386\irql.h
+ddk\i386\pagesize.h
+dflat32\classdef.h
+dflat32\classes.h
+dflat32\commands.h
+dflat32\config.h
+dflat32\dflat.h
+dflat32\dflatmsg.h
+dflat32\dialbox.h
+dflat32\htree.h
+dflat32\keys.h
+dflat32\menu.h
+dflat32\rect.h
+dflat32\system.h
+dflat32\video.h
+fslib\vfatlib.h
+kernel32\cptable.h
+kernel32\error.h
+kernel32\heap.h
+kernel32\kernel32.h
+kernel32\lctable.h
+kernel32\nls.h
+kernel32\proc.h
+kernel32\process.h
+kernel32\thread.h
+kernel32\winnls.h
+libc\atexit.h
+libc\file.h
+libc\ieee.h
+lsass\lsass.h
+lsass\ntsecapi.h
+msvcrt\alloc.h
+msvcrt\assert.h
+msvcrt\conio.h
+msvcrt\crttypes.h
+msvcrt\ctype.h
+msvcrt\dir.h
+msvcrt\direct.h
+msvcrt\errno.h
+msvcrt\fcntl.h
+msvcrt\float.h
+msvcrt\io.h
+msvcrt\locale.h
+msvcrt\malloc.h
+msvcrt\math.h
+msvcrt\mbctype.h
+msvcrt\mbstring.h
+msvcrt\msvcrtdbg.h
+msvcrt\process.h
+msvcrt\search.h
+msvcrt\share.h
+msvcrt\signal.h
+msvcrt\stdarg.h
+msvcrt\stddef.h
+msvcrt\stdio.h
+msvcrt\stdlib.h
+msvcrt\string.h
+msvcrt\time.h
+msvcrt\wchar.h
+msvcrt\internal\atexit.h
+msvcrt\internal\console.h
+msvcrt\internal\file.h
+msvcrt\internal\ieee.h
+msvcrt\internal\rterror.h
+msvcrt\internal\stdio.h
+msvcrt\internal\tls.h
+msvcrt\sys\fcntl.h
+msvcrt\sys\file.h
+msvcrt\sys\locking.h
+msvcrt\sys\stat.h
+msvcrt\sys\time.h
+msvcrt\sys\timeb.h
+msvcrt\sys\types.h
+msvcrt\sys\unistd.h
+msvcrt\sys\utime.h
+napi\core.h
+napi\dbg.h
+napi\lpc.h
+napi\npipe.h
+napi\shared_data.h
+napi\teb.h
+napi\types.h
+napi\win32.h
+napi\i386\floatsave.h
+napi\i386\segment.h
+net\miniport.h
+net\ndis.h
+net\ndisoid.h
+net\netevent.h
+net\netpnp.h
+net\ntddndis.h
+net\ntddtdi.h
+net\tdi.h
+net\tdiinfo.h
+net\tdikrnl.h
+net\tdistat.h
+ntdll\base.h
+ntdll\csr.h
+ntdll\dbg.h
+ntdll\ldr.h
+ntdll\napi.h
+ntdll\ntdll.h
+ntdll\pagesize.h
+ntdll\rtl.h
+ntdll\trace.h
+ntos\bootvid.h
+ntos\cdrom.h
+ntos\console.h
+ntos\dbgfuncs.h
+ntos\disk.h
+ntos\except.h
+ntos\file.h
+ntos\fstypes.h
+ntos\gditypes.h
+ntos\halfuncs.h
+ntos\haltypes.h
+ntos\heap.h
+ntos\kdbgsyms.h
+ntos\kdfuncs.h
+ntos\kefuncs.h
+ntos\keyboard.h
+ntos\ldrtypes.h
+ntos\minmax.h
+ntos\mm.h
+ntos\ntdef.h
+ntos\obtypes.h
+ntos\port.h
+ntos\ps.h
+ntos\registry.h
+ntos\rtl.h
+ntos\rtltypes.h
+ntos\security.h
+ntos\service.h
+ntos\synch.h
+ntos\time.h
+ntos\tss.h
+ntos\types.h
+ntos\zw.h
+ntos\zwtypes.h
+ole32\basetyps.h
+ole32\guiddef.h
+ole32\objbase.h
+ole32\obj_base.h
+ole32\obj_cache.h
+ole32\obj_channel.h
+ole32\obj_clientserver.h
+ole32\obj_commdlgbrowser.h
+ole32\obj_connection.h
+ole32\obj_contextmenu.h
+ole32\obj_control.h
+ole32\obj_dataobject.h
+ole32\obj_dockingwindowframe.h
+ole32\obj_dragdrop.h
+ole32\obj_enumidlist.h
+ole32\obj_errorinfo.h
+ole32\obj_extracticon.h
+ole32\obj_inplace.h
+ole32\obj_marshal.h
+ole32\obj_misc.h
+ole32\obj_moniker.h
+ole32\obj_oleaut.h
+ole32\obj_olefont.h
+ole32\obj_oleobj.h
+ole32\obj_oleundo.h
+ole32\obj_oleview.h
+ole32\obj_picture.h
+ole32\obj_property.h
+ole32\obj_propertystorage.h
+ole32\obj_queryassociations.h
+ole32\obj_serviceprovider.h
+ole32\obj_shellbrowser.h
+ole32\obj_shellextinit.h
+ole32\obj_shellfolder.h
+ole32\obj_shelllink.h
+ole32\obj_shellview.h
+ole32\obj_storage.h
+ole32\obj_webbrowser.h
+ole32\ole32.h
+ole32\olectl.h
+ole32\rpc.h
+ole32\rpcdce.h
+ole32\rpcdcep.h
+ole32\unknwn.h
+ole32\winerror.h
+ole32\wtypes.h
+reactos\bugcodes.h
+reactos\buildno.h
+reactos\config.h
+reactos\errcodes.h
+reactos\resource.h
+reactos\version.h
+rosrtl\devmode.h
+rosrtl\logfont.h
+rosrtl\thread.h
+services\services.h
+user32\accel.h
+user32\callback.h
+user32\regcontrol.h
+user32\wininternal.h
+win32k\bitmaps.h
+win32k\brush.h
+win32k\cliprgn.h
+win32k\color.h
+win32k\coord.h
+win32k\cursoricon.h
+win32k\dc.h
+win32k\debug.h
+win32k\debug1.h
+win32k\driver.h
+win32k\fillshap.h
+win32k\float.h
+win32k\gdiobj.h
+win32k\icm.h
+win32k\kapi.h
+win32k\line.h
+win32k\math.h
+win32k\metafile.h
+win32k\misc.h
+win32k\ntddraw.h
+win32k\ntuser.h
+win32k\paint.h
+win32k\path.h
+win32k\pen.h
+win32k\print.h
+win32k\region.h
+win32k\text.h
+win32k\userobj.h
+win32k\win32k.h
+win32k\wingl.h
+wine\commctrl.h
+wine\config.h
+wine\debug.h
+wine\debugtools.h
+wine\port.h
+wine\prsht.h
+wine\test.h
+wine\unicode.h
+wine\vfw.h
+wine\windef16.h
+wine\wineros.h
+wine\winuser.h
--- /dev/null
+// iskeyword.cpp
+
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif//_MSC_VER
+
+#include <string>
+
+#include "iskeyword.h"
+
+using std::string;
+
+bool iskeyword ( const string& ident )
+{
+#define I(s) if ( ident == #s ) return true;
+ switch ( ident[0] )
+ {
+ case '_':
+ I(__cdecl);
+ I(__declspec);
+ I(__except);
+ I(__fastcall);
+ I(__finally);
+ I(__inline);
+ I(__int8);
+ I(__int16);
+ I(__int32);
+ I(__int64);
+ I(__leave);
+ I(__stdcall);
+ I(__try);
+ break;
+ case 'b':
+ I(bool);
+ I(break);
+ break;
+ case 'c':
+ I(case);
+ I(catch);
+ I(char);
+ I(class);
+ I(const);
+ I(const_cast);
+ I(continue);
+ break;
+ case 'd':
+ I(default);
+ I(delete);
+ I(dllexport);
+ I(dllimport);
+ I(do);
+ I(double);
+ I(dynamic_cast);
+ break;
+ case 'e':
+ I(else);
+ I(enum);
+ I(explicit);
+ I(extern);
+ break;
+ case 'f':
+ I(false);
+ I(float);
+ I(for);
+ I(friend);
+ break;
+ case 'g':
+ I(goto);
+ break;
+ case 'i':
+ I(if);
+ I(inline);
+ I(int);
+ break;
+ case 'l':
+ I(long);
+ break;
+ case 'm':
+ I(mutable);
+ break;
+ case 'n':
+ I(naked);
+ I(namespace);
+ I(new);
+ I(noreturn);
+ break;
+ case 'o':
+ I(operator);
+ break;
+ case 'p':
+ I(private);
+ I(protected);
+ I(public);
+ break;
+ case 'r':
+ I(register);
+ I(reinterpret_cast);
+ I(return);
+ break;
+ case 's':
+ I(short);
+ I(signed);
+ I(sizeof);
+ I(static);
+ I(static_cast);
+ I(struct);
+ I(switch);
+ break;
+ case 't':
+ I(template);
+ I(this);
+ I(thread);
+ I(throw);
+ I(true);
+ I(try);
+ I(typedef);
+ I(typeid);
+ I(typename);
+ break;
+ case 'u':
+ I(union);
+ I(unsigned);
+ I(using);
+ I(uuid);
+ I(__uuidof);
+ break;
+ case 'v':
+ I(virtual);
+ I(void);
+ I(volatile);
+ break;
+ case 'w':
+ I(wmain);
+ I(while);
+ break;
+ }
+ return false;
+}
--- /dev/null
+// iskeyword.h
+
+#ifndef ISKEYWORD_H
+#define ISKEYWORD_H
+
+bool iskeyword ( const std::string& ident );
+
+#endif//ISKEYWORD_H
--- /dev/null
+//
+// safestr.h
+//
+// safe versions of some string manipulation routines
+//
+
+#ifndef __SAFESTR_H
+#define __SAFESTR_H
+
+#include <tchar.h>
+
+#ifndef tchar
+#define tchar TCHAR
+#endif//tchar
+
+#include <string.h>
+#include "assert.h"
+
+inline size_t safestrlen ( const tchar *string )
+{
+ if ( !string )
+ return 0;
+ return _tcslen(string);
+}
+
+inline tchar* safestrcpy ( tchar* strDest, const tchar* strSource )
+{
+ ASSERT(strDest);
+ if ( !strSource )
+ *strDest = 0;
+ else
+ _tcscpy ( strDest, strSource );
+ return strDest;
+}
+
+inline tchar* safestrncpy ( tchar* strDest, const tchar* strSource, size_t count )
+{
+ ASSERT(strDest);
+ if ( !strSource )
+ count = 0;
+ else
+ _tcsncpy ( strDest, strSource, count );
+ strDest[count] = 0;
+ return strDest;
+}
+
+inline tchar* safestrlwr ( tchar* str )
+{
+ if ( !str )
+ return 0;
+ return _tcslwr(str);
+}
+
+inline tchar* safestrupr ( tchar* str )
+{
+ if ( !str )
+ return 0;
+ return _tcsupr(str);
+}
+
+#endif//__SAFESTR_H
--- /dev/null
+// sdkparse.cpp
+
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif//_MSC_VER
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <string>
+#include <vector>
+#include <conio.h>
+
+#include "EnumFilesImpl.h"
+
+#include "assert.h"
+#include "File.h"
+#include "binary2cstr.h"
+#include "strip_comments.h"
+#include "tokenize.h"
+#include "skip_ws.h"
+#include "iskeyword.h"
+#include "Type.h"
+#include "Header.h"
+
+#define TOKASSERT(x) \
+if(!(x))\
+{\
+ printf("ASSERT FAILURE: (%s) at %s:%i\n", #x, __FILE__, __LINE__);\
+ printf("WHILE PROCESSING: \n");\
+ for ( int ajf83pfj = 0; ajf83pfj < tokens.size(); ajf83pfj++ )\
+ printf("%s ", tokens[ajf83pfj].c_str() );\
+ printf("\n");\
+ _CrtDbgBreak();\
+}
+using std::string;
+using std::vector;
+
+vector<Header*> headers;
+
+bool import_file ( const char* filename );
+char* findend ( char* p, bool& externc );
+Type identify ( const vector<string>& tokens, int off = 0 );
+Type process ( const string& element, vector<string>& names, bool& isTypedef, vector<string>& dependencies );
+void process_preprocessor ( const char* filename, Header& h, const string& element );
+void process_c ( Header& h, const string& element );
+int parse_type ( Type t, const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
+int parse_ignored_statement ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
+int parse_tident ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
+int parse_variable ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
+int parse_struct ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
+int parse_function ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
+int parse_function_ptr ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
+int parse_ifwhile ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
+int parse_do ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
+
+const char* libc_includes[] =
+{
+ "basestd.h",
+ "except.h",
+ "float.h",
+ "limits.h",
+ "stdarg.h",
+ "stddef.h",
+ "stdlib.h",
+ "string.h",
+ "types.h"
+};
+
+bool is_libc_include ( const string& inc )
+{
+ string s ( inc );
+ strlwr ( &s[0] );
+ for ( int i = 0; i < sizeof(libc_includes)/sizeof(libc_includes[0]); i++ )
+ {
+ if ( s == libc_includes[i] )
+ return true;
+ }
+ return false;
+}
+
+BOOL FileEnumProc ( PWIN32_FIND_DATA pwfd, const char* filename, long lParam )
+{
+ if ( !is_libc_include ( filename ) )
+ import_file ( filename );
+ return TRUE;
+}
+
+void main()
+{
+ //import_file ( "coff.h" );
+
+ File f ( "input.lst", "r" );
+ if ( !f.isopened() )
+ {
+ printf ( "Couldn't open \"input.lst\" for input\nPress any key to exit\n" );
+ (void)getch();
+ return;
+ }
+ string filename;
+ while ( f.next_line ( filename, true ) )
+ import_file ( filename.c_str() );
+ //printf ( "press any key to start\n" );
+ //getch();
+/*#if 1
+ import_file ( "../test.h" );
+#else
+ EnumFilesInDirectory ( "c:/cvs/reactos/apps/utils/sdkparse/include", "*.h", FileEnumProc, 0, TRUE, FALSE );
+#endif*/
+ printf ( "Done!\nPress any key to exit!\n" );
+ (void)getch();
+}
+
+bool import_file ( const char* filename )
+{
+ int i;
+
+ for ( i = 0; i < headers.size(); i++ )
+ {
+ if ( headers[i]->filename == filename )
+ return true;
+ }
+
+ string s;
+ if ( !File::LoadIntoString ( s, filename ) )
+ {
+ printf ( "Couldn't load \"%s\" for input.\n", filename );
+ ASSERT(0);
+ }
+
+ printf ( "%s\n", filename );
+
+ // strip comments from the file...
+ strip_comments ( s, true );
+
+ /*{
+ string no_comments ( filename );
+ no_comments += ".nocom.txt";
+ File::SaveFromString ( no_comments.c_str(), s, false );
+ }*/
+
+ Header* h = new Header ( filename );
+ headers.push_back ( h );
+
+ char* p = &s[0];
+ while ( p )
+ {
+ // skip whitespace
+ p = skip_ws ( p );
+ if ( !*p )
+ break;
+ // check for pre-processor command
+ if ( *p == '#' )
+ {
+ char* end = strchr ( p, '\n' );
+ while ( end && end[-1] == '\\' )
+ end = strchr ( end+1, '\n' );
+ if ( !end )
+ end = p + strlen(p);
+ string element ( p, end-p );
+
+ process_preprocessor ( filename, *h, element );
+
+ p = end;
+ }
+ else if ( *p == '}' && h->externc )
+ {
+ p++;
+ p = skip_ws ( p );
+
+ if ( *p == ';' ) p++;
+ }
+ else
+ {
+ bool externc = false;
+ char* end = findend ( p, externc );
+ ASSERT(end);
+ if ( externc )
+ h->externc = true;
+ else
+ {
+ string element ( p, end-p );
+
+ process_c ( *h, element );
+ }
+ p = end;
+ }
+ }
+ h->done = true;
+ return true;
+}
+
+string get_hdrguardtext ( const char* filename )
+{
+ string s ( filename );
+ char* p = &s[0];
+ char* p2;
+ while ( (p2 = strchr(p, '\\')) )
+ *p2 = '/';
+ while ( (p2 = strchr(p,'/')) )
+ p = p2 + 1;
+ char* end = strchr ( p, '.' );
+ ASSERT(end);
+ while ( (p2 = strchr(end+1,'.')) )
+ end = p2;
+ string hdrguardtext ( p, end-p );
+ strupr ( &hdrguardtext[0] );
+ return hdrguardtext;
+}
+
+void process_preprocessor ( const char* filename, Header& h, const string& element )
+{
+ string hdrguardtext ( get_hdrguardtext ( filename ) );
+
+ const char* p = &element[0];
+ ASSERT ( *p == '#' );
+ p++;
+ p = skip_ws ( p );
+ const char* end = p;
+ while ( iscsym(*end) )
+ end++;
+ string preproc ( p, end-p );
+ p = end+1;
+ p = skip_ws ( p );
+
+ const string dbg_filename = "napi/lpc.h DISABLE DISABLE DISABLE";
+
+ if ( preproc == "include" )
+ {
+ //if ( h.filename == "napi/lpc.h" )
+ // _CrtDbgBreak();
+ ASSERT ( *p == '<' || *p == '\"' );
+ p++;
+ p = skip_ws ( p );
+ const char* end = strpbrk ( p, ">\"" );
+ if ( !end )
+ end = p + strlen(p);
+ while ( end > p && isspace(end[-1]) )
+ end--;
+ string include_filename ( p, end-p );
+ if ( is_libc_include ( include_filename ) )
+ h.libc_includes.push_back ( include_filename );
+ else
+ {
+ bool loaded = false;
+ for ( int i = 0; i < headers.size() && !loaded; i++ )
+ {
+ if ( headers[i]->filename == include_filename )
+ {
+ if ( !headers[i]->done )
+ {
+ printf ( "circular dependency between '%s' and '%s'\n", filename, include_filename.c_str() );
+ ASSERT ( 0 );
+ }
+ loaded = true;
+ }
+ }
+ if ( !loaded )
+ {
+ printf ( "(diverting to '%s')\n", include_filename.c_str() );
+ import_file ( include_filename.c_str() );
+ printf ( "(now back to '%s')\n", filename );
+ }
+ h.includes.push_back ( include_filename );
+ }
+ }
+ else if ( preproc == "define" )
+ {
+ size_t len = element.size();
+ if ( strstr ( element.c_str(), hdrguardtext.c_str() )
+ && element[len-2] == '_'
+ && element[len-1] == 'H' )
+ {
+ // header include guard... ignore!
+ return;
+ }
+ Symbol *s = new Symbol;
+ s->type = T_DEFINE;
+
+ p += 6;
+ p = skip_ws ( p );
+
+ const char* end = p;
+ while ( iscsym(*end) )
+ end++;
+
+ s->names.push_back ( string(p,end-p) );
+
+ s->definition = element;
+
+ h.symbols.push_back ( s );
+ }
+ else if ( preproc == "undef" )
+ {
+ // safely ignoreable for now, I think
+ }
+ else if ( preproc == "if" || preproc == "ifdef" || preproc == "ifndef" )
+ {
+ if ( dbg_filename == h.filename )
+ printf ( "(%s) PRE-PUSH preproc stack = %lu\n", preproc.c_str(), h.ifs.size() );
+ size_t len = element.size();
+ // check for header include guard...
+ if ( strstr ( element.c_str(), hdrguardtext.c_str() )
+ && element[len-2] == '_'
+ && element[len-1] == 'H' )
+ h.ifs.push_back ( string("") );
+ else
+ h.ifs.push_back ( element );
+ h.ifspreproc.push_back ( preproc );
+ if ( dbg_filename == h.filename )
+ printf ( "POST-PUSH preproc stack = %lu\n", h.ifs.size() );
+ }
+ else if ( preproc == "endif" )
+ {
+ if ( dbg_filename == h.filename )
+ printf ( "(%s) PRE-POP preproc stack = %lu\n", preproc.c_str(), h.ifs.size() );
+ ASSERT ( h.ifs.size() > 0 && h.ifs.size() == h.ifspreproc.size() );
+ h.ifs.pop_back();
+ h.ifspreproc.pop_back();
+ if ( dbg_filename == h.filename )
+ printf ( "POST-POP preproc stack = %lu\n", h.ifs.size() );
+ }
+ else if ( preproc == "elif" )
+ {
+ if ( dbg_filename == h.filename )
+ printf ( "(%s) PRE-PUSHPOP preproc stack = %lu\n", preproc.c_str(), h.ifs.size() );
+ string& oldpre = h.ifspreproc.back();
+ string old = h.ifs.back();
+ string condold;
+ if ( oldpre == "ifdef" )
+ condold = string("!defined(") + old + ")";
+ else if ( oldpre == "ifndef" )
+ condold = string("defined(") + old + ")";
+ else if ( oldpre == "if" )
+ condold = string("!(") + old + ")";
+ else
+ {
+ printf ( "unrecognized preproc '%s'\n", oldpre.c_str() );
+ ASSERT(0);
+ return;
+ }
+ h.ifs.back() = string("(") + element + ") && " + condold;
+ h.ifspreproc.back() = "if";
+ if ( dbg_filename == h.filename )
+ printf ( "POST-PUSHPOP preproc stack = %lu\n", h.ifs.size() );
+ }
+ else if ( preproc == "else" )
+ {
+ if ( dbg_filename == h.filename )
+ printf ( "(%s) PRE-PUSHPOP preproc stack = %lu\n", preproc.c_str(), h.ifs.size() );
+ string& oldpre = h.ifspreproc.back();
+ ASSERT ( oldpre != "else" );
+ if ( oldpre == "ifdef" )
+ h.ifs.back() = "ifndef";
+ else if ( oldpre == "ifndef" )
+ h.ifs.back() = "ifdef";
+ else if ( oldpre == "if" )
+ h.ifs.back() = string("!(") + h.ifs.back() + ")";
+ else
+ {
+ printf ( "unrecognized preproc '%s'\n", oldpre.c_str() );
+ ASSERT(0);
+ return;
+ }
+ oldpre = "else";
+ if ( dbg_filename == h.filename )
+ printf ( "POST-PUSHPOP preproc stack = %lu\n", h.ifs.size() );
+ }
+ else if ( preproc == "include_next" )
+ {
+ // we can safely ignore this command...
+ }
+ else if ( preproc == "pragma" )
+ {
+ h.pragmas.push_back ( element );
+ }
+ else if ( preproc == "error" )
+ {
+ // FIXME - how to handle these
+ }
+ else
+ {
+ printf ( "process_preprocessor() choked on '%s'\n", preproc.c_str() );
+ }
+}
+
+void process_c ( Header& h, const string& element )
+{
+ //printf ( "\"%s\"\n\n", binary2cstr(element).c_str() );
+
+ bool isTypedef;
+
+ Symbol *s = new Symbol;
+ s->definition = element;
+ s->type = process ( element, s->names, isTypedef, s->dependencies );
+
+ for ( int i = 0; i < h.ifs.size(); i++ )
+ {
+ if ( h.ifs[i].size() )
+ s->ifs.push_back ( h.ifs[i] );
+ }
+
+ /*printf ( "names: " );
+ if ( s->names.size() )
+ {
+ printf ( "%s", s->names[0].c_str() );
+ for ( int i = 1; i < s->names.size(); i++ )
+ printf ( ", %s", s->names[i].c_str() );
+ }
+ else
+ printf ( "(none)" );
+ printf ( "\n\n" );
+
+ printf ( "dependencies: " );
+ if ( s->dependencies.size() )
+ {
+ printf ( "%s", s->dependencies[0].c_str() );
+ for ( int i = 1; i < s->dependencies.size(); i++ )
+ printf ( ", %s", s->dependencies[i].c_str() );
+ }
+ else
+ printf ( "(none)" );
+ printf ( "\n\n" );*/
+
+ h.symbols.push_back ( s );
+}
+
+char* skipsemi ( char* p )
+{
+ if ( *p != '{' ) // }
+ {
+ ASSERT(0);
+ }
+ p++;
+ for ( ;; )
+ {
+ char* s = strchr ( p, '{' );
+ char* e = strchr ( p, '}' );
+ if ( !e )
+ e = p + strlen(p);
+ if ( !s || s > e )
+ {
+ // make sure we don't return pointer past null
+ if ( *e )
+ return e + 1;
+ else
+ return e;
+ }
+ p = skipsemi ( s );
+ }
+}
+
+char* findend ( char* p, bool& externc )
+{
+ //if ( !strncmp ( p, "typedef struct _OSVERSIONINFOEXA : ", 35 ) )
+ // _CrtDbgBreak();
+ // special-case for 'extern "C"'
+ if ( !strncmp ( p, "extern", 6 ) )
+ {
+ char* p2 = p + 6;
+ p2 = skip_ws ( p2 );
+ if ( !strncmp ( p2, "\"C\"", 3 ) )
+ {
+ p2 += 3;
+ p2 = skip_ws ( p2 );
+ if ( *p2 == '{' )
+ {
+ externc = true;
+ return p2+1;
+ }
+ }
+ }
+ // special-case for 'typedef_tident'
+ if ( !strncmp ( p, "typedef_tident", 14 ) )
+ {
+ char* end = strchr ( p, ')' );
+ ASSERT(end);
+ return end+1;
+ }
+ externc = false;
+ bool isStruct = false;
+
+ char* end = strchr ( p, ';' );
+ if ( !end )
+ end = p + strlen(p);
+ else
+ end++;
+ char* semi = strchr ( p, '{' );
+ if ( !semi || semi > end )
+ return end;
+ end = skipsemi ( semi );
+
+ const char* structs[] = { "struct", "enum", "class", "union" };
+ for ( int i = 0; i < sizeof(structs)/sizeof(structs[0]); i++ )
+ {
+ char* pStruct = strstr ( p, structs[i] );
+ if ( pStruct
+ && pStruct < semi
+ && !__iscsym(pStruct[-1])
+ && !__iscsym(pStruct[strlen(structs[i])]) )
+ {
+ // make sure there's at most one identifier followed
+ // by a {
+ pStruct += strlen(structs[i]);
+ pStruct = skip_ws ( pStruct );
+ if ( __iscsymf(*pStruct) )
+ {
+ while ( __iscsym(*pStruct) )
+ pStruct++;
+ pStruct = skip_ws ( pStruct );
+ }
+ // special exception - C++ classes & stuff
+ if ( *pStruct == ':' )
+ {
+ pStruct = skip_ws ( pStruct + 1 );
+ ASSERT ( !strncmp(pStruct,"public",6) || !strncmp(pStruct,"protected",9) || !strncmp(pStruct,"private",7) );
+ // skip access:
+ while ( __iscsym(*pStruct) )
+ pStruct++;
+ pStruct = skip_ws ( pStruct );
+ // skip base-class-name:
+ ASSERT ( __iscsymf(*pStruct) );
+ while ( __iscsym(*pStruct) )
+ pStruct++;
+ pStruct = skip_ws ( pStruct );
+ }
+ if ( *pStruct == '{' )
+ isStruct = true;
+ break;
+ }
+ }
+
+ if ( isStruct )
+ {
+ end = strchr ( end, ';' );
+ if ( !end )
+ end = p + strlen(p);
+ else
+ end++;
+ }
+ else
+ {
+ char* p2 = skip_ws ( end );
+ if ( *p2 == ';' )
+ end = p2 + 1;
+ }
+ return end;
+}
+
+int skip_declspec ( const vector<string>& tokens, int off )
+{
+ if ( tokens[off] == "__declspec" )
+ {
+ off++;
+ TOKASSERT ( tokens[off] == "(" );
+ off++;
+ int parens = 1;
+ while ( parens )
+ {
+ if ( tokens[off] == "(" )
+ parens++;
+ else if ( tokens[off] == ")" )
+ parens--;
+ off++;
+ }
+ }
+ return off;
+}
+
+Type identify ( const vector<string>& tokens, int off )
+{
+ off = skip_declspec ( tokens, off );
+ /*if ( tokens.size() > off+4 )
+ {
+ if ( tokens[off+4] == "PCONTROLDISPATCHER" )
+ _CrtDbgBreak();
+ }*/
+ /*if ( tokens.size() > off+1 )
+ {
+ if ( tokens[off+1] == "_OSVERSIONINFOEXA" )
+ _CrtDbgBreak();
+ }*/
+ if ( tokens[off] == "__asm__" )
+ return T_IGNORED_STATEMENT;
+ else if ( tokens[off] == "return" )
+ return T_IGNORED_STATEMENT;
+ else if ( tokens[off] == "typedef_tident" )
+ return T_TIDENT;
+ else if ( tokens[off] == "if" )
+ return T_IF;
+ else if ( tokens[off] == "while" )
+ return T_WHILE;
+ else if ( tokens[off] == "do" )
+ return T_DO;
+ int openparens = 0;
+ int closeparens = 0;
+ int brackets = 0;
+ for ( int i = off; i < tokens.size(); i++ )
+ {
+ if ( tokens[i] == "(" && !brackets )
+ openparens++;
+ else if ( tokens[i] == ")" && !brackets && openparens == 1 )
+ closeparens++;
+ else if ( tokens[i] == "{" )
+ brackets++;
+ else if ( (tokens[i] == "struct" || tokens[i] == "union") && !openparens )
+ {
+ for ( int j = i + 1; j < tokens.size(); j++ )
+ {
+ if ( tokens[j] == "{" )
+ return T_STRUCT;
+ else if ( tokens[j] == "(" || tokens[j] == ";" || tokens[j] == "*" )
+ break;
+ }
+ }
+ else if ( tokens[i] == ";" )
+ break;
+ else if ( tokens[i] == "__attribute__" )
+ break;
+ }
+ if ( openparens > 1 && closeparens )
+ return T_FUNCTION_PTR;
+ else if ( openparens >= 1 )
+ return T_FUNCTION;
+ return T_VARIABLE;
+}
+
+Type process ( const string& element, vector<string>& names, bool& isTypedef, vector<string>& dependencies )
+{
+ names.resize ( 0 );
+ isTypedef = false;
+ dependencies.resize ( 0 );
+
+ vector<string> tokens;
+
+ tokenize ( element, tokens );
+
+ // now let's do the classification...
+ int i = 0;
+ if ( tokens[i] == "typedef" )
+ {
+ isTypedef = true;
+ i++;
+ }
+
+ Type t = identify ( tokens, i );
+
+ parse_type ( t, tokens, i, names, dependencies );
+
+ return t;
+}
+
+int parse_type ( Type t, const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
+{
+ switch ( t )
+ {
+ case T_IGNORED_STATEMENT:
+ return parse_ignored_statement ( tokens, off, names, dependencies );
+ case T_TIDENT:
+ return parse_tident ( tokens, off, names, dependencies );
+ case T_VARIABLE:
+ return parse_variable ( tokens, off, names, dependencies );
+ case T_STRUCT:
+ return parse_struct ( tokens, off, names, dependencies );
+ case T_FUNCTION:
+ return parse_function ( tokens, off, names, dependencies );
+ case T_FUNCTION_PTR:
+ return parse_function_ptr ( tokens, off, names, dependencies );
+ case T_IF:
+ case T_WHILE:
+ return parse_ifwhile ( tokens, off, names, dependencies );
+ case T_DO:
+ return parse_do ( tokens, off, names, dependencies );
+ default:
+ TOKASSERT(!"unidentified type in parse_type()");
+ return 0;
+ }
+}
+
+void name ( const string& ident, vector<string>& names )
+{
+ if ( !__iscsymf ( ident[0] ) )
+ return;
+ if ( iskeyword ( ident ) )
+ return;
+ for ( int i = 0; i < names.size(); i++ )
+ {
+ if ( names[i] == ident )
+ return;
+ }
+ names.push_back ( ident );
+}
+
+void depend ( const string& ident, vector<string>& dependencies )
+{
+ if ( !__iscsymf ( ident[0] ) )
+ return;
+ if ( iskeyword ( ident ) )
+ return;
+ for ( int i = 0; i < dependencies.size(); i++ )
+ {
+ if ( dependencies[i] == ident )
+ return;
+ }
+ dependencies.push_back ( ident );
+}
+
+int parse_ignored_statement ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
+{
+ off++;
+ while ( tokens[off] != ";" )
+ off++;
+ ASSERT ( tokens[off] == ";" );
+ return off + 1;
+}
+
+int parse_tident ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
+{
+ TOKASSERT ( tokens[off] == "typedef_tident" );
+ TOKASSERT ( tokens[off+1] == "(" && tokens[off+3] == ")" );
+ names.push_back ( tokens[off+2] );
+ dependencies.push_back ( "typedef_tident" );
+ return off + 4;
+}
+
+int parse_variable ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
+{
+ // NOTE - Test with bitfields, I think this code will actually handle them properly...
+ if ( tokens[off] == ";" )
+ return off + 1;
+ depend ( tokens[off++], dependencies );
+ int done = tokens.size();
+ while ( off < tokens.size() && tokens[off] != ";" )
+ name ( tokens[off++], names );
+ TOKASSERT ( off < tokens.size() && tokens[off] == ";" );
+ return off + 1;
+}
+
+int parse_struct ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
+{
+ int done = tokens.size();
+
+ //if ( tokens[off+1] == "_LARGE_INTEGER" )
+ // _CrtDbgBreak();
+
+ while ( off < done && tokens[off] != "struct" && tokens[off] != "union" )
+ depend ( tokens[off++], dependencies );
+
+ TOKASSERT ( tokens[off] == "struct" || tokens[off] == "union" );
+ if ( tokens[off] != "struct" && tokens[off] != "union" )
+ return off;
+ off++;
+
+ if ( tokens[off] != "{" )
+ name ( tokens[off++], names );
+
+ if ( tokens[off] == ":" )
+ {
+ off++;
+ TOKASSERT ( tokens[off] == "public" || tokens[off] == "protected" || tokens[off] == "private" );
+ off++;
+ depend ( tokens[off++], dependencies );
+ }
+
+ TOKASSERT ( tokens[off] == "{" );
+ off++;
+
+ // skip through body of struct - noting any dependencies
+ int indent = 1;
+ //if ( off >= done ) _CrtDbgBreak();
+ while ( off < done && tokens[off] != "}" )
+ {
+ vector<string> fauxnames;
+ Type t = identify ( tokens, off );
+ off = parse_type ( t, tokens, off, fauxnames, dependencies );
+ //if ( off >= done ) _CrtDbgBreak();
+ }
+
+ // process any trailing dependencies/names...
+ while ( tokens[off] != ";" )
+ {
+ TOKASSERT ( off+1 < done );
+ if ( tokens[off+1] == "," || tokens[off+1] == ";" )
+ name ( tokens[off], names );
+ else
+ depend ( tokens[off], dependencies );
+ off++;
+ }
+
+ TOKASSERT ( tokens[off] == ";" );
+ off++;
+
+ return off;
+}
+
+int parse_param ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
+{
+ if ( tokens[off] == ")" )
+ return off;
+ // special-case check for function pointer params
+ int done = off;
+ int parens = 1;
+ bool fptr = false;
+ for ( ;; )
+ {
+ if ( tokens[done] == "," && parens == 1 )
+ break;
+ if ( tokens[done] == ")" )
+ {
+ if ( parens == 1 )
+ break;
+ else
+ parens--;
+ }
+ if ( tokens[done] == "(" )
+ parens++;
+ if ( tokens[done] == "*" && tokens[done-1] == "(" )
+ fptr = true;
+ done++;
+ }
+ if ( !fptr )
+ done--;
+ while ( off < done )
+ depend ( tokens[off++], dependencies );
+ if ( !fptr )
+ name ( tokens[off++], names );
+ return off;
+}
+
+int parse_function ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
+{
+ vector<string> fauxnames;
+
+ off = skip_declspec ( tokens, off );
+
+ while ( tokens[off+1] != "(" )
+ depend ( tokens[off++], dependencies );
+ name ( tokens[off++], names );
+
+ TOKASSERT ( tokens[off] == "(" );
+
+ while ( tokens[off] != ")" )
+ {
+ off++;
+ off = parse_param ( tokens, off, fauxnames, dependencies );
+ TOKASSERT ( tokens[off] == "," || tokens[off] == ")" );
+ }
+
+ off++;
+
+ // check for "attributes"
+ if ( tokens[off] == "__attribute__" )
+ {
+ off++;
+ TOKASSERT ( tokens[off] == "(" );
+ off++;
+ int parens = 1;
+ while ( parens )
+ {
+ if ( tokens[off] == "(" )
+ parens++;
+ else if ( tokens[off] == ")" )
+ parens--;
+ off++;
+ }
+ }
+
+ // is this just a function *declaration* ?
+ if ( tokens[off] == ";" )
+ return off;
+
+ // we have a function body...
+ TOKASSERT ( tokens[off] == "{" );
+ off++;
+
+ while ( tokens[off] != "}" )
+ {
+ Type t = identify ( tokens, off );
+ if ( t == T_VARIABLE )
+ off = parse_type ( t, tokens, off, fauxnames, dependencies );
+ else
+ {
+ while ( tokens[off] != ";" )
+ off++;
+ TOKASSERT ( tokens[off] == ";" );
+ off++;
+ }
+ }
+
+ TOKASSERT ( tokens[off] == "}" );
+ off++;
+
+ return off;
+}
+
+int parse_function_ptr ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
+{
+ off = skip_declspec ( tokens, off );
+
+ while ( tokens[off] != "(" )
+ depend ( tokens[off++], dependencies );
+
+ TOKASSERT ( tokens[off] == "(" );
+ off++;
+
+ while ( tokens[off+1] != ")" )
+ depend ( tokens[off++], dependencies );
+ name ( tokens[off++], names );
+
+ TOKASSERT ( tokens[off] == ")" );
+
+ off++;
+
+ TOKASSERT ( tokens[off] == "(" );
+
+ while ( tokens[off] != ")" )
+ {
+ off++;
+ vector<string> fauxnames;
+ off = parse_param ( tokens, off, fauxnames, dependencies );
+ TOKASSERT ( tokens[off] == "," || tokens[off] == ")" );
+ }
+
+ off++;
+ TOKASSERT ( tokens[off] == ";" );
+ off++;
+ return off;
+}
+
+int parse_ifwhile ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
+{
+ TOKASSERT ( tokens[off] == "if" || tokens[off] == "while" );
+ off++;
+
+ TOKASSERT ( tokens[off] == "(" );
+ off++;
+
+ TOKASSERT ( tokens[off] != ")" );
+ while ( tokens[off] != ")" )
+ off++;
+
+ if ( tokens[off] == "{" )
+ {
+ while ( tokens[off] != "}" )
+ {
+ Type t = identify ( tokens, off );
+ off = parse_type ( t, tokens, off, names, dependencies );
+ }
+ off++;
+ }
+ return off;
+}
+
+int parse_do ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
+{
+ TOKASSERT ( tokens[off] == "do" );
+ off++;
+
+ if ( tokens[off] != "{" )
+ {
+ Type t = identify ( tokens, off );
+ off = parse_type ( t, tokens, off, names, dependencies );
+ }
+ else
+ {
+ while ( tokens[off] != "}" )
+ {
+ Type t = identify ( tokens, off );
+ off = parse_type ( t, tokens, off, names, dependencies );
+ }
+ }
+
+ TOKASSERT ( tokens[off] == "while" );
+ off++;
+
+ TOKASSERT ( tokens[off] == "(" );
+ while ( tokens[off] != ")" )
+ off++;
+
+ TOKASSERT ( tokens[off] == ")" );
+ off++;
+
+ TOKASSERT ( tokens[off] == ";" );
+ off++;
+
+ return off;
+}
+
--- /dev/null
+# Microsoft Developer Studio Project File - Name="sdkparse" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=sdkparse - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "sdkparse.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "sdkparse.mak" CFG="sdkparse - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "sdkparse - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "sdkparse - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF "$(CFG)" == "sdkparse - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+\r
+!ELSEIF "$(CFG)" == "sdkparse - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "sdkparse - Win32 Release"\r
+# Name "sdkparse - Win32 Debug"\r
+# Begin Source File\r
+\r
+SOURCE=.\assert.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\binary2cstr.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\EnumDirs.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\EnumDirsImpl.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\EnumFiles.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\EnumFilesImpl.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\File.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\File.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\FixLFN.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\Header.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\iskeyword.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\iskeyword.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\safestr.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\sdkparse.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\skip_ws.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\skip_ws.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\strip_comments.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\strip_comments.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\Symbol.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\tokenize.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\Type.h\r
+# End Source File\r
+# End Target\r
+# End Project\r
--- /dev/null
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "sdkparse"=.\sdkparse.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
--- /dev/null
+// skip_ws.cpp
+
+#include <string.h>
+
+#include "skip_ws.h"
+
+const char* ws = " \t\r\n\v";
+
+char* skip_ws ( char* p )
+{
+ return p + strspn ( p, ws );
+}
+
+const char* skip_ws ( const char* p )
+{
+ return p + strspn ( p, ws );
+}
--- /dev/null
+// skip_ws.h
+
+#ifndef SKIP_WS_H
+#define SKIP_WS_H
+
+char* skip_ws ( char* );
+
+const char* skip_ws ( const char* );
+
+#endif//SKIP_WS_H
--- /dev/null
+// strip_comments.cpp
+
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif//_MSC_VER
+
+#include "strip_comments.h"
+
+void strip_comments ( std::string& s, bool strip_lf )
+{
+ char* src = &s[0];
+ char* dst = src;
+ while ( *src )
+ {
+ if ( src[0] == '/' && src[1] == '/' )
+ {
+ src += 2;
+ while ( *src && *src != '\n' )
+ src++;
+ if ( *src )
+ src++; // skip newline
+ }
+ else if ( src[0] == '/' && src[1] == '*' )
+ {
+ src += 2;
+ char* newsrc = strstr ( src, "*/" );
+ if ( !newsrc )
+ break;
+ src = newsrc;
+ //while ( *src && ( src[0] != '*' || src[1] != '/' ) )
+ // src++;
+ if ( *src ) src++;
+ if ( *src ) src++;
+ }
+ else if ( src[0] == '\r' && strip_lf )
+ src++;
+ else
+ *dst++ = *src++;
+ }
+ *dst = '\0';
+
+ s.resize ( dst-&s[0] );
+}
--- /dev/null
+// strip_comments.h
+
+#ifndef STRIP_COMMENTS_H
+#define STRIP_COMMENTS_H
+
+#include <string>
+
+void strip_comments ( std::string& s, bool strip_lf = false );
+
+#endif//STRIP_COMMENTS_H
--- /dev/null
+/* $Id$
+*/
+/*
+ * test.h
+ *
+ * This file is a combination of a couple different headers
+ * from ReactOS's include/ folder, and a little bit of custom
+ * hacking as well for the purpose of testing sdkparse.
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __INTERNAL_PSAPI_H_INCLUDED__
+#define __INTERNAL_PSAPI_H_INCLUDED__
+
+void *_lfind(const void* match, const void* start,unsigned int* array_size, unsigned int elem_size,int (*cf)(const void*,const void*));
+
+static inline struct _TEB * NtCurrentTeb(void)
+{
+ struct _TEB * pTeb;
+
+ /* FIXME: instead of hardcoded offsets, use offsetof() - if possible */
+ __asm__ __volatile__
+ (
+ "movl %%fs:0x18, %0\n" /* fs:18h == Teb->Tib.Self */
+ : "=r" (pTeb) /* can't have two memory operands */
+ : /* no inputs */
+ );
+
+ return pTeb;
+}
+
+typedef struct tagFOO
+{
+ INT lonibble : 4;
+ INT hinibble : 4;
+} FOO, *PFOO, FAR *LPFOO;
+
+/* INCLUDES */
+#define NTOS_MODE_USER
+#include <ntos.h>
+
+/* OBJECTS */
+typedef struct
+{
+ LPSTR LeftVolumeName;
+ LPSTR RightVolumeName;
+ ULONG DefaultVolume;
+ ULONG Type;
+ ULONG DeviceType;
+ char Key[4];
+ LPSTR PrototypeName;
+ PVOID DeferredRoutine;
+ PVOID ExclusionRoutine;
+ PVOID DispatchRoutine;
+ PVOID DevCapsRoutine;
+ PVOID HwSetVolume;
+ ULONG IoMethod;
+}SOUND_DEVICE_INIT;
+
+/* TYPES */
+typedef NTSTATUS NTAPI (*PPROC_ENUM_ROUTINE)
+(
+ IN PSYSTEM_PROCESSES CurrentProcess,
+ IN OUT PVOID CallbackContext
+);
+
+typedef NTSTATUS NTAPI (*PTHREAD_ENUM_ROUTINE)
+(
+ IN PSYSTEM_THREADS CurrentThread,
+ IN OUT PVOID CallbackContext
+);
+
+typedef NTSTATUS NTAPI (*PSYSMOD_ENUM_ROUTINE)
+(
+ IN PSYSTEM_MODULE_INFORMATION_ENTRY CurrentModule,
+ IN OUT PVOID CallbackContext
+);
+
+typedef NTSTATUS NTAPI (*PPROCMOD_ENUM_ROUTINE)
+(
+ IN HANDLE ProcessHandle,
+ IN PLDR_DATA_TABLE_ENTRY CurrentModule,
+ IN OUT PVOID CallbackContext
+);
+
+/* CONSTANTS */
+#define FAILED_WITH_STATUS DEFINE_DBG_MSG("%s() failed, status 0x%08X")
+
+/* PROTOTYPES */
+/* Processes and threads */
+/* enumeration */
+NTSTATUS
+NTAPI
+PsaEnumerateProcessesAndThreads
+(
+ IN PPROC_ENUM_ROUTINE ProcessCallback,
+ IN OUT PVOID ProcessCallbackContext,
+ IN PTHREAD_ENUM_ROUTINE ThreadCallback,
+ IN OUT PVOID ThreadCallbackContext
+);
+
+NTSTATUS
+NTAPI
+PsaEnumerateProcesses
+(
+ IN PPROC_ENUM_ROUTINE Callback,
+ IN OUT PVOID CallbackContext
+);
+
+NTSTATUS
+NTAPI
+PsaEnumerateThreads
+(
+ IN PTHREAD_ENUM_ROUTINE Callback,
+ IN OUT PVOID CallbackContext
+);
+
+/* capturing & walking */
+NTSTATUS
+NTAPI
+PsaCaptureProcessesAndThreads
+(
+ OUT PSYSTEM_PROCESSES * ProcessesAndThreads
+);
+
+NTSTATUS
+NTAPI
+PsaWalkProcessesAndThreads
+(
+ IN PSYSTEM_PROCESSES ProcessesAndThreads,
+ IN PPROC_ENUM_ROUTINE ProcessCallback,
+ IN OUT PVOID ProcessCallbackContext,
+ IN PTHREAD_ENUM_ROUTINE ThreadCallback,
+ IN OUT PVOID ThreadCallbackContext
+);
+
+NTSTATUS
+NTAPI
+PsaWalkProcesses
+(
+ IN PSYSTEM_PROCESSES ProcessesAndThreads,
+ IN PPROC_ENUM_ROUTINE Callback,
+ IN OUT PVOID CallbackContext
+);
+
+NTSTATUS
+NTAPI
+PsaWalkThreads
+(
+ IN PSYSTEM_PROCESSES ProcessesAndThreads,
+ IN PTHREAD_ENUM_ROUTINE Callback,
+ IN OUT PVOID CallbackContext
+);
+
+PSYSTEM_PROCESSES
+FASTCALL
+PsaWalkFirstProcess
+(
+ IN PSYSTEM_PROCESSES ProcessesAndThreads
+);
+
+PSYSTEM_PROCESSES
+FASTCALL
+PsaWalkNextProcess
+(
+ IN PSYSTEM_PROCESSES CurrentProcess
+);
+
+PSYSTEM_THREADS
+FASTCALL
+PsaWalkFirstThread
+(
+ IN PSYSTEM_PROCESSES CurrentProcess
+);
+
+PSYSTEM_THREADS
+FASTCALL
+PsaWalkNextThread
+(
+ IN PSYSTEM_THREADS CurrentThread
+);
+
+/* System modules */
+/* enumeration */
+NTSTATUS
+NTAPI
+PsaEnumerateSystemModules
+(
+ IN PSYSMOD_ENUM_ROUTINE Callback,
+ IN OUT PVOID CallbackContext
+);
+
+/* capturing & walking */
+NTSTATUS
+NTAPI
+PsaCaptureSystemModules
+(
+ OUT PSYSTEM_MODULE_INFORMATION * SystemModules
+);
+
+NTSTATUS
+NTAPI
+PsaWalkSystemModules
+(
+ IN PSYSTEM_MODULE_INFORMATION SystemModules,
+ IN PSYSMOD_ENUM_ROUTINE Callback,
+ IN OUT PVOID CallbackContext
+);
+
+PSYSTEM_MODULE_INFORMATION_ENTRY
+FASTCALL
+PsaWalkFirstSystemModule
+(
+ IN PSYSTEM_MODULE_INFORMATION SystemModules
+);
+
+PSYSTEM_MODULE_INFORMATION_ENTRY
+FASTCALL
+PsaWalkNextSystemModule
+(
+ IN PSYSTEM_MODULE_INFORMATION CurrentSystemModule
+);
+
+/* Process modules */
+NTSTATUS
+NTAPI
+PsaEnumerateProcessModules
+(
+ IN HANDLE ProcessHandle,
+ IN PPROCMOD_ENUM_ROUTINE Callback,
+ IN OUT PVOID CallbackContext
+);
+
+/* Miscellaneous */
+VOID
+NTAPI
+PsaFreeCapture
+(
+ IN PVOID Capture
+);
+
+/* The user must define these functions. They are called by PSAPI to allocate
+ memory. This allows PSAPI to be called from any environment */
+void *PsaiMalloc(SIZE_T size);
+void *PsaiRealloc(void *ptr, SIZE_T size);
+void PsaiFree(void *ptr);
+
+/* MACROS */
+#define DEFINE_DBG_MSG(__str__) "PSAPI: " __str__ "\n"
+
+#endif /* __INTERNAL_PSAPI_H_INCLUDED__ */
+
+/* EOF */
--- /dev/null
+// tokenize.cpp
+
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif//_MSC_VER
+
+#include <string>
+#include <vector>
+#include <conio.h>
+
+#include "assert.h"
+#include "tokenize.h"
+#include "skip_ws.h"
+
+using std::string;
+using std::vector;
+
+void tokenize ( const string& text, vector<string>& tokens )
+{
+ tokens.resize ( 0 );
+ string s ( text );
+ char* p = &s[0];
+ while ( *p )
+ {
+ // skip whitespace
+ p = skip_ws ( p );
+ // check for literal string
+ if ( *p == '\"' )
+ {
+ // skip initial quote
+ char* end = p + 1;
+ for ( ;; )
+ {
+ if ( *end == '\\' )
+ {
+ end++;
+ switch ( *end )
+ {
+ case 'x':
+ case 'X':
+ ASSERT(0); // come back to this....
+ break;
+ case '0':
+ ASSERT(0);
+ break;
+ default:
+ end++;
+ break;
+ }
+ }
+ else if ( *end == '\"' )
+ {
+ end++;
+ break;
+ }
+ else
+ end++;
+ }
+ tokens.push_back ( string ( p, end-p ) );
+ p = end;
+ }
+ else if ( __iscsymf(*p) )
+ {
+ char* end = p + 1;
+ while ( __iscsym ( *end ) )
+ end++;
+ tokens.push_back ( string ( p, end-p ) );
+ p = end;
+ }
+ else if ( isdigit(*p) || *p == '.' )
+ {
+ char* end = p;
+ while ( isdigit(*end) )
+ end++;
+ bool f = false;
+ if ( *end == '.' )
+ {
+ end++;
+ while ( isdigit(*end) )
+ end++;
+ f = true;
+ }
+ if ( *end == 'f' || *end == 'F' )
+ end++;
+ else if ( !f && ( *end == 'l' || *end == 'L' ) )
+ end++;
+ tokens.push_back ( string ( p, end-p ) );
+ p = end;
+ }
+ else switch ( *p )
+ {
+ case '.':
+ tokens.push_back ( "." );
+ p++;
+ break;
+ case ',':
+ tokens.push_back ( "," );
+ p++;
+ break;
+ case '(':
+ tokens.push_back ( "(" );
+ p++;
+ break;
+ case ')':
+ tokens.push_back ( ")" );
+ p++;
+ break;
+ case '{':
+ tokens.push_back ( "{" );
+ p++;
+ break;
+ case '}':
+ tokens.push_back ( "}" );
+ p++;
+ break;
+ case '[':
+ tokens.push_back ( "[" );
+ p++;
+ break;
+ case ']':
+ tokens.push_back ( "]" );
+ p++;
+ break;
+ case ';':
+ tokens.push_back ( ";" );
+ p++;
+ break;
+ case '\\':
+ switch ( p[1] )
+ {
+ case '\n':
+ tokens.push_back ( string ( p, 2 ) );
+ p += 2;
+ break;
+ default:
+ ASSERT(0); // shouldn't hit here, I think
+ tokens.push_back ( "\\" );
+ p++;
+ break;
+ }
+ break;
+ case '|':
+ switch ( p[1] )
+ {
+ case '|':
+ tokens.push_back ( string ( p, 2 ) );
+ p += 2;
+ break;
+ default:
+ tokens.push_back ( "|" );
+ p++;
+ break;
+ }
+ break;
+ case '&':
+ switch ( p[1] )
+ {
+ case '&':
+ tokens.push_back ( string ( p, 2 ) );
+ p += 2;
+ break;
+ default:
+ tokens.push_back ( "&" );
+ p++;
+ break;
+ }
+ break;
+ case '<':
+ switch ( p[1] )
+ {
+ case '<':
+ if ( p[2] == '=' )
+ tokens.push_back ( string ( p, 3 ) ), p += 3;
+ else
+ tokens.push_back ( string ( p, 2 ) ), p += 2;
+ break;
+ case '=':
+ tokens.push_back ( string ( p, 2 ) );
+ p += 2;
+ break;
+ default:
+ tokens.push_back ( "<" );
+ p++;
+ break;
+ }
+ break;
+ case '>':
+ switch ( p[1] )
+ {
+ case '>':
+ if ( p[2] == '=' )
+ tokens.push_back ( string ( p, 3 ) ), p += 3;
+ else
+ tokens.push_back ( string ( p, 2 ) ), p += 2;
+ break;
+ case '=':
+ tokens.push_back ( string ( p, 2 ) );
+ p += 2;
+ break;
+ default:
+ tokens.push_back ( ">" );
+ p++;
+ break;
+ }
+ break;
+ case '!':
+ switch ( p[1] )
+ {
+ case '=':
+ tokens.push_back ( string ( p, 2 ) );
+ p += 2;
+ break;
+ default:
+ tokens.push_back ( "!" );
+ p++;
+ break;
+ }
+ break;
+ case '=':
+ switch ( p[1] )
+ {
+ case '=':
+ tokens.push_back ( string ( p, 2 ) );
+ p += 2;
+ break;
+ default:
+ tokens.push_back ( "=" );
+ p++;
+ break;
+ }
+ break;
+ case ':':
+ switch ( p[1] )
+ {
+ case ':':
+ tokens.push_back ( string ( p, 2 ) );
+ p += 2;
+ break;
+ default:
+ tokens.push_back ( ":" );
+ p++;
+ break;
+ }
+ break;
+ case '*':
+ switch ( p[1] )
+ {
+ case '=':
+ tokens.push_back ( string ( p, 2 ) );
+ p += 2;
+ break;
+ default:
+ tokens.push_back ( "*" );
+ p++;
+ break;
+ }
+ break;
+ case '/':
+ switch ( p[1] )
+ {
+ case '=':
+ tokens.push_back ( string ( p, 2 ) );
+ p += 2;
+ break;
+ default:
+ tokens.push_back ( "/" );
+ p++;
+ break;
+ }
+ break;
+ case '+':
+ switch ( p[1] )
+ {
+ case '+':
+ case '=':
+ tokens.push_back ( string ( p, 2 ) );
+ p += 2;
+ break;
+ default:
+ tokens.push_back ( "+" );
+ p++;
+ break;
+ }
+ break;
+ case '-':
+ switch ( p[1] )
+ {
+ case '-':
+ case '=':
+ tokens.push_back ( string ( p, 2 ) );
+ p += 2;
+ break;
+ default:
+ tokens.push_back ( "-" );
+ p++;
+ break;
+ }
+ break;
+ case '#':
+ while ( *p && *p != '\n' )
+ p++;
+ break;
+ case 0:
+ break;
+ default:
+ printf ( "choked on '%c' in tokenize() - press any key to continue\n", *p );
+ getch();
+ p++;
+ break;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// tokenize.h
+
+#ifndef TOKENIZE_H
+#define TOKENIZE_H
+
+void tokenize ( const std::string& text, std::vector<std::string>& tokens );
+
+#endif//TOKENIZE_H
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS project statistics
+ * FILE: stats.c
+ * PURPOSE: Main program file
+ * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * REVISIONS:
+ * CSH 01/01-2002 Created
+ */
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+
+typedef struct _EXTENSION_INFO
+{
+ struct _EXTENSION_INFO * Next;
+ struct _FILE_INFO * StatInfoList;
+ TCHAR ExtName[16];
+ TCHAR ExpandedExtName[128];
+ DWORD nExtensions;
+ TCHAR Description[256];
+ DWORD FileCount;
+ DWORD LineCount;
+ DWORD EmptyLines;
+} EXTENSION_INFO, *PEXTENSION_INFO;
+
+typedef struct _FILE_INFO
+{
+ struct _FILE_INFO * Next;
+ struct _FILE_INFO * StatInfoListNext;
+ PEXTENSION_INFO ExtInfo;
+ TCHAR FileName[MAX_PATH];
+ DWORD LineCount;
+ DWORD EmptyLines;
+ DWORD FunctionCount;
+} FILE_INFO, *PFILE_INFO;
+
+HANDLE FileHandle;
+PEXTENSION_INFO ExtInfoList;
+PFILE_INFO StatInfoList;
+BOOLEAN SkipEmptyLines, BeSilent;
+
+#define MAX_OPTIONS 2
+TCHAR *Options[MAX_OPTIONS];
+
+
+VOID
+Initialize(VOID)
+{
+ ExtInfoList = NULL;
+ StatInfoList = NULL;
+}
+
+
+VOID
+Cleanup(VOID)
+{
+ PEXTENSION_INFO ExtInfo;
+ PEXTENSION_INFO NextExtInfo;
+
+ ExtInfo = ExtInfoList;
+ while (ExtInfo != NULL)
+ {
+ NextExtInfo = ExtInfo->Next;
+ HeapFree (GetProcessHeap(), 0, ExtInfo);
+ ExtInfo = NextExtInfo;
+ }
+}
+
+
+PEXTENSION_INFO
+AddExtension(LPTSTR ExtName,
+ LPTSTR Description)
+{
+ PEXTENSION_INFO ExtInfo;
+ PEXTENSION_INFO Info;
+ TCHAR *t;
+ DWORD ln;
+
+ ExtInfo = (PEXTENSION_INFO) HeapAlloc (GetProcessHeap(), 0, sizeof (EXTENSION_INFO));
+ if (!ExtInfo)
+ return NULL;
+
+ for(t = ExtName; *t != _T('\0'); t += _tcslen(t) + 1);
+ ln = (DWORD)t - (DWORD)ExtName;
+
+ ZeroMemory (ExtInfo, sizeof (EXTENSION_INFO));
+ memcpy (ExtInfo->ExtName, ExtName, ln);
+ _tcscpy (ExtInfo->Description, Description);
+
+ for(t = ExtInfo->ExtName; *t != _T('\0'); t += _tcslen(t) + 1)
+ {
+ if(ExtInfo->nExtensions++ != 0)
+ _tcscat (ExtInfo->ExpandedExtName, _T(";"));
+ _tcscat (ExtInfo->ExpandedExtName, _T("*."));
+ _tcscat (ExtInfo->ExpandedExtName, t);
+ }
+
+ if (ExtInfoList)
+ {
+ Info = ExtInfoList;
+ while (Info->Next != NULL)
+ {
+ Info = Info->Next;
+ }
+ Info->Next = ExtInfo;
+ }
+ else
+ {
+ ExtInfoList = ExtInfo;
+ }
+
+ return ExtInfo;
+}
+
+
+PFILE_INFO
+AddFile(LPTSTR FileName,
+ PEXTENSION_INFO ExtInfo)
+{
+ PFILE_INFO StatInfo;
+ PFILE_INFO Info;
+
+ StatInfo = (PFILE_INFO) HeapAlloc (GetProcessHeap(), 0, sizeof (FILE_INFO));
+ if (!StatInfo)
+ return NULL;
+ ZeroMemory (StatInfo, sizeof (FILE_INFO));
+ _tcscpy (StatInfo->FileName, FileName);
+ StatInfo->ExtInfo = ExtInfo;
+
+ if (ExtInfo->StatInfoList)
+ {
+ Info = ExtInfo->StatInfoList;
+ while (Info->StatInfoListNext != NULL)
+ {
+ Info = Info->StatInfoListNext;
+ }
+ Info->StatInfoListNext = StatInfo;
+ }
+ else
+ {
+ ExtInfo->StatInfoList = StatInfo;
+ }
+
+ if (StatInfoList)
+ {
+ Info = StatInfoList;
+ while (Info->Next != NULL)
+ {
+ Info = Info->Next;
+ }
+ Info->Next = StatInfo;
+ }
+ else
+ {
+ StatInfoList = StatInfo;
+ }
+
+ return StatInfo;
+}
+
+
+VOID
+CleanupAfterFile(VOID)
+{
+ if(FileHandle != INVALID_HANDLE_VALUE)
+ CloseHandle (FileHandle);
+}
+
+
+BOOL
+LoadFile(LPTSTR FileName)
+{
+ LONG FileSize;
+
+ FileHandle = CreateFile (FileName, // Create this file
+ GENERIC_READ, // Open for reading
+ 0, // No sharing
+ NULL, // No security
+ OPEN_EXISTING, // Open the file
+ FILE_ATTRIBUTE_NORMAL, // Normal file
+ NULL); // No attribute template
+ if (FileHandle == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ FileSize = GetFileSize (FileHandle, NULL);
+ if (FileSize <= 0)
+ {
+ CloseHandle (FileHandle);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+VOID
+ReadLines(PFILE_INFO StatInfo)
+{
+ DWORD ReadBytes, LineLen;
+ static char FileBuffer[1024];
+ char LastChar = '\0';
+ char *Current;
+
+ LineLen = 0;
+ while(ReadFile (FileHandle, FileBuffer, sizeof(FileBuffer), &ReadBytes, NULL) && ReadBytes >= sizeof(char))
+ {
+ for(Current = FileBuffer; ReadBytes > 0; ReadBytes -= sizeof(char), Current++)
+ {
+ if(*Current == '\n' && LastChar == '\r')
+ {
+ LastChar = '\0';
+ if(!SkipEmptyLines || (LineLen > 0))
+ StatInfo->LineCount++;
+ if(LineLen == 0)
+ StatInfo->EmptyLines++;
+ LineLen = 0;
+ continue;
+ }
+ LastChar = *Current;
+ if(SkipEmptyLines && (*Current == ' ' || *Current == '\t'))
+ {
+ continue;
+ }
+ if(*Current != '\r')
+ LineLen++;
+ }
+ }
+
+ StatInfo->LineCount += (LineLen > 0);
+ StatInfo->EmptyLines += ((LastChar != '\0') && (LineLen == 0));
+}
+
+
+VOID
+PrintStatistics(VOID)
+{
+ PEXTENSION_INFO Info;
+ DWORD TotalFileCount;
+ DWORD TotalLineCount;
+ DWORD TotalAvgLF;
+ DWORD TotalEmptyLines;
+
+ TotalFileCount = 0;
+ TotalLineCount = 0;
+ TotalEmptyLines = 0;
+ Info = ExtInfoList;
+
+ for (Info = ExtInfoList; Info != NULL; Info = Info->Next)
+ {
+ TotalFileCount += Info->FileCount;
+ TotalLineCount += Info->LineCount;
+ TotalEmptyLines += Info->EmptyLines;
+ }
+
+ TotalAvgLF = (TotalFileCount ? TotalLineCount / TotalFileCount : 0);
+
+ for (Info = ExtInfoList; Info != NULL; Info = Info->Next)
+ {
+ DWORD AvgLF;
+
+ if (Info->FileCount != 0)
+ {
+ AvgLF = (Info->FileCount ? Info->LineCount / Info->FileCount : 0);
+ }
+ else
+ {
+ AvgLF = 0;
+ }
+
+ _tprintf (_T("\n"));
+ _tprintf (_T("File extension%c : %s\n"), ((Info->nExtensions > 1) ? _T('s') : _T(' ')), Info->ExpandedExtName);
+ _tprintf (_T("File ext. description : %s\n"), Info->Description);
+ _tprintf (_T("Number of files : %lu\n"), Info->FileCount);
+ _tprintf (_T("Number of lines : %lu\n"), Info->LineCount);
+ if(SkipEmptyLines)
+ _tprintf (_T("Number of empty lines : %lu\n"), Info->EmptyLines);
+ _tprintf (_T("Proportion of lines : %.2f %%\n"), (float)(TotalLineCount ? (((float)Info->LineCount * 100) / (float)TotalLineCount) : 0));
+ _tprintf (_T("Average no. lines/file : %lu\n"), AvgLF);
+ }
+
+ _tprintf (_T("\n"));
+ _tprintf (_T("Total number of files : %lu\n"), TotalFileCount);
+ _tprintf (_T("Total number of lines : %lu\n"), TotalLineCount);
+ if(SkipEmptyLines)
+ _tprintf (_T("Total number of empty lines : %lu\n"), TotalEmptyLines);
+ _tprintf (_T("Average no. lines/file : %lu\n"), TotalAvgLF);
+}
+
+
+BOOL
+ProcessFiles(LPTSTR Path)
+{
+ WIN32_FIND_DATA FindFile;
+ PEXTENSION_INFO Info;
+ TCHAR SearchPath[256];
+ TCHAR FileName[256];
+ TCHAR *Ext;
+ HANDLE SearchHandle;
+ BOOL More;
+
+ Info = ExtInfoList;
+ while (Info != NULL)
+ {
+ Ext = Info->ExtName;
+ do
+ {
+ ZeroMemory (&FindFile, sizeof (FindFile));
+ _tcscpy (SearchPath, Path);
+ _tcscat (SearchPath, _T("\\*."));
+ _tcscat (SearchPath, Ext);
+ _tcscpy (FindFile.cFileName, SearchPath);
+ SearchHandle = FindFirstFile (SearchPath, &FindFile);
+ if (SearchHandle != INVALID_HANDLE_VALUE)
+ {
+ More = TRUE;
+ while (More)
+ {
+ if (!(FindFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ _tcscpy (FileName, Path);
+ _tcscat (FileName, _T("\\"));
+ _tcscat (FileName, FindFile.cFileName);
+
+ if (LoadFile (FileName))
+ {
+ PFILE_INFO StatInfo;
+
+ StatInfo = AddFile (FindFile.cFileName, Info);
+ if (!StatInfo)
+ {
+ _tprintf (_T("Not enough free memory.\n"));
+ return FALSE;
+ }
+
+ ReadLines (StatInfo);
+
+ Info->FileCount++;
+ Info->LineCount += StatInfo->LineCount;
+ Info->EmptyLines += StatInfo->EmptyLines;
+
+ CleanupAfterFile();
+ }
+ }
+ More = FindNextFile (SearchHandle, &FindFile);
+ }
+ FindClose (SearchHandle);
+ }
+ Ext += _tcslen(Ext) + 1;
+ } while(*Ext != _T('\0'));
+ Info = Info->Next;
+ }
+ return TRUE;
+}
+
+
+BOOL
+ProcessDirectories(LPTSTR Path)
+{
+ WIN32_FIND_DATA FindFile;
+ TCHAR SearchPath[MAX_PATH];
+ HANDLE SearchHandle;
+ BOOL More;
+
+ if(!BeSilent)
+ {
+ _tprintf (_T("Processing %s ...\n"), Path);
+ }
+
+ _tcscpy (SearchPath, Path);
+ _tcscat (SearchPath, _T("\\*.*"));
+
+ SearchHandle = FindFirstFileEx (SearchPath,
+ FindExInfoStandard,
+ &FindFile,
+ FindExSearchLimitToDirectories,
+ NULL,
+ 0);
+ if (SearchHandle != INVALID_HANDLE_VALUE)
+ {
+ More = TRUE;
+ while (More)
+ {
+ if ((FindFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ && (_tcscmp (FindFile.cFileName, _T(".")) != 0)
+ && (_tcscmp (FindFile.cFileName, _T("..")) != 0)
+ && (_tcscmp (FindFile.cFileName, _T("CVS")) != 0)
+ && (_tcscmp (FindFile.cFileName, _T(".svn")) != 0))
+ {
+ _tcscpy (SearchPath, Path);
+ _tcscat (SearchPath, _T("\\"));
+ _tcscat (SearchPath, FindFile.cFileName);
+ if (!ProcessDirectories (SearchPath))
+ return FALSE;
+ if (!ProcessFiles (SearchPath))
+ return FALSE;
+ }
+ More = FindNextFile (SearchHandle, &FindFile);
+ }
+ FindClose (SearchHandle);
+ }
+ return TRUE;
+}
+
+
+VOID
+Execute(LPTSTR Path)
+{
+ if (!ExtInfoList)
+ {
+ _tprintf (_T("No extensions specified.\n"));
+ return;
+ }
+
+ if (!ProcessDirectories (Path))
+ {
+ _tprintf (_T("Failed to process directories.\n"));
+ return;
+ }
+
+ if (!ProcessFiles (Path))
+ {
+ _tprintf (_T("Failed to process files.\n"));
+ return;
+ }
+
+ PrintStatistics();
+}
+
+BOOLEAN
+IsOptionSet(TCHAR *Option)
+{
+ int i;
+ for(i = 0; i < MAX_OPTIONS; i++)
+ {
+ if(!Options[i])
+ continue;
+
+ if(!_tcscmp(Options[i], Option))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+int
+main (int argc, char * argv [])
+{
+ int a;
+#if UNICODE
+ TCHAR Path[MAX_PATH + 1];
+#endif
+
+ _tprintf (_T("ReactOS Project Statistics\n"));
+ _tprintf (_T("==========================\n\n"));
+
+ if (argc < 2 || argc > 2 + MAX_OPTIONS)
+ {
+ _tprintf(_T("Usage: stats [-e] [-s] directory\n"));
+ _tprintf(_T(" -e: don't count empty lines\n"));
+ _tprintf(_T(" -s: be silent, don't print directories while processing\n"));
+ return 1;
+ }
+
+ Initialize();
+ AddExtension (_T("c\0\0"), _T("Ansi C Source files"));
+ AddExtension (_T("cpp\0cxx\0\0"), _T("C++ Source files"));
+ AddExtension (_T("h\0\0"), _T("Header files"));
+
+ for(a = 1; a < argc - 1; a++)
+ {
+#if UNICODE
+ int len = lstrlenA(argv[a]);
+ TCHAR *str = (TCHAR*)HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(TCHAR));
+ if(MultiByteToWideChar(CP_ACP, 0, argv[a], -1, str, len + 1) > 0)
+ Options[a - 1] = str;
+ else
+ Options[a - 1] = NULL;
+#else
+ Options[a - 1] = argv[a];
+#endif
+ }
+
+ SkipEmptyLines = IsOptionSet(_T("-e"));
+ BeSilent = IsOptionSet(_T("-s"));
+
+#if UNICODE
+ ZeroMemory(Path, sizeof(Path));
+ if(MultiByteToWideChar(CP_ACP, 0, argv[argc - 1], -1, Path, MAX_PATH) > 0)
+ Execute (Path);
+#else
+ Execute (argv[argc - 1]);
+#endif
+ Cleanup();
+
+ return 0;
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="X86"
+ name="ReactOS.Theme.Dump"
+ type="win32"
+ />
+ <description>Dumps properties of Windows/ReactOS Visual Styles.</description>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="X86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+ </dependency>
+</assembly>
+
+<!-- EOF -->
--- /dev/null
+<?xml version='1.0' encoding='utf-8' ?>
+<!-- C++Builder XML Project -->
+<PROJECT>
+ <MACROS>
+ <VERSION value="BCB.06.00"/>
+ <PROJECT value="themedump.exe"/>
+ <OBJFILES value="themedump.obj"/>
+ <RESFILES value="themedump.res"/>
+ <IDLFILES value=""/>
+ <IDLGENFILES value=""/>
+ <DEFFILE value=""/>
+ <RESDEPEN value="$(RESFILES)"/>
+ <LIBFILES value=""/>
+ <LIBRARIES value=""/>
+ <SPARELIBS value=""/>
+ <PACKAGES value="vcl.bpi rtl.bpi dbrtl.bpi adortl.bpi vcldb.bpi vclx.bpi bdertl.bpi
+ ibxpress.bpi cds.bpi dsnap.bpi bdecds.bpi qrpt.bpi teeui.bpi teedb.bpi
+ tee.bpi vcldbx.bpi dss.bpi teeqr.bpi visualclx.bpi visualdbclx.bpi
+ dsnapcrba.bpi dsnapcon.bpi bcbsmp.bpi dbexpress.bpi dbxcds.bpi indy.bpi"/>
+ <PATHCPP value=".;"/>
+ <PATHPAS value=".;"/>
+ <PATHRC value=".;"/>
+ <PATHASM value=".;"/>
+ <DEBUGLIBPATH value="$(BCB)\lib\debug"/>
+ <RELEASELIBPATH value="$(BCB)\lib\release"/>
+ <LINKER value="ilink32"/>
+ <USERDEFINES value="_DEBUG"/>
+ <SYSDEFINES value="NO_STRICT;_NO_VCL;USEPACKAGES"/>
+ <MAINSOURCE value="themedump.cpp"/>
+ <INCLUDEPATH value=".;$(BCB)\include;$(BCB)\include\vcl"/>
+ <LIBPATH value=".;$(BCB)\lib\obj;$(BCB)\lib"/>
+ <WARNINGS value="-w-pch -w-par"/>
+ <OTHERFILES value=""/>
+ </MACROS>
+ <OPTIONS>
+ <IDLCFLAGS value="-I. -I$(BCB)\include -I$(BCB)\include\vcl -src_suffix cpp -D_DEBUG -boa"/>
+ <CFLAG1 value="-Od -H=$(BCB)\lib\vcl60.csm -Hc -Vx -Ve -X- -r- -a8 -b- -k -y -v -vi- -tWC
+ -tWM -c"/>
+ <PFLAGS value="-$YD -$W -$O- -$A8 -v -JPHNE -M"/>
+ <RFLAGS value=""/>
+ <AFLAGS value="/mx /w2 /zd"/>
+ <LFLAGS value="-D"" -ap -Tpe -x -Gn -v"/>
+ <OTHERFILES value=""/>
+ </OPTIONS>
+ <LINKER>
+ <ALLOBJ value="c0x32.obj $(PACKAGES) $(OBJFILES)"/>
+ <ALLRES value="$(RESFILES)"/>
+ <ALLLIB value="$(LIBFILES) $(LIBRARIES) uxtheme.lib import32.lib cw32mt.lib"/>
+ <OTHERFILES value=""/>
+ </LINKER>
+ <FILELIST>
+ <FILE FILENAME="themedump.cpp" FORMNAME="" UNITNAME="themedump" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
+ <FILE FILENAME="themedump.rc" FORMNAME="" UNITNAME="themedump.rc" CONTAINERID="RCCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
+ </FILELIST>
+ <BUILDTOOLS>
+ </BUILDTOOLS>
+
+ <IDEOPTIONS>
+[Version Info]
+IncludeVerInfo=0
+AutoIncBuild=0
+MajorVer=1
+MinorVer=0
+Release=0
+Build=0
+Debug=0
+PreRelease=0
+Special=0
+Private=0
+DLL=0
+Locale=1040
+CodePage=1252
+
+[Version Info Keys]
+CompanyName=
+FileDescription=
+FileVersion=1.0.0.0
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=1.0.0.0
+Comments=
+
+[Debugging]
+DebugSourceDirs=$(BCB)\source\vcl
+
+[Parameters]
+RunParams=
+Launcher=
+UseLauncher=0
+DebugCWD=
+HostApplication=
+RemoteHost=
+RemotePath=
+RemoteLauncher=
+RemoteCWD=
+RemoteDebug=0
+
+[Compiler]
+ShowInfoMsgs=0
+LinkDebugVcl=0
+LinkCGLIB=0
+
+[CORBA]
+AddServerUnit=1
+AddClientUnit=1
+PrecompiledHeaders=1
+
+[Language]
+ActiveLang=
+ProjectLang=
+RootDir=
+ </IDEOPTIONS>
+</PROJECT>
\ No newline at end of file
--- /dev/null
+#include <cstdlib>
+#include <cstdio>
+#include <cwchar>
+#include <iostream>
+#include <exception>
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <string>
+#include <map>
+
+#define WIN32_LEAN_AND_MEAN
+#define UNICODE
+#include <windows.h>
+#include <commctrl.h>
+#include <uxtheme.h>
+#include <tmschema.h>
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#define SCHEMA_STRINGS
+#define TMT_ENUMDEF (0x0D) // undocumented
+#define TMT_ENUMVAL (0x0E) // undocumented
+#define TMT_ENUM (0x0F) // undocumented
+#include <tmschema.h>
+
+namespace tmdump
+{
+ typedef std::map<int, std::wstring> tm_enum_t;
+ typedef std::map<std::wstring, tm_enum_t> tm_enums_t;
+
+ struct tm_property_t
+ {
+ std::wstring name;
+ int id;
+ int type;
+ tm_enums_t::iterator enum_type;
+ };
+
+ static tm_enums_t tm_enums;
+
+ typedef std::list<tm_property_t> tm_properties_t;
+
+ static tm_properties_t tm_properties;
+
+ typedef std::map<int, std::wstring> tm_states_t;
+ typedef std::map<std::wstring, tm_states_t> tm_state_enums_t;
+
+ static tm_state_enums_t tm_state_enums;
+
+ struct tm_part_t
+ {
+ std::wstring name;
+ tm_state_enums_t::iterator states;
+ };
+
+ typedef std::map<int, tm_part_t> tm_parts_t;
+
+ typedef std::map<std::wstring, tm_parts_t> tm_classes_t;
+
+ static tm_classes_t tm_classes;
+
+ class print
+ {
+ protected:
+ std::FILE * m_out;
+
+ public:
+ print(std::FILE * out_): m_out(out_) { }
+ };
+
+ class property_print:
+ public print,
+ public std::unary_function<tm_property_t, void>
+ {
+ private:
+ wchar_t const * type_name(const tm_property_t& property_)
+ {
+ switch(property_.type)
+ {
+ case TMT_STRING: return L"LPWSTR";
+ case TMT_INT: return L"int";
+ case TMT_BOOL: return L"BOOL";
+ case TMT_COLOR: return L"COLORREF";
+ case TMT_MARGINS: return L"MARGINS";
+ case TMT_FILENAME: return L"LPWSTR";
+ case TMT_SIZE: return L"SIZE";
+ case TMT_POSITION: return L"POINT";
+ case TMT_RECT: return L"RECT";
+ case TMT_FONT: return L"LOGFONT";
+ case TMT_INTLIST: return L"INTLIST";
+ case TMT_ENUM: return property_.enum_type->first.c_str();
+ default: return L"<unknown>";
+ }
+ }
+
+ public:
+ property_print(std::FILE * out_): print(out_) { }
+
+ void operator()(const tm_property_t& property_)
+ {
+ std::fwprintf
+ (
+ m_out,
+ L"%s\t%s\t%d\n",
+ type_name(property_),
+ property_.name.c_str(),
+ property_.id
+ );
+ }
+ };
+
+ class part_print:
+ public print,
+ public std::unary_function<tm_parts_t::value_type, void>
+ {
+ public:
+ part_print(std::FILE * out_): print(out_) { }
+
+ void operator()(const tm_parts_t::value_type& part_)
+ {
+ std::fwprintf
+ (
+ m_out,
+ L"\t%s\t%d\t%s\n",
+ part_.second.name.c_str(),
+ part_.first,
+ part_.second.states == tm_state_enums.end() ?
+ L"-" :
+ part_.second.states->first.c_str()
+ );
+ }
+ };
+
+ class class_print:
+ public print,
+ public std::unary_function<tm_classes_t::value_type, void>
+ {
+ public:
+ class_print(std::FILE * out_): print(out_) { }
+
+ void operator()(const tm_classes_t::value_type& class_)
+ {
+ std::fwprintf(m_out, L"%s\n", class_.first.c_str());
+
+ std::for_each
+ (
+ class_.second.begin(),
+ class_.second.end(),
+ part_print(m_out)
+ );
+ }
+ };
+
+ class schema_scan: public std::unary_function<struct TMPROPINFO, void>
+ {
+ private:
+ enum
+ {
+ at_none,
+ at_enum,
+ at_parts,
+ at_states
+ }
+ m_state;
+
+ union
+ {
+ void * p_none;
+ tm_enum_t * p_enum;
+ tm_parts_t * p_class;
+ tm_states_t * p_states;
+ }
+ m_cur;
+
+ bool has_suffix(const std::wstring& name_, const std::wstring& suffix_)
+ {
+ if(name_.length() <= suffix_.length()) return false;
+
+ return std::equal
+ (
+ name_.end() - suffix_.length(),
+ name_.end(),
+ suffix_.begin()
+ );
+ }
+
+ public:
+ schema_scan(): m_state(at_none) { }
+
+ void operator()(const struct TMPROPINFO& prop_)
+ {
+ static const std::wstring parts_suffix(L"PARTS");
+ static const std::wstring states_suffix(L"STATES");
+
+ std::wstring name(prop_.pszName);
+
+ // Compound declaration
+ if(prop_.sEnumVal == TMT_ENUMDEF && prop_.bPrimVal == TMT_ENUMDEF)
+ {
+ // class
+ if(has_suffix(name, parts_suffix))
+ {
+ m_state = at_parts;
+ m_cur.p_class = &
+ (
+ tm_classes
+ [
+ std::wstring(name.begin(), name.end() - parts_suffix.length())
+ ] = tm_parts_t()
+ );
+ }
+ // states
+ else if(has_suffix(name, states_suffix))
+ {
+ m_state = at_states;
+ m_cur.p_states = &
+ (
+ tm_state_enums
+ [
+ std::wstring(name.begin(), name.end() - states_suffix.length())
+ ] = tm_states_t()
+ );
+ }
+ // enumeration
+ else
+ {
+ m_state = at_enum;
+ m_cur.p_enum = &(tm_enums[name] = tm_enum_t());
+ }
+ }
+ // Enumeration member
+ else if(prop_.bPrimVal == TMT_ENUMVAL) switch(m_state)
+ {
+ // enumeration member
+ case at_enum:
+ {
+ (*m_cur.p_enum)[prop_.sEnumVal] = name;
+ break;
+ }
+
+ // class part
+ case at_parts:
+ {
+ tm_part_t part;
+ part.name = name;
+ part.states = tm_state_enums.end();
+ (*m_cur.p_class)[prop_.sEnumVal] = part;
+ break;
+ }
+
+ // state
+ case at_states:
+ {
+ (*m_cur.p_states)[prop_.sEnumVal] = name;
+ break;
+ }
+ }
+ // Primitive type
+ else if(prop_.sEnumVal == prop_.bPrimVal)
+ {
+ m_state = at_none;
+ m_cur.p_none = NULL;
+ }
+ // Property
+ else
+ {
+ m_state = at_none;
+ m_cur.p_none = NULL;
+
+ tm_property_t property;
+
+ property.name = name;
+ property.id = prop_.sEnumVal;
+ property.type = prop_.bPrimVal;
+
+ if(prop_.bPrimVal == TMT_ENUM)
+ property.enum_type = tm_enums.find(name);
+
+ tm_properties.push_back(property);
+ }
+ }
+ };
+
+ struct state_mapping_t
+ {
+ LPWSTR classname;
+ int partid;
+ LPWSTR states;
+ };
+
+ static const tmdump::state_mapping_t state_map[] =
+ {
+ { L"BUTTON", 0, NULL },
+ { NULL, BP_CHECKBOX, L"CHECKBOX" },
+ { NULL, BP_GROUPBOX, L"GROUPBOX" },
+ { NULL, BP_PUSHBUTTON, L"PUSHBUTTON" },
+ { NULL, BP_RADIOBUTTON, L"RADIOBUTTON" },
+ { L"CLOCK", CLP_TIME, L"CLOCK" },
+ { L"COMBOBOX", CP_DROPDOWNBUTTON, L"COMBOBOX" },
+ { L"EDIT", EP_EDITTEXT, L"EDITTEXT" },
+ { L"EXPLORERBAR", 0, NULL },
+ { NULL, EBP_HEADERCLOSE, L"HEADERCLOSE" },
+ { NULL, EBP_HEADERPIN, L"HEADERPIN" },
+ { NULL, EBP_IEBARMENU, L"IEBARMENU" },
+ { NULL, EBP_NORMALGROUPCOLLAPSE, L"NORMALGROUPCOLLAPSE" },
+ { NULL, EBP_NORMALGROUPEXPAND, L"NORMALGROUPEXPAND" },
+ { NULL, EBP_SPECIALGROUPCOLLAPSE, L"SPECIALGROUPCOLLAPSE"},
+ { NULL, EBP_SPECIALGROUPEXPAND, L"SPECIALGROUPEXPAND" },
+ { L"HEADER", 0, NULL },
+ { NULL, HP_HEADERITEM, L"HEADERITEM" },
+ { NULL, HP_HEADERITEMLEFT, L"HEADERITEMLEFT" },
+ { NULL, HP_HEADERITEMRIGHT, L"HEADERITEMRIGHT" },
+ { NULL, HP_HEADERSORTARROW, L"HEADERSORTARROW" },
+ { L"LISTVIEW", LVP_LISTITEM, L"LISTITEM " },
+ { L"MENU", 0, NULL },
+ { NULL, MP_MENUBARDROPDOWN, L"MENU" },
+ { NULL, MP_MENUBARITEM, L"MENU" },
+ { NULL, MP_CHEVRON, L"MENU" },
+ { NULL, MP_MENUDROPDOWN, L"MENU" },
+ { NULL, MP_MENUITEM, L"MENU" },
+ { NULL, MP_SEPARATOR, L"MENU" },
+ { L"MENUBAND", MDP_NEWAPPBUTTON, L"MENUBAND" },
+ { L"PAGE", 0, NULL },
+ { NULL, PGRP_DOWN, L"DOWN" },
+ { NULL, PGRP_DOWNHORZ, L"DOWNHORZ" },
+ { NULL, PGRP_UP, L"UP" },
+ { NULL, PGRP_UPHORZ, L"UPHORZ" },
+ { L"REBAR", RP_CHEVRON, L"CHEVRON" },
+ { L"SCROLLBAR", 0, NULL },
+ { NULL, SBP_ARROWBTN, L"ARROWBTN" },
+ { NULL, SBP_LOWERTRACKHORZ, L"SCROLLBAR" },
+ { NULL, SBP_LOWERTRACKVERT, L"SCROLLBAR" },
+ { NULL, SBP_THUMBBTNHORZ, L"SCROLLBAR" },
+ { NULL, SBP_THUMBBTNVERT, L"SCROLLBAR" },
+ { NULL, SBP_UPPERTRACKHORZ, L"SCROLLBAR" },
+ { NULL, SBP_UPPERTRACKVERT, L"SCROLLBAR" },
+ { NULL, SBP_SIZEBOX, L"SIZEBOX" },
+ { L"SPIN", 0, NULL },
+ { NULL, SPNP_DOWN, L"DOWN" },
+ { NULL, SPNP_DOWNHORZ, L"DOWNHORZ" },
+ { NULL, SPNP_UP, L"UP" },
+ { NULL, SPNP_UPHORZ, L"UPHORZ" },
+ { L"STARTPANEL", 0, NULL },
+ { NULL, SPP_LOGOFFBUTTONS, L"LOGOFFBUTTONS" },
+ { NULL, SPP_MOREPROGRAMSARROW, L"MOREPROGRAMSARROW" },
+ { L"TAB", 0, NULL },
+ { NULL, TABP_TABITEM, L"TABITEM" },
+ { NULL, TABP_TABITEMBOTHEDGE, L"TABITEMBOTHEDGE" },
+ { NULL, TABP_TABITEMLEFTEDGE, L"TABITEMLEFTEDGE" },
+ { NULL, TABP_TABITEMRIGHTEDGE, L"TABITEMRIGHTEDGE" },
+ { NULL, TABP_TOPTABITEM, L"TOPTABITEM" },
+ { NULL, TABP_TOPTABITEMBOTHEDGE, L"TOPTABITEMBOTHEDGE" },
+ { NULL, TABP_TOPTABITEMLEFTEDGE, L"TOPTABITEMLEFTEDGE" },
+ { NULL, TABP_TOPTABITEMRIGHTEDGE, L"TOPTABITEMRIGHTEDGE" },
+ { L"TOOLBAR", 0, NULL },
+ { NULL, TP_BUTTON, L"TOOLBAR" },
+ { NULL, TP_DROPDOWNBUTTON, L"TOOLBAR" },
+ { NULL, TP_SPLITBUTTON, L"TOOLBAR" },
+ { NULL, TP_SPLITBUTTONDROPDOWN, L"TOOLBAR" },
+ { NULL, TP_SEPARATOR, L"TOOLBAR" },
+ { NULL, TP_SEPARATORVERT, L"TOOLBAR" },
+ { L"TOOLTIP", 0, NULL },
+ { NULL, TTP_BALLOON, L"BALLOON" },
+ { NULL, TTP_BALLOONTITLE, L"BALLOON" },
+ { NULL, TTP_CLOSE, L"CLOSE" },
+ { NULL, TTP_STANDARD, L"STANDARD" },
+ { NULL, TTP_STANDARDTITLE, L"STANDARD" },
+ { L"TRACKBAR", 0, NULL },
+ { NULL, TKP_THUMB, L"THUMB" },
+ { NULL, TKP_THUMBBOTTOM, L"THUMBBOTTOM" },
+ { NULL, TKP_THUMBLEFT, L"THUMBLEFT" },
+ { NULL, TKP_THUMBRIGHT, L"THUMBRIGHT" },
+ { NULL, TKP_THUMBTOP, L"THUMBTOP" },
+ { NULL, TKP_THUMBVERT, L"THUMBVERT" },
+ { NULL, TKP_TICS, L"TICS" },
+ { NULL, TKP_TICSVERT, L"TICSVERT" },
+ { NULL, TKP_TRACK, L"TRACK" },
+ { NULL, TKP_TRACKVERT, L"TRACKVERT" },
+ { L"TREEVIEW", 0, NULL },
+ { NULL, TVP_GLYPH, L"GLYPH" },
+ { NULL, TVP_TREEITEM, L"TREEITEM" },
+ { L"WINDOW", 0, NULL },
+ { NULL, WP_CAPTION, L"CAPTION" },
+ { NULL, WP_CLOSEBUTTON, L"CLOSEBUTTON" },
+ { NULL, WP_FRAMEBOTTOM, L"FRAME" },
+ { NULL, WP_FRAMELEFT, L"FRAME" },
+ { NULL, WP_FRAMERIGHT, L"FRAME" },
+ { NULL, WP_HELPBUTTON, L"HELPBUTTON" },
+ { NULL, WP_HORZSCROLL, L"HORZSCROLL" },
+ { NULL, WP_HORZTHUMB, L"HORZTHUMB" },
+ { NULL, WP_MAXBUTTON, L"MAXBUTTON" },
+ { NULL, WP_MAXCAPTION, L"MAXCAPTION" },
+ { NULL, WP_MDICLOSEBUTTON, L"CLOSEBUTTON" },
+ { NULL, WP_MDIHELPBUTTON, L"HELPBUTTON" },
+ { NULL, WP_MDIMINBUTTON, L"MINBUTTON" },
+ { NULL, WP_MDIRESTOREBUTTON, L"RESTOREBUTTON" },
+ { NULL, WP_MDISYSBUTTON, L"SYSBUTTON" },
+ { NULL, WP_MINBUTTON, L"MINBUTTON" },
+ { NULL, WP_MINCAPTION, L"MINCAPTION" },
+ { NULL, WP_RESTOREBUTTON, L"RESTOREBUTTON" },
+ { NULL, WP_SMALLCAPTION, L"CAPTION" },
+ { NULL, WP_SMALLCLOSEBUTTON, L"CLOSEBUTTON" },
+ { NULL, WP_SMALLFRAMEBOTTOM, L"FRAME" },
+ { NULL, WP_SMALLFRAMELEFT, L"FRAME" },
+ { NULL, WP_SMALLFRAMERIGHT, L"FRAME" },
+ { NULL, WP_SMALLMAXCAPTION, L"MAXCAPTION" },
+ { NULL, WP_SMALLMINCAPTION, L"MINCAPTION" },
+ { NULL, WP_SYSBUTTON, L"SYSBUTTON" },
+ { NULL, WP_VERTSCROLL, L"HORZSCROLL" },
+ { NULL, WP_VERTTHUMB, L"HORZTHUMB" },
+ };
+
+ class state_link: public std::unary_function<struct state_mapping_t, void>
+ {
+ private:
+ tm_classes_t::iterator m_class;
+
+ public:
+ void operator()(const struct state_mapping_t& mapping_)
+ {
+ // switch to a new class
+ if(mapping_.classname)
+ m_class = tm_classes.find(std::wstring(mapping_.classname));
+
+ // no mapping, or class not found
+ if(mapping_.states == NULL || m_class == tm_classes.end()) return;
+
+ tm_state_enums_t::iterator states =
+ tm_state_enums.find(std::wstring(mapping_.states));
+
+ // unknown set of states
+ if(states == tm_state_enums.end()) return;
+
+ tm_parts_t::iterator part = m_class->second.find(mapping_.partid);
+
+ // unknown part
+ if(part == m_class->second.end()) return;
+
+ // success
+ part->second.states = states;
+ }
+ };
+}
+
+int main(int argc, char * argv[])
+{
+ try
+ {
+ struct TMSCHEMAINFO const & schema = *GetSchemaInfo();
+
+ // build the tables of properties, classes, parts and states
+ std::for_each
+ (
+ schema.pPropTable,
+ schema.pPropTable + schema.iPropCount,
+ tmdump::schema_scan()
+ );
+
+ // link parts to states
+ std::for_each
+ (
+ tmdump::state_map,
+ tmdump::state_map + sizeof(tmdump::state_map) / sizeof(tmdump::state_map[0]),
+ tmdump::state_link()
+ );
+
+ ::InitCommonControls();
+ ::SetThemeAppProperties(STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS);
+
+ // dump the current values of all properties
+ for
+ (
+ tmdump::tm_classes_t::iterator p = tmdump::tm_classes.begin();
+ p != tmdump::tm_classes.end();
+ ++ p
+ )
+ {
+ const std::wstring& class_name = p->first;
+
+ // open the theme data for the current class
+ class htheme_t
+ {
+ public:
+ HTHEME m_handle;
+
+ htheme_t(HTHEME handle_): m_handle(handle_) { }
+ ~htheme_t() { ::CloseThemeData(m_handle); }
+
+ operator HTHEME() { return m_handle; }
+ }
+ data = ::OpenThemeData(NULL, class_name.c_str());
+
+ // failure
+ if(data == NULL)
+ {
+ std::fwprintf
+ (
+ stderr,
+ L"OpenThemeData(\"%s\") failed, error %d\n",
+ class_name.c_str(),
+ GetLastError()
+ );
+
+ continue;
+ }
+
+ // class name
+ std::fwprintf(stdout, L"%s\n", p->first.c_str());
+
+ // dump system properties
+ for
+ (
+ tmdump::tm_properties_t::iterator p = tmdump::tm_properties.begin();
+ p != tmdump::tm_properties.end();
+ ++ p
+ )
+ {
+ switch(p->type)
+ {
+ case TMT_POSITION:
+ case TMT_MARGINS:
+ case TMT_RECT:
+ case TMT_INTLIST:
+ continue;
+ }
+
+ // property name
+ std::fwprintf(stdout, L"\t%s = ", p->name.c_str());
+
+ HRESULT hres;
+
+ switch(p->type)
+ {
+ // string
+ case TMT_STRING:
+ case TMT_FILENAME: // FIXME
+ {
+ WCHAR buffer[256];
+ if(FAILED(hres = GetThemeSysString(data, p->id, buffer, 256))) break;
+ std::fwprintf(stdout, L"string: \"%s\"", buffer);
+ break;
+ }
+
+ // integer
+ case TMT_INT:
+ {
+ int val;
+ if(FAILED(hres = GetThemeSysInt(data, p->id, &val))) break;
+ std::fwprintf(stdout, L"int: %d", val);
+ break;
+ }
+
+ // boolean
+ case TMT_BOOL:
+ {
+ SetLastError(0);
+ BOOL val = GetThemeSysBool(data, p->id);
+ if(FAILED(hres = GetLastError())) break;
+ std::fwprintf(stdout, L"bool: %s", val ? L"true" : L"false");
+ break;
+ }
+
+ // color
+ case TMT_COLOR:
+ {
+ SetLastError(0);
+
+ COLORREF val = GetThemeSysColor(data, p->id);
+
+ if(FAILED(hres = GetLastError())) break;
+
+ std::fwprintf
+ (
+ stdout,
+ L"rgb: %d, %d, %d",
+ GetRValue(val),
+ GetGValue(val),
+ GetBValue(val)
+ );
+
+ break;
+ }
+
+ // size
+ case TMT_SIZE:
+ {
+ SetLastError(0);
+ int val = GetThemeSysSize(data, p->id);
+ if(FAILED(hres = GetLastError())) break;
+ std::fwprintf(stdout, L"size: %d", val);
+ break;
+ }
+
+ // font
+ case TMT_FONT:
+ {
+ LOGFONTW val;
+ if(FAILED(hres = GetThemeSysFont(data, p->id, &val))) break;
+ std::fwprintf(stdout, L"font: %s", val.lfFaceName);
+ break;
+ }
+
+ // enumerated integer
+ case TMT_ENUM:
+ {
+ int val;
+ if(FAILED(hres = GetThemeSysInt(data, p->id, &val))) break;
+
+ std::fwprintf(stdout, L"enum(%s): ", p->enum_type->first.c_str());
+
+ tmdump::tm_enum_t::iterator enumval = p->enum_type->second.find(val);
+
+ if(enumval == p->enum_type->second.end())
+ std::fwprintf(stdout, L"<%d>", val);
+ else
+ std::fwprintf(stdout, L"%s", enumval->second.c_str());
+
+ break;
+ }
+ }
+
+ if(FAILED(hres)) std::fwprintf(stdout, L"<error %08X>", hres);
+
+ std::fputwc(L'\n', stdout);
+ }
+
+ }
+ }
+ catch(std::exception e)
+ {
+ std::cerr << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
+// EOF
+
--- /dev/null
+#define WIN32_LEAN_AND_MEAN
+#include <winuser.h>
+
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "manifest.xml"
+
+// EOF
--- /dev/null
+/* $Id$
+*/
+/*
+ tickcount -- Display the kernel tick count (or any tick count passed as an
+ argument or as input) in human-readable format
+
+ This is public domain software
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <tchar.h>
+#include <windows.h>
+
+typedef __int64 int64_;
+typedef unsigned __int64 uint64_;
+
+#define TICKS_YEAR (TICKS_DAY * ((uint64_)365))
+#define TICKS_MONTH (TICKS_DAY * ((uint64_)30))
+#define TICKS_WEEK (TICKS_DAY * ((uint64_)7))
+#define TICKS_DAY (TICKS_HOUR * ((uint64_)24))
+#define TICKS_HOUR (TICKS_MINUTE * ((uint64_)60))
+#define TICKS_MINUTE (TICKS_SECOND * ((uint64_)60))
+#define TICKS_SECOND ((uint64_)1000)
+
+#define SLICES_COUNT (sizeof(ticks_per_slice) / sizeof(ticks_per_slice[0]))
+
+uint64_ ticks_per_slice[] =
+{
+ TICKS_YEAR,
+ TICKS_MONTH,
+ TICKS_WEEK,
+ TICKS_DAY,
+ TICKS_HOUR,
+ TICKS_MINUTE,
+ TICKS_SECOND,
+ 1
+};
+
+_TCHAR * slice_names_singular[SLICES_COUNT] =
+{
+ _T("year"),
+ _T("month"),
+ _T("week"),
+ _T("day"),
+ _T("hour"),
+ _T("minute"),
+ _T("second"),
+ _T("millisecond")
+};
+
+_TCHAR * slice_names_plural[SLICES_COUNT] =
+{
+ _T("years"),
+ _T("months"),
+ _T("weeks"),
+ _T("days"),
+ _T("hours"),
+ _T("minutes"),
+ _T("seconds"),
+ _T("milliseconds")
+};
+
+void print_uptime
+(
+ uint64_ tickcount,
+ uint64_ prevsliceval,
+ _TCHAR * prevsliceunit,
+ int curslice
+)
+{
+ uint64_ tick_cur = tickcount / ticks_per_slice[curslice];
+ uint64_ tick_residual = tickcount % ticks_per_slice[curslice];
+
+ assert(tick_cur <= (~((uint64_)0)));
+
+ if(tick_residual == 0)
+ {
+ /* the current slice is the last */
+
+ if(prevsliceval == 0)
+ {
+ /* the current slice is the only */
+ _tprintf
+ (
+ _T("%u %s"),
+ (unsigned)tick_cur,
+ (tick_cur == 1 ? slice_names_singular : slice_names_plural)[curslice]
+ );
+ }
+ else
+ {
+ /* the current slice is the last, and there's a previous slice */
+ assert(prevsliceunit);
+
+ /* print the previous and the current slice, and terminate */
+ _tprintf
+ (
+ _T("%u %s %s %u %s"),
+ (unsigned)prevsliceval,
+ prevsliceunit,
+ _T("and"),
+ (unsigned)tick_cur,
+ (tick_cur == 1 ? slice_names_singular : slice_names_plural)[curslice]
+ );
+ }
+ }
+ else if(tick_cur != 0)
+ {
+ /* the current slice is not the last, and non-zero */
+
+ if(prevsliceval != 0)
+ {
+ /* there's a previous slice: print it */
+ assert(prevsliceunit);
+ _tprintf(_T("%u %s, "), (unsigned)prevsliceval, prevsliceunit);
+ }
+
+ /* recursion on the next slice size, storing the current slice */
+ print_uptime
+ (
+ tick_residual,
+ tick_cur,
+ (tick_cur == 1 ? slice_names_singular : slice_names_plural)[curslice],
+ curslice + 1
+ );
+ }
+ else
+ {
+ /*
+ the current slice is not the last, and zero: recursion, remembering the
+ previous non-zero slice
+ */
+ print_uptime(tick_residual, prevsliceval, prevsliceunit, curslice + 1);
+ }
+}
+
+int parse_print(const _TCHAR * str)
+{
+ int64_ tickcount;
+
+ tickcount = _ttoi64(str);
+
+ if(tickcount < 0)
+ tickcount = - tickcount;
+ else if(tickcount == 0)
+ return 1;
+
+ print_uptime(tickcount, 0, NULL, 0);
+ _puttc(_T('\n'), stdout);
+
+ return 0;
+}
+
+int _tmain(int argc, _TCHAR * argv[])
+{
+ int r;
+
+ if(argc <= 1)
+ {
+ print_uptime((uint64_)GetTickCount(), 0, NULL, 0);
+ _puttc(_T('\n'), stdout);
+ }
+ else if(argc == 2 && argv[1][0] == _T('-') && argv[1][1] == 0)
+ {
+ while(!feof(stdin))
+ {
+ _TCHAR buf[23];
+ _TCHAR * str;
+
+ str = _fgetts(buf, 22, stdin);
+
+ if(str == NULL)
+ return 0;
+
+ if((r = parse_print(str)) != 0)
+ return r;
+ }
+ }
+ else
+ {
+ int i;
+
+ for(i = 1; i < argc; ++ i)
+ if((r = parse_print(argv[i])) != 0)
+ return r;
+ }
+
+ return 0;
+}