mirror of
https://github.com/UzixLS/KernelEx.git
synced 2025-07-18 23:11:19 +03:00
import KernelEx-4.0-Final
This commit is contained in:
72
core/Core.rc
Executable file → Normal file
72
core/Core.rc
Executable file → Normal file
@ -1,7 +1,5 @@
|
||||
#include "resource.h"
|
||||
#include "version.h"
|
||||
#define _QUOTEME(x) #x
|
||||
#define QUOTEME(x) _QUOTEME(x)
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@ -41,7 +39,7 @@ END
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Polish resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_PLK)
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_POL)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
|
||||
#pragma code_page(1250)
|
||||
@ -98,7 +96,7 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Xeno86\0"
|
||||
VALUE "FileDescription", "KernelEx Core\0"
|
||||
VALUE "FileVersion", QUOTEME(RCVERSION) "\0"
|
||||
VALUE "FileVersion", _RCVERSION_ "\0"
|
||||
VALUE "InternalName", "KernelEx\0"
|
||||
VALUE "LegalCopyright", "Copyright <20> 2009, Xeno86\0"
|
||||
VALUE "OriginalFilename", "KernelEx.dll\0"
|
||||
@ -114,9 +112,73 @@ END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
#ifdef _DEBUG
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_DEBUG DIALOG DISCARDABLE 0, 0, 186, 100
|
||||
STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU |
|
||||
WS_THICKFRAME
|
||||
CAPTION "KernelEx Debug Console"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
CONTROL "",IDC_LOG,"SysListView32",LVS_REPORT | WS_TABSTOP,0,0,
|
||||
185,100
|
||||
END
|
||||
|
||||
IDD_DEBUGFILTER DIALOG DISCARDABLE 0, 0, 177, 90
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Filter settings"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,65,70,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,120,70,50,14
|
||||
EDITTEXT IDC_DFINCLUDE,5,15,165,14,ES_AUTOHSCROLL
|
||||
EDITTEXT IDC_DFEXCLUDE,5,45,165,14,ES_AUTOHSCROLL
|
||||
LTEXT "Include:",IDC_STATIC,5,5,26,8
|
||||
LTEXT "Exclude:",IDC_STATIC,5,35,28,8
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDR_LOGMENU MENU DISCARDABLE
|
||||
BEGIN
|
||||
POPUP ""
|
||||
BEGIN
|
||||
MENUITEM "Save to file", IDM_TOFILE
|
||||
MENUITEM "Clear", IDM_CLEAR
|
||||
MENUITEM "Filter", IDM_FILTER
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO DISCARDABLE
|
||||
BEGIN
|
||||
IDD_DEBUGFILTER, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 170
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 83
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Polish resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // _DEBUG
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
|
431
core/DebugWindow.cpp
Normal file
431
core/DebugWindow.cpp
Normal file
@ -0,0 +1,431 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx 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; version 2 of the License.
|
||||
*
|
||||
* KernelEx 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 GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <malloc.h>
|
||||
#include "DebugWindow.h"
|
||||
#include "resource.h"
|
||||
#include "internals.h"
|
||||
#include "debug.h"
|
||||
|
||||
const unsigned short WM_KEXSTOPDEBUG = 0x6eee;
|
||||
const unsigned short WM_KEXAPPENDLOG = 0x6eef;
|
||||
|
||||
DebugWindow* DebugWindow::instance = NULL;
|
||||
|
||||
extern "C"
|
||||
char* strtok_r(char* s, const char* delim, char** holder);
|
||||
|
||||
|
||||
DebugWindow::DebugWindow()
|
||||
{
|
||||
DWORD tid;
|
||||
hwnd = (HWND) -1;
|
||||
includes.push_back("*");
|
||||
InitializeCriticalSection(&cs);
|
||||
InitCommonControls();
|
||||
hThread = CreateThread(NULL, 0, thread, (void*) this, 0, &tid);
|
||||
}
|
||||
|
||||
DebugWindow::~DebugWindow()
|
||||
{
|
||||
DeleteCriticalSection(&cs);
|
||||
SendMessage(hwnd, WM_KEXSTOPDEBUG, 0, 0);
|
||||
}
|
||||
|
||||
BOOL CALLBACK DebugWindow::DebugDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
NMHDR* nmhdr;
|
||||
DebugWindow* _this = (DebugWindow*) GetWindowLong(hwnd, GWL_USERDATA);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
_this = (DebugWindow*) lParam;
|
||||
SetWindowLong(hwnd, GWL_USERDATA, lParam);
|
||||
_this->InitDialog(hwnd);
|
||||
break;
|
||||
case WM_SIZE:
|
||||
MoveWindow(GetDlgItem(hwnd, IDC_LOG), 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
|
||||
SendDlgItemMessage(hwnd, IDC_LOG, WM_VSCROLL, SB_BOTTOM, 0);
|
||||
break;
|
||||
case WM_KEXSTOPDEBUG:
|
||||
DestroyWindow(hwnd);
|
||||
break;
|
||||
case WM_KEXAPPENDLOG:
|
||||
_this->AppendLog((char*) lParam);
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
nmhdr = (NMHDR*) lParam;
|
||||
if (nmhdr->idFrom == IDC_LOG && nmhdr->code == NM_RCLICK)
|
||||
{
|
||||
_this->HandleMenu();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void DebugWindow::InitDialog(HWND hwnd)
|
||||
{
|
||||
hList = GetDlgItem(hwnd, IDC_LOG);
|
||||
SetClassLong(hwnd, GCL_STYLE, GetClassLong(hwnd, GCL_STYLE) | CS_NOCLOSE);
|
||||
MoveWindow(hwnd, 0, 0, 320, 200, TRUE);
|
||||
SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE,
|
||||
0, LVS_EX_FULLROWSELECT);
|
||||
|
||||
LV_COLUMN col;
|
||||
memset(&col, 0, sizeof(col));
|
||||
col.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
|
||||
|
||||
col.cx = 80;
|
||||
col.pszText = "Process";
|
||||
ListView_InsertColumn(hList, 0, &col);
|
||||
col.cx = 60;
|
||||
col.pszText = "Thread";
|
||||
ListView_InsertColumn(hList, 1, &col);
|
||||
col.cx = 80;
|
||||
col.pszText = "Source";
|
||||
ListView_InsertColumn(hList, 2, &col);
|
||||
col.cx = 80;
|
||||
col.pszText = "Dest";
|
||||
ListView_InsertColumn(hList, 3, &col);
|
||||
col.cx = 120;
|
||||
col.pszText = "Function";
|
||||
ListView_InsertColumn(hList, 4, &col);
|
||||
col.cx = 40;
|
||||
col.mask |= LVCF_FMT;
|
||||
col.fmt = LVCFMT_RIGHT;
|
||||
col.pszText = "Return";
|
||||
ListView_InsertColumn(hList, 5, &col);
|
||||
|
||||
menu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_LOGMENU));
|
||||
menu = GetSubMenu(menu, 0);
|
||||
}
|
||||
|
||||
void DebugWindow::HandleMenu()
|
||||
{
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
|
||||
int res = TrackPopupMenu(menu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RETURNCMD,
|
||||
p.x, p.y, 0, hwnd, NULL);
|
||||
switch (res)
|
||||
{
|
||||
case IDM_TOFILE:
|
||||
WriteToFile();
|
||||
break;
|
||||
case IDM_CLEAR:
|
||||
//FIXME: when there is a lot of entries it takes very long to clear the list
|
||||
//how to improve this?
|
||||
ListView_DeleteAllItems(hList);
|
||||
break;
|
||||
case IDM_FILTER:
|
||||
DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_DEBUGFILTER),
|
||||
hwnd, FilterDlgProc, (LPARAM) this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DebugWindow::AppendLog(char* msg)
|
||||
{
|
||||
LV_ITEM item;
|
||||
int idx;
|
||||
HWND hList = GetDlgItem(hwnd, IDC_LOG);
|
||||
char* p;
|
||||
char* pch;
|
||||
|
||||
memset(&item, 0, sizeof(item));
|
||||
|
||||
pch = strtok_r(msg, "|", &p);
|
||||
if (!pch)
|
||||
return;
|
||||
|
||||
item.mask = LVIF_TEXT;
|
||||
item.iItem = ListView_GetItemCount(hList);
|
||||
item.iSubItem = 0;
|
||||
item.pszText = pch;
|
||||
idx = ListView_InsertItem(hList, &item);
|
||||
|
||||
while ((pch = strtok_r(NULL, "|", &p)) != NULL)
|
||||
{
|
||||
item.iSubItem++;
|
||||
item.pszText = pch;
|
||||
ListView_SetItem(hList, &item);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CALLBACK DebugWindow::FilterDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
DebugWindow* _this = (DebugWindow*) GetWindowLong(hwnd, GWL_USERDATA);
|
||||
int len1, len2;
|
||||
char* buf;
|
||||
char* pch;
|
||||
char* p;
|
||||
list<sstring>::const_iterator it;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
_this = (DebugWindow*) lParam;
|
||||
SetWindowLong(hwnd, GWL_USERDATA, lParam);
|
||||
|
||||
len1 = 0;
|
||||
len2 = 0;
|
||||
for (it = _this->includes.begin() ; it != _this->includes.end() ; it++)
|
||||
len1 += it->length() + 1;
|
||||
for (it = _this->excludes.begin() ; it != _this->excludes.end() ; it++)
|
||||
len2 += it->length() + 1;
|
||||
buf = (char*) alloca(max(len1, len2));
|
||||
|
||||
buf[0] = '\0';
|
||||
for (it = _this->includes.begin() ; it != _this->includes.end() ; it++)
|
||||
{
|
||||
if (it != _this->includes.begin())
|
||||
strcat(buf, ";");
|
||||
strcat(buf, *it);
|
||||
}
|
||||
SetDlgItemText(hwnd, IDC_DFINCLUDE, buf);
|
||||
|
||||
buf[0] = '\0';
|
||||
for (it = _this->excludes.begin() ; it != _this->excludes.end() ; it++)
|
||||
{
|
||||
if (it != _this->excludes.begin())
|
||||
strcat(buf, ";");
|
||||
strcat(buf, *it);
|
||||
}
|
||||
SetDlgItemText(hwnd, IDC_DFEXCLUDE, buf);
|
||||
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDCANCEL:
|
||||
EndDialog(hwnd, 0);
|
||||
break;
|
||||
case IDOK:
|
||||
len1 = GetWindowTextLength(GetDlgItem(hwnd, IDC_DFINCLUDE)) + 1;
|
||||
len2 = GetWindowTextLength(GetDlgItem(hwnd, IDC_DFEXCLUDE)) + 1;
|
||||
buf = (char*) alloca(max(len1, len2));
|
||||
EnterCriticalSection(&_this->cs);
|
||||
|
||||
GetDlgItemText(hwnd, IDC_DFINCLUDE, buf, len1);
|
||||
_this->includes.clear();
|
||||
pch = strtok_r(buf, ";", &p);
|
||||
if (pch)
|
||||
{
|
||||
_this->includes.push_back(pch);
|
||||
while ((pch = strtok_r(NULL, ";", &p)) != NULL)
|
||||
_this->includes.push_back(pch);
|
||||
}
|
||||
|
||||
GetDlgItemText(hwnd, IDC_DFEXCLUDE, buf, len2);
|
||||
_this->excludes.clear();
|
||||
pch = strtok_r(buf, ";", &p);
|
||||
if (pch)
|
||||
{
|
||||
_this->excludes.push_back(pch);
|
||||
while ((pch = strtok_r(NULL, ";", &p)) != NULL)
|
||||
_this->excludes.push_back(pch);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&_this->cs);
|
||||
EndDialog(hwnd, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
EndDialog(hwnd, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void DebugWindow::WriteToFile()
|
||||
{
|
||||
char buf[DEBUGMSG_MAXLEN];
|
||||
OPENFILENAME ofn;
|
||||
int rows;
|
||||
LV_COLUMN col;
|
||||
char filename[MAX_PATH];
|
||||
HANDLE hFile;
|
||||
HMODULE hComDlg32;
|
||||
BOOL (WINAPI* pGetSaveFileName)(OPENFILENAME*);
|
||||
|
||||
hComDlg32 = LoadLibrary("COMDLG32.DLL");
|
||||
if (!hComDlg32)
|
||||
return;
|
||||
pGetSaveFileName = (BOOL (WINAPI*)(OPENFILENAME*))
|
||||
GetProcAddress(hComDlg32, "GetSaveFileNameA");
|
||||
if (!pGetSaveFileName)
|
||||
goto __fini;
|
||||
|
||||
filename[0] = '\0';
|
||||
memset(&ofn, 0, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hwnd;
|
||||
ofn.hInstance = hInstance;
|
||||
ofn.lpstrFilter = "Text file\0*.txt\0";
|
||||
ofn.lpstrDefExt = ".txt";
|
||||
ofn.lpstrFile = filename;
|
||||
ofn.nMaxFile = sizeof(filename);
|
||||
ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
|
||||
if (!pGetSaveFileName(&ofn))
|
||||
goto __fini;
|
||||
|
||||
hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
goto __fini;
|
||||
|
||||
//write column headers
|
||||
col.mask = LVCF_TEXT;
|
||||
col.pszText = buf;
|
||||
col.cchTextMax = sizeof(buf);
|
||||
DWORD wlen;
|
||||
for (int j = 0 ; j < 6 ; j++)
|
||||
{
|
||||
DWORD len;
|
||||
ListView_GetColumn(hList, j, &col);
|
||||
len = strlen(buf);
|
||||
if (j) WriteFile(hFile, "|", 1, &wlen, NULL);
|
||||
WriteFile(hFile, buf, len, &wlen, NULL);
|
||||
}
|
||||
WriteFile(hFile, "\r\n", 2, &wlen, NULL);
|
||||
|
||||
//write rows
|
||||
rows = ListView_GetItemCount(hList);
|
||||
for (int i = 0 ; i < rows ; i++)
|
||||
{
|
||||
for (int j = 0 ; j < 6 ; j++)
|
||||
{
|
||||
DWORD len; DWORD wlen;
|
||||
ListView_GetItemText(hList, i, j, buf, sizeof(buf));
|
||||
len = strlen(buf);
|
||||
if (j) WriteFile(hFile, "|", 1, &wlen, NULL);
|
||||
WriteFile(hFile, buf, len, &wlen, NULL);
|
||||
}
|
||||
WriteFile(hFile, "\r\n", 2, &wlen, NULL);
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
|
||||
MessageBox(hwnd, "File written successfully", "Information", MB_ICONINFORMATION | MB_OK);
|
||||
|
||||
__fini:
|
||||
FreeLibrary(hComDlg32);
|
||||
}
|
||||
|
||||
DWORD WINAPI DebugWindow::thread(void* param)
|
||||
{
|
||||
MSG msg;
|
||||
DebugWindow* _this = (DebugWindow*) param;
|
||||
_this->hwnd = CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_DEBUG),
|
||||
NULL, DebugDlgProc, (LPARAM) _this);
|
||||
ShowWindow(_this->hwnd, SW_MINIMIZE);
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
DispatchMessage(&msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DebugWindow::append(const char* str)
|
||||
{
|
||||
static char msg[DEBUGMSG_MAXLEN];
|
||||
bool filter_out = true;
|
||||
list<sstring>::const_iterator it;
|
||||
|
||||
EnterCriticalSection(&cs);
|
||||
|
||||
//filter out based on includes and excludes
|
||||
if (includes.size() != 0)
|
||||
{
|
||||
if (includes.size() == 1 && strcmp(includes.front(), "*") == 0)
|
||||
filter_out = false;
|
||||
else for (it = includes.begin() ; it != includes.end() ; it++)
|
||||
if (strstr(str, *it))
|
||||
{
|
||||
filter_out = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!filter_out)
|
||||
for (it = excludes.begin() ; it != excludes.end() ; it++)
|
||||
if (strstr(str, *it))
|
||||
{
|
||||
filter_out = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (filter_out)
|
||||
{
|
||||
LeaveCriticalSection(&cs);
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(msg, str, sizeof(msg));
|
||||
msg[sizeof(msg) - 1] = '\0';
|
||||
|
||||
SendMessage(hwnd, WM_KEXAPPENDLOG, 0, (LPARAM) msg);
|
||||
|
||||
LeaveCriticalSection(&cs);
|
||||
SendMessage(hList, WM_VSCROLL, SB_BOTTOM, 0);
|
||||
}
|
||||
|
||||
DebugWindow* DebugWindow::get()
|
||||
{
|
||||
if (instance->hwnd == (HWND) -1 || instance->hwnd == NULL)
|
||||
{
|
||||
delete instance;
|
||||
instance = NULL;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool DebugWindow::create()
|
||||
{
|
||||
instance = new DebugWindow;
|
||||
if (instance->hThread)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
delete instance;
|
||||
instance = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void DebugWindow::destroy()
|
||||
{
|
||||
if (instance)
|
||||
delete instance;
|
||||
}
|
63
core/DebugWindow.h
Normal file
63
core/DebugWindow.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx 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; version 2 of the License.
|
||||
*
|
||||
* KernelEx 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 GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DEBUG_WINDOW_H
|
||||
#define __DEBUG_WINDOW_H
|
||||
|
||||
#include "sstring.hpp"
|
||||
#pragma warning(disable:4530) //we don't do exception handling
|
||||
#include <list>
|
||||
#pragma warning(default:4530)
|
||||
|
||||
using namespace std;
|
||||
|
||||
class DebugWindow
|
||||
{
|
||||
public:
|
||||
DebugWindow();
|
||||
~DebugWindow();
|
||||
|
||||
static bool create();
|
||||
static void destroy();
|
||||
static DebugWindow* get();
|
||||
void append(const char* str);
|
||||
|
||||
private:
|
||||
HWND hwnd;
|
||||
HWND hList;
|
||||
HANDLE hThread;
|
||||
int max_entries;
|
||||
static DebugWindow* instance;
|
||||
CRITICAL_SECTION cs;
|
||||
HMENU menu;
|
||||
list<sstring> includes;
|
||||
list<sstring> excludes;
|
||||
|
||||
static BOOL CALLBACK DebugDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static BOOL CALLBACK FilterDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
void InitDialog(HWND hwnd);
|
||||
void HandleMenu();
|
||||
void AppendLog(char* msg);
|
||||
void WriteToFile();
|
||||
static DWORD WINAPI thread(void* param);
|
||||
};
|
||||
|
||||
#endif
|
39
core/SettingsDB.cpp
Executable file → Normal file
39
core/SettingsDB.cpp
Executable file → Normal file
@ -32,6 +32,7 @@ SettingsDB SettingsDB::instance;
|
||||
SettingsDB::SettingsDB()
|
||||
{
|
||||
InitializeCriticalSection(&cs);
|
||||
MakeCriticalSectionGlobal(&cs);
|
||||
}
|
||||
|
||||
SettingsDB::~SettingsDB()
|
||||
@ -55,6 +56,7 @@ void SettingsDB::flush_all()
|
||||
clear();
|
||||
parse_configs();
|
||||
parse_flags();
|
||||
add_apilib_excludes();
|
||||
LeaveCriticalSection(&cs);
|
||||
}
|
||||
|
||||
@ -92,7 +94,7 @@ void SettingsDB::parse_configs()
|
||||
if (type != REG_SZ)
|
||||
continue;
|
||||
name[sizeof(name) - 1] = '\0';
|
||||
as.conf = ApiConfigurationManager::get_api_configuration(name);
|
||||
as.conf = apiconfmgr.get_api_configuration(name);
|
||||
if (!as.conf)
|
||||
continue;
|
||||
|
||||
@ -161,6 +163,20 @@ void SettingsDB::parse_flags()
|
||||
RegCloseKey(key);
|
||||
}
|
||||
|
||||
void SettingsDB::add_apilib_excludes()
|
||||
{
|
||||
ApiLibrary* lib;
|
||||
int i = 1;
|
||||
appsetting as;
|
||||
as.flags = LDR_KEX_DISABLE;
|
||||
while ((lib = apilibmgr.get_apilib_by_index(i++)) != NULL)
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
lib->get_dll_path(path);
|
||||
db[path] = as;
|
||||
}
|
||||
}
|
||||
|
||||
appsetting SettingsDB::get_appsetting(const char* path)
|
||||
{
|
||||
map<sstring,appsetting>::const_iterator it;
|
||||
@ -173,7 +189,7 @@ appsetting SettingsDB::get_appsetting(const char* path)
|
||||
//then try wildcard matching
|
||||
for (it = db_wild.begin() ; it != db_wild.end() ; it++)
|
||||
{
|
||||
if (wildcmp(it->first.get(), path))
|
||||
if (wildcmp(it->first, path))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -181,7 +197,13 @@ appsetting SettingsDB::get_appsetting(const char* path)
|
||||
bool atend = it == db.end() || it == db_wild.end();
|
||||
LeaveCriticalSection(&cs);
|
||||
if (!atend)
|
||||
return it->second;
|
||||
{
|
||||
appsetting as = it->second;
|
||||
as.flags |= LDR_VALID_FLAG;
|
||||
if (!as.conf && !(as.flags & LDR_KEX_DISABLE))
|
||||
as.conf = apiconfmgr.get_default_configuration();
|
||||
return as;
|
||||
}
|
||||
else
|
||||
return appsetting();
|
||||
}
|
||||
@ -198,7 +220,7 @@ void SettingsDB::write_single(const char* path, const char* conf_name, BYTE flag
|
||||
strupr(path2);
|
||||
|
||||
//check if configuration name is valid
|
||||
as.conf = ApiConfigurationManager::get_api_configuration(conf_name);
|
||||
as.conf = apiconfmgr.get_api_configuration(conf_name);
|
||||
as.flags = flags;
|
||||
|
||||
//write config
|
||||
@ -206,9 +228,8 @@ void SettingsDB::write_single(const char* path, const char* conf_name, BYTE flag
|
||||
"Software\\KernelEx\\AppSettings\\Configs", 0, KEY_WRITE, &key);
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
if (!as.conf || as.conf == ApiConfigurationManager::get_default_configuration())
|
||||
RegSetValueEx(key, path, 0, REG_SZ, (const BYTE*) "default",
|
||||
sizeof("default"));
|
||||
if (!as.conf)
|
||||
RegDeleteValue(key, path);
|
||||
else
|
||||
RegSetValueEx(key, path, 0, REG_SZ, (const BYTE*) conf_name,
|
||||
strlen(conf_name) + 1);
|
||||
@ -241,7 +262,7 @@ void SettingsDB::dump_db()
|
||||
for (it = db.begin() ; it != db.end() ; it++)
|
||||
{
|
||||
ApiConfiguration* conf = it->second.conf;
|
||||
dbgprintf("%-40s %-10s %02x\n", it->first.get(),
|
||||
dbgprintf("%-40s %-10s %02x\n", static_cast<const char*>(it->first),
|
||||
conf ? conf->get_name() : "unknown", it->second.flags);
|
||||
}
|
||||
|
||||
@ -249,7 +270,7 @@ void SettingsDB::dump_db()
|
||||
for (it = db_wild.begin() ; it != db_wild.end() ; it++)
|
||||
{
|
||||
ApiConfiguration* conf = it->second.conf;
|
||||
dbgprintf("%-40s %-10s %02x\n", it->first.get(),
|
||||
dbgprintf("%-40s %-10s %02x\n", static_cast<const char*>(it->first),
|
||||
conf ? conf->get_name() : "unknown", it->second.flags);
|
||||
}
|
||||
}
|
||||
|
1
core/SettingsDB.h
Executable file → Normal file
1
core/SettingsDB.h
Executable file → Normal file
@ -61,6 +61,7 @@ private:
|
||||
SettingsDB();
|
||||
void parse_configs();
|
||||
void parse_flags();
|
||||
void add_apilib_excludes();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
85
core/apiconf.cpp
Executable file → Normal file
85
core/apiconf.cpp
Executable file → Normal file
@ -39,17 +39,6 @@ ApiConfiguration::ApiConfiguration(const char* new_name, const ApiConfiguration&
|
||||
if (!prepare(new_name))
|
||||
goto __error;
|
||||
|
||||
if (src.used_apilibs)
|
||||
{
|
||||
void* mem = malloc(src.used_apilibs_count * sizeof(ApiLibrary*));
|
||||
if (!mem)
|
||||
goto __error;
|
||||
|
||||
used_apilibs = (const ApiLibrary**) mem;
|
||||
copy(src.used_apilibs, src.used_apilibs + src.used_apilibs_count, used_apilibs);
|
||||
used_apilibs_count = src.used_apilibs_count;
|
||||
}
|
||||
|
||||
for (int i = 0 ; i < src.api_tables_count ; i++)
|
||||
{
|
||||
void* mem;
|
||||
@ -91,7 +80,6 @@ ApiConfiguration::~ApiConfiguration()
|
||||
}
|
||||
free(conf_name);
|
||||
free(api_tables);
|
||||
free(used_apilibs);
|
||||
}
|
||||
|
||||
bool ApiConfiguration::prepare(const char* name)
|
||||
@ -103,31 +91,11 @@ bool ApiConfiguration::prepare(const char* name)
|
||||
|
||||
strcpy(conf_name, name);
|
||||
|
||||
api_tables = (ModuleApi*) calloc(new_overridden_mod_cnt, sizeof(ModuleApi));
|
||||
api_tables = (ModuleApi*) calloc(overridden_module_count, sizeof(ModuleApi));
|
||||
if (!api_tables)
|
||||
return false;
|
||||
|
||||
api_tables_count = new_overridden_mod_cnt;
|
||||
used_apilibs = NULL;
|
||||
used_apilibs_count = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ApiConfiguration::add_to_used_apilibs(const ApiLibrary* apilib)
|
||||
{
|
||||
for (int i = 0 ; i < used_apilibs_count ; i++)
|
||||
{
|
||||
if (used_apilibs[i] == apilib)
|
||||
return true;
|
||||
}
|
||||
|
||||
//not found => add to list
|
||||
void* mem = realloc(used_apilibs, (used_apilibs_count + 1) * sizeof(ApiLibrary*));
|
||||
if (!mem)
|
||||
return false;
|
||||
|
||||
used_apilibs = (const ApiLibrary**) mem;
|
||||
used_apilibs[used_apilibs_count++] = apilib;
|
||||
api_tables_count = overridden_module_count;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -136,23 +104,20 @@ bool ApiConfiguration::merge(const ApiLibrary* apilib)
|
||||
if (!apilib)
|
||||
return false;
|
||||
|
||||
if (!add_to_used_apilibs(apilib))
|
||||
return false;
|
||||
|
||||
for (int i = 0 ; i < new_overridden_mod_cnt ; i++)
|
||||
for (int i = 0 ; i < overridden_module_count ; i++)
|
||||
{
|
||||
const apilib_api_table* psrc = apilib->api_tables;
|
||||
while (psrc->target_library)
|
||||
{
|
||||
if (!strcmpi(psrc->target_library, new_overridden_mod_nms[i]))
|
||||
if (!strcmpi(psrc->target_library, overridden_module_names[i]))
|
||||
{
|
||||
if (i >= api_tables_count)
|
||||
{
|
||||
void* mem = recalloc(api_tables, new_overridden_mod_cnt * sizeof(ModuleApi));
|
||||
void* mem = recalloc(api_tables, overridden_module_count * sizeof(ModuleApi));
|
||||
if (!mem)
|
||||
return false;
|
||||
api_tables = (ModuleApi*) mem;
|
||||
api_tables_count = new_overridden_mod_cnt;
|
||||
api_tables_count = overridden_module_count;
|
||||
}
|
||||
ModuleApi* pdst = api_tables + i;
|
||||
|
||||
@ -319,23 +284,20 @@ bool ApiConfiguration::merge(const char* module, unsigned short ordinal,
|
||||
return false;
|
||||
|
||||
int i;
|
||||
for (i = 0 ; i < new_overridden_mod_cnt ; i++)
|
||||
if (!strcmpi(module, new_overridden_mod_nms[i]))
|
||||
for (i = 0 ; i < overridden_module_count ; i++)
|
||||
if (!strcmpi(module, overridden_module_names[i]))
|
||||
break;
|
||||
|
||||
if (i == new_overridden_mod_cnt)
|
||||
return false;
|
||||
|
||||
if (!add_to_used_apilibs(apilib))
|
||||
if (i == overridden_module_count)
|
||||
return false;
|
||||
|
||||
if (api_tables_count <= i)
|
||||
{
|
||||
void* mem = recalloc(api_tables, new_overridden_mod_cnt * sizeof(ModuleApi));
|
||||
void* mem = recalloc(api_tables, overridden_module_count * sizeof(ModuleApi));
|
||||
if (!mem)
|
||||
return false;
|
||||
api_tables = (ModuleApi*) mem;
|
||||
api_tables_count = new_overridden_mod_cnt;
|
||||
api_tables_count = overridden_module_count;
|
||||
}
|
||||
|
||||
ModuleApi* pdst = api_tables + i;
|
||||
@ -388,23 +350,20 @@ bool ApiConfiguration::merge(const char* module, const char* api_name,
|
||||
return false;
|
||||
|
||||
int i;
|
||||
for (i = 0 ; i < new_overridden_mod_cnt ; i++)
|
||||
if (!strcmpi(module, new_overridden_mod_nms[i]))
|
||||
for (i = 0 ; i < overridden_module_count ; i++)
|
||||
if (!strcmpi(module, overridden_module_names[i]))
|
||||
break;
|
||||
|
||||
if (i == new_overridden_mod_cnt)
|
||||
if (i == overridden_module_count)
|
||||
return false;
|
||||
|
||||
if (!add_to_used_apilibs(apilib))
|
||||
return false;
|
||||
|
||||
if (api_tables_count <= i)
|
||||
{
|
||||
void* mem = recalloc(api_tables, new_overridden_mod_cnt * sizeof(ModuleApi));
|
||||
void* mem = recalloc(api_tables, overridden_module_count * sizeof(ModuleApi));
|
||||
if (!mem)
|
||||
return false;
|
||||
api_tables = (ModuleApi*) mem;
|
||||
api_tables_count = new_overridden_mod_cnt;
|
||||
api_tables_count = overridden_module_count;
|
||||
}
|
||||
|
||||
ModuleApi* pdst = api_tables + i;
|
||||
@ -446,11 +405,11 @@ bool ApiConfiguration::merge(const char* module, const char* api_name,
|
||||
bool ApiConfiguration::erase(const char* module, unsigned short ordinal)
|
||||
{
|
||||
int i;
|
||||
for (i = 0 ; i < new_overridden_mod_cnt ; i++)
|
||||
if (!strcmpi(module, new_overridden_mod_nms[i]))
|
||||
for (i = 0 ; i < overridden_module_count ; i++)
|
||||
if (!strcmpi(module, overridden_module_names[i]))
|
||||
break;
|
||||
|
||||
if (i == new_overridden_mod_cnt || i >= api_tables_count)
|
||||
if (i == overridden_module_count || i >= api_tables_count)
|
||||
return false;
|
||||
|
||||
ModuleApi* pdst = api_tables + i;
|
||||
@ -467,11 +426,11 @@ bool ApiConfiguration::erase(const char* module, unsigned short ordinal)
|
||||
bool ApiConfiguration::erase(const char* module, const char* api_name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0 ; i < new_overridden_mod_cnt ; i++)
|
||||
if (!strcmpi(module, new_overridden_mod_nms[i]))
|
||||
for (i = 0 ; i < overridden_module_count ; i++)
|
||||
if (!strcmpi(module, overridden_module_names[i]))
|
||||
break;
|
||||
|
||||
if (i == new_overridden_mod_cnt || i >= api_tables_count)
|
||||
if (i == overridden_module_count || i >= api_tables_count)
|
||||
return false;
|
||||
|
||||
ModuleApi* pdst = api_tables + i;
|
||||
|
3
core/apiconf.h
Executable file → Normal file
3
core/apiconf.h
Executable file → Normal file
@ -72,12 +72,9 @@ private:
|
||||
ModuleApi* api_tables;
|
||||
unsigned short api_tables_count;
|
||||
char* conf_name;
|
||||
const ApiLibrary** used_apilibs;
|
||||
int used_apilibs_count;
|
||||
bool initialized;
|
||||
|
||||
bool prepare(const char* name);
|
||||
bool add_to_used_apilibs(const ApiLibrary* apilib);
|
||||
};
|
||||
|
||||
inline bool ApiConfiguration::NamedApi::operator<(const NamedApi& a) const
|
||||
|
225
core/apiconfmgr.cpp
Executable file → Normal file
225
core/apiconfmgr.cpp
Executable file → Normal file
@ -29,38 +29,31 @@
|
||||
|
||||
#define ALLOC_CAPACITY 10
|
||||
|
||||
ApiConfiguration** ApiConfigurationManager::curr_apiconf_ptrs = NULL;
|
||||
int ApiConfigurationManager::curr_apiconf_cnt = 0;
|
||||
ApiConfiguration** ApiConfigurationManager::prev_apiconf_ptrs = NULL;
|
||||
int ApiConfigurationManager::prev_apiconf_cnt = 0;
|
||||
ApiConfiguration* ApiConfigurationManager::default_apiconf = NULL;
|
||||
|
||||
//TODO: I should check if new ApiConfiguration is identical to existing one
|
||||
//and deallocate it if this is true
|
||||
ApiConfigurationManager apiconfmgr;
|
||||
|
||||
ApiConfigurationManager::ApiConfigurationManager()
|
||||
{
|
||||
new_apiconf_ptrs = NULL;
|
||||
new_apiconf_cnt = 0;
|
||||
strcpy(core_conf_file, kernelex_dir.get());
|
||||
strcat(core_conf_file, "core.ini");
|
||||
apiconf_ptrs = NULL;
|
||||
apiconf_cnt = 0;
|
||||
default_apiconf = NULL;
|
||||
disable_extensions = false;
|
||||
}
|
||||
|
||||
ApiConfigurationManager::~ApiConfigurationManager()
|
||||
{
|
||||
for (int i = 0 ; i < new_apiconf_cnt ; i++)
|
||||
delete new_apiconf_ptrs[i];
|
||||
if (new_apiconf_ptrs)
|
||||
free(new_apiconf_ptrs);
|
||||
for (int i = 0 ; i < apiconf_cnt ; i++)
|
||||
delete apiconf_ptrs[i];
|
||||
if (apiconf_ptrs)
|
||||
free(apiconf_ptrs);
|
||||
}
|
||||
|
||||
bool ApiConfigurationManager::add_apiconf(ApiConfiguration* ac)
|
||||
{
|
||||
//allocate space for new ApiConfigurations
|
||||
if (new_apiconf_cnt % ALLOC_CAPACITY == 0)
|
||||
if (apiconf_cnt % ALLOC_CAPACITY == 0)
|
||||
{
|
||||
void* new_block = realloc(new_apiconf_ptrs,
|
||||
(new_apiconf_cnt + ALLOC_CAPACITY) * sizeof(ApiConfiguration*));
|
||||
void* new_block = realloc(apiconf_ptrs,
|
||||
(apiconf_cnt + ALLOC_CAPACITY) * sizeof(ApiConfiguration*));
|
||||
|
||||
if (!new_block)
|
||||
{
|
||||
@ -68,38 +61,42 @@ bool ApiConfigurationManager::add_apiconf(ApiConfiguration* ac)
|
||||
return false;
|
||||
}
|
||||
|
||||
new_apiconf_ptrs = (ApiConfiguration**) new_block;
|
||||
apiconf_ptrs = (ApiConfiguration**) new_block;
|
||||
}
|
||||
|
||||
//add to table of new ApiConfigurations
|
||||
new_apiconf_ptrs[new_apiconf_cnt++] = ac;
|
||||
apiconf_ptrs[apiconf_cnt++] = ac;
|
||||
return true;
|
||||
}
|
||||
|
||||
ApiConfiguration* ApiConfigurationManager::get_new_apiconf(const char* conf_name)
|
||||
{
|
||||
for (int i = 0 ; i < new_apiconf_cnt ; i++)
|
||||
if (!strcmp(new_apiconf_ptrs[i]->conf_name, conf_name))
|
||||
return new_apiconf_ptrs[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ApiConfiguration* ApiConfigurationManager::get_api_configuration(const char* conf_name)
|
||||
{
|
||||
if (!strcmp("default", conf_name))
|
||||
return get_default_configuration();
|
||||
|
||||
for (int i = 0 ; i < curr_apiconf_cnt ; i++)
|
||||
if (!strcmp(curr_apiconf_ptrs[i]->conf_name, conf_name))
|
||||
return curr_apiconf_ptrs[i];
|
||||
for (int i = 0 ; i < apiconf_cnt ; i++)
|
||||
if (!strcmp(apiconf_ptrs[i]->conf_name, conf_name))
|
||||
return apiconf_ptrs[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ApiConfigurationManager::reload_api_configurations()
|
||||
bool ApiConfigurationManager::load_api_configurations()
|
||||
{
|
||||
DBGPRINTF(("Reloading api configurations\n"));
|
||||
strcpy(core_conf_file, kernelex_dir);
|
||||
strcat(core_conf_file, "core.ini");
|
||||
|
||||
DBGPRINTF(("Loading api configurations\n"));
|
||||
|
||||
HKEY key;
|
||||
LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||||
"Software\\KernelEx", 0, KEY_WRITE, &key);
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD type, data, size = sizeof(data);
|
||||
RegQueryValueEx(key, "DisableExtensions", NULL, &type, (BYTE*) &data, &size);
|
||||
if (result == ERROR_SUCCESS && type == REG_DWORD && size == sizeof(data) && data == 1)
|
||||
disable_extensions = true;
|
||||
RegCloseKey(key);
|
||||
}
|
||||
|
||||
default_apiconf_index = GetPrivateProfileInt(
|
||||
int default_apiconf_index = GetPrivateProfileInt(
|
||||
"ApiConfigurations", "default", 0, core_conf_file);
|
||||
|
||||
for (int i = 0 ; i < 65536 ; i++)
|
||||
@ -116,7 +113,7 @@ void ApiConfigurationManager::reload_api_configurations()
|
||||
if (i <= default_apiconf_index)
|
||||
{
|
||||
DBGPRINTF(("Failed to load default api configuration - aborting\n"));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -132,7 +129,7 @@ void ApiConfigurationManager::reload_api_configurations()
|
||||
}
|
||||
else
|
||||
{
|
||||
ApiConfiguration* src_conf = get_new_apiconf(buf);
|
||||
ApiConfiguration* src_conf = get_api_configuration(buf);
|
||||
if (!src_conf)
|
||||
{
|
||||
DBGPRINTF(("Cannot inherit: %s. Configuration not found\n", buf));
|
||||
@ -159,40 +156,33 @@ __error:
|
||||
if (i == default_apiconf_index)
|
||||
{
|
||||
DBGPRINTF(("Failed to load default api configuration - aborting\n"));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
} //for loop
|
||||
|
||||
DBGPRINTF(("No more api configurations\n"));
|
||||
|
||||
FullCritLock();
|
||||
|
||||
if (commit_changes())
|
||||
{
|
||||
DBGPRINTF(("Re-add api libraries for previous api configurations\n"));
|
||||
for (int i = 0 ; i < prev_apiconf_cnt ; i++)
|
||||
for (int j = 0 ; j < prev_apiconf_ptrs[i]->used_apilibs_count ; j++)
|
||||
if (!libmgr.load_apilib(prev_apiconf_ptrs[i]->used_apilibs[j]->apilib_name))
|
||||
DBGPRINTF(("Error\n"));
|
||||
|
||||
libmgr.commit_changes();
|
||||
}
|
||||
//set default apiconf
|
||||
if (default_apiconf_index >= 0)
|
||||
default_apiconf = apiconf_ptrs[default_apiconf_index];
|
||||
else
|
||||
DBGPRINTF(("Bailing out\n"));
|
||||
{
|
||||
DBGPRINTF(("Failed to load default api configuration - aborting\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
FullCritUnlock();
|
||||
DBGPRINTF(("Default api configuration is: %s\n", default_apiconf->get_name()));
|
||||
DBGPRINTF(("API extensions are by default: %s\n",
|
||||
disable_extensions ? "disabled" : "enabled"));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ApiConfigurationManager::join_apilibs(ApiConfiguration* apiconf)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
if (!GetPrivateProfileString(apiconf->get_name(), "contents", "",
|
||||
buf, sizeof(buf), core_conf_file) || !strcmpi(buf, "none"))
|
||||
{
|
||||
DBGPRINTF(("No contents found\n"));
|
||||
}
|
||||
else
|
||||
if (GetPrivateProfileString(apiconf->get_name(), "contents", "",
|
||||
buf, sizeof(buf), core_conf_file) && strcmpi(buf, "none") != 0)
|
||||
{
|
||||
char buf2[256];
|
||||
|
||||
@ -201,7 +191,7 @@ bool ApiConfigurationManager::join_apilibs(ApiConfiguration* apiconf)
|
||||
char* lib = strtok(buf, ",");
|
||||
while (lib)
|
||||
{
|
||||
if (!libmgr.load_apilib(lib))
|
||||
if (!apilibmgr.load_apilib(lib))
|
||||
{
|
||||
DBGPRINTF(("Failed to load api library: %s\n", lib));
|
||||
return false;
|
||||
@ -214,7 +204,7 @@ bool ApiConfigurationManager::join_apilibs(ApiConfiguration* apiconf)
|
||||
lib = strtok(buf2, ",");
|
||||
while (lib)
|
||||
{
|
||||
if (!apiconf->merge(libmgr.get_new_apilib(lib)))
|
||||
if (!apiconf->merge(apilibmgr.get_apilib(lib)))
|
||||
{
|
||||
DBGPRINTF(("Failed to merge api library: %s\n", lib));
|
||||
return false;
|
||||
@ -313,7 +303,7 @@ bool ApiConfigurationManager::parse_overrides(ApiConfiguration* apiconf)
|
||||
else
|
||||
{
|
||||
if (!apiconf->merge(module, api_name,
|
||||
libmgr.get_new_apilib(apilib_name), id))
|
||||
apilibmgr.get_apilib(apilib_name), id))
|
||||
{
|
||||
DBGPRINTF(("Failed to merge named api overrides\n"));
|
||||
return false;
|
||||
@ -411,7 +401,7 @@ bool ApiConfigurationManager::parse_overrides(ApiConfiguration* apiconf)
|
||||
else
|
||||
{
|
||||
if (!apiconf->merge(module, (WORD) ordinal,
|
||||
libmgr.get_new_apilib(apilib_name), id))
|
||||
apilibmgr.get_apilib(apilib_name), id))
|
||||
{
|
||||
DBGPRINTF(("Failed to merge ordinal api overrides\n"));
|
||||
return false;
|
||||
@ -422,113 +412,14 @@ bool ApiConfigurationManager::parse_overrides(ApiConfiguration* apiconf)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ApiConfigurationManager::commit_changes()
|
||||
{
|
||||
DBGPRINTF(("Updating api configuration list\n"));
|
||||
|
||||
//calculate number of apiconf in use
|
||||
WORD imteMax = *pimteMax;
|
||||
IMTE** pmteModTable = *ppmteModTable;
|
||||
int used = 0;
|
||||
for (int j = 0 ; j < curr_apiconf_cnt ; j++)
|
||||
{
|
||||
for (WORD i = 0 ; i < imteMax ; i++)
|
||||
{
|
||||
IMTE_KEX* imte = (IMTE_KEX*) pmteModTable[i];
|
||||
if (imte && imte->config == curr_apiconf_ptrs[j])
|
||||
{
|
||||
used++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int j = 0 ; j < prev_apiconf_cnt ; j++)
|
||||
{
|
||||
for (WORD i = 0 ; i < imteMax ; i++)
|
||||
{
|
||||
IMTE_KEX* imte = (IMTE_KEX*) pmteModTable[i];
|
||||
if (imte && imte->config == prev_apiconf_ptrs[j])
|
||||
{
|
||||
used++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//alloc space for new_prev
|
||||
ApiConfiguration** new_prev;
|
||||
new_prev = (ApiConfiguration**) malloc(used * sizeof(ApiConfiguration*));
|
||||
if (!new_prev)
|
||||
return false;
|
||||
|
||||
int cnt = 0;
|
||||
|
||||
//move used entries from curr and prev to new_prev, free unused
|
||||
for (int j = 0 ; j < curr_apiconf_cnt ; j++)
|
||||
{
|
||||
WORD i;
|
||||
for (i = 0 ; i < imteMax ; i++)
|
||||
{
|
||||
IMTE_KEX* imte = (IMTE_KEX*) pmteModTable[i];
|
||||
if (imte && imte->config == curr_apiconf_ptrs[j])
|
||||
{
|
||||
new_prev[cnt++] = curr_apiconf_ptrs[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == imteMax)
|
||||
delete curr_apiconf_ptrs[j];
|
||||
}
|
||||
for (int j = 0 ; j < prev_apiconf_cnt ; j++)
|
||||
{
|
||||
WORD i;
|
||||
for (i = 0 ; i < imteMax ; i++)
|
||||
{
|
||||
IMTE_KEX* imte = (IMTE_KEX*) pmteModTable[i];
|
||||
if (imte && imte->config == prev_apiconf_ptrs[j])
|
||||
{
|
||||
new_prev[cnt++] = prev_apiconf_ptrs[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == imteMax)
|
||||
delete curr_apiconf_ptrs[j];
|
||||
}
|
||||
|
||||
//replace prev with new_prev
|
||||
if (prev_apiconf_ptrs)
|
||||
free(prev_apiconf_ptrs);
|
||||
prev_apiconf_ptrs = new_prev;
|
||||
prev_apiconf_cnt = cnt;
|
||||
|
||||
//replace curr with new
|
||||
if (curr_apiconf_ptrs)
|
||||
free(curr_apiconf_ptrs);
|
||||
curr_apiconf_ptrs = new_apiconf_ptrs;
|
||||
curr_apiconf_cnt = new_apiconf_cnt;
|
||||
new_apiconf_ptrs = NULL;
|
||||
new_apiconf_cnt = 0;
|
||||
|
||||
//set default apiconf
|
||||
if (default_apiconf_index >= 0)
|
||||
default_apiconf = curr_apiconf_ptrs[default_apiconf_index];
|
||||
else
|
||||
default_apiconf = NULL;
|
||||
|
||||
DBGPRINTF(("Default api configuration is: %s\n",
|
||||
default_apiconf ? default_apiconf->get_name() : "system"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
void ApiConfigurationManager::dump_configurations()
|
||||
{
|
||||
dbgprintf("Dumping all api configurations (count = %d) ...\n\n", curr_apiconf_cnt);
|
||||
for (int i = 0 ; i < curr_apiconf_cnt ; i++)
|
||||
dbgprintf("Dumping all api configurations (count = %d) ...\n\n", apiconf_cnt);
|
||||
for (int i = 0 ; i < apiconf_cnt ; i++)
|
||||
{
|
||||
curr_apiconf_ptrs[i]->dump();
|
||||
apiconf_ptrs[i]->dump();
|
||||
}
|
||||
dbgprintf("End dump\n\n");
|
||||
}
|
||||
|
32
core/apiconfmgr.h
Executable file → Normal file
32
core/apiconfmgr.h
Executable file → Normal file
@ -29,34 +29,27 @@ class ApiConfigurationManager
|
||||
public:
|
||||
ApiConfigurationManager();
|
||||
~ApiConfigurationManager();
|
||||
void reload_api_configurations();
|
||||
static ApiConfiguration* get_api_configuration(const char* conf_name);
|
||||
static ApiConfiguration* get_default_configuration();
|
||||
bool load_api_configurations();
|
||||
ApiConfiguration* get_default_configuration();
|
||||
bool are_extensions_disabled();
|
||||
ApiConfiguration* get_api_configuration(const char* conf_name);
|
||||
|
||||
#ifdef _DEBUG
|
||||
static void dump_configurations();
|
||||
void dump_configurations();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
char core_conf_file[MAX_PATH];
|
||||
ApiConfiguration** new_apiconf_ptrs;
|
||||
int new_apiconf_cnt;
|
||||
int default_apiconf_index;
|
||||
ApiLibraryManager libmgr;
|
||||
|
||||
static ApiConfiguration** curr_apiconf_ptrs;
|
||||
static int curr_apiconf_cnt;
|
||||
static ApiConfiguration** prev_apiconf_ptrs;
|
||||
static int prev_apiconf_cnt;
|
||||
static ApiConfiguration* default_apiconf;
|
||||
ApiConfiguration** apiconf_ptrs;
|
||||
int apiconf_cnt;
|
||||
ApiConfiguration* default_apiconf;
|
||||
bool disable_extensions;
|
||||
|
||||
bool join_apilibs(ApiConfiguration* apiconf);
|
||||
bool parse_overrides(ApiConfiguration* apiconf);
|
||||
bool add_apiconf(ApiConfiguration* ac);
|
||||
ApiConfiguration* get_new_apiconf(const char* conf_name);
|
||||
bool commit_changes();
|
||||
};
|
||||
|
||||
inline ApiConfiguration* ApiConfigurationManager::get_default_configuration()
|
||||
@ -64,4 +57,11 @@ inline ApiConfiguration* ApiConfigurationManager::get_default_configuration()
|
||||
return default_apiconf;
|
||||
}
|
||||
|
||||
inline bool ApiConfigurationManager::are_extensions_disabled()
|
||||
{
|
||||
return disable_extensions;
|
||||
}
|
||||
|
||||
extern ApiConfigurationManager apiconfmgr;
|
||||
|
||||
#endif
|
||||
|
389
core/apilib.cpp
Executable file → Normal file
389
core/apilib.cpp
Executable file → Normal file
@ -32,36 +32,40 @@ using namespace std;
|
||||
|
||||
#define ALLOC_CAPACITY 10
|
||||
|
||||
ApiLibrary** ApiLibraryManager::apilib_ptrs = NULL;
|
||||
int ApiLibraryManager::apilib_cnt = 0;
|
||||
|
||||
int overridden_module_count;
|
||||
const char** overridden_module_names;
|
||||
const char** new_overridden_mod_nms;
|
||||
int new_overridden_mod_cnt;
|
||||
int overridden_module_count;
|
||||
|
||||
ApiLibraryManager apilibmgr;
|
||||
|
||||
void ApiLibrary::get_dll_path(char* out)
|
||||
{
|
||||
strcpy(out, kernelex_dir);
|
||||
strcat(out, apilib_name);
|
||||
strcat(out, ".DLL");
|
||||
}
|
||||
|
||||
ApiLibraryManager::ApiLibraryManager()
|
||||
{
|
||||
new_apilib_ptrs = NULL;
|
||||
new_apilib_cnt = 0;
|
||||
new_overridden_mod_nms = NULL;
|
||||
new_overridden_mod_cnt = 0;
|
||||
initialized = false;
|
||||
apilib_ptrs = NULL;
|
||||
apilib_cnt = 0;
|
||||
overridden_module_names = NULL;
|
||||
overridden_module_count = 0;
|
||||
|
||||
initialized = initialize();
|
||||
}
|
||||
|
||||
ApiLibraryManager::~ApiLibraryManager()
|
||||
{
|
||||
rollback_changes();
|
||||
}
|
||||
|
||||
bool ApiLibraryManager::initialize()
|
||||
{
|
||||
ApiLibrary* std_apilib;
|
||||
ApiLibrary* std_apilib = NULL;
|
||||
|
||||
new_apilib_cnt = 0;
|
||||
new_apilib_ptrs = (ApiLibrary**) malloc(ALLOC_CAPACITY * sizeof(ApiLibrary*));
|
||||
apilib_cnt = 0;
|
||||
apilib_ptrs = (ApiLibrary**) malloc(ALLOC_CAPACITY * sizeof(ApiLibrary*));
|
||||
|
||||
if (!new_apilib_ptrs)
|
||||
if (!apilib_ptrs)
|
||||
goto __error;
|
||||
|
||||
std_apilib = (ApiLibrary*) malloc(sizeof(ApiLibrary) + strlen("STD"));
|
||||
@ -74,54 +78,30 @@ bool ApiLibraryManager::initialize()
|
||||
std_apilib->api_tables = NULL;
|
||||
std_apilib->index = 0;
|
||||
|
||||
//copy previous STD api library tables and overridden module names
|
||||
if (overridden_module_count)
|
||||
{
|
||||
int size = (overridden_module_count / ALLOC_CAPACITY + 1) * ALLOC_CAPACITY;
|
||||
|
||||
std_apilib->api_tables = (apilib_api_table*)
|
||||
malloc((size + 1) * sizeof(apilib_api_table));
|
||||
apilib_ptrs[apilib_cnt++] = std_apilib;
|
||||
|
||||
if (!std_apilib->api_tables)
|
||||
goto __error;
|
||||
|
||||
apilib_api_table* prev_std_tab = apilib_ptrs[0]->api_tables;
|
||||
copy(prev_std_tab, prev_std_tab + size + 1, std_apilib->api_tables);
|
||||
|
||||
new_overridden_mod_nms = (const char**) malloc(size * sizeof(char*));
|
||||
|
||||
if (!new_overridden_mod_nms)
|
||||
goto __error;
|
||||
|
||||
copy(overridden_module_names, overridden_module_names + size,
|
||||
new_overridden_mod_nms);
|
||||
|
||||
new_overridden_mod_cnt = overridden_module_count;
|
||||
}
|
||||
|
||||
new_apilib_ptrs[new_apilib_cnt++] = std_apilib;
|
||||
|
||||
initialized = true;
|
||||
return true;
|
||||
|
||||
__error:
|
||||
free(new_overridden_mod_nms);
|
||||
if (std_apilib)
|
||||
free(std_apilib->api_tables);
|
||||
free(std_apilib);
|
||||
free(new_apilib_ptrs);
|
||||
free(apilib_ptrs);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ApiLibraryManager::load_apilib(const char* apilib_name)
|
||||
{
|
||||
if (!initialized && !initialize())
|
||||
IMTE** pmteModTable;
|
||||
MODREF* mr;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
DBGPRINTF(("Failed to initialize api library manager\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (new_apilib_cnt >= 0xff)
|
||||
if (apilib_cnt >= 0xff)
|
||||
{
|
||||
DBGPRINTF(("Too many api libraries loaded\n"));
|
||||
return false;
|
||||
@ -132,89 +112,72 @@ bool ApiLibraryManager::load_apilib(const char* apilib_name)
|
||||
return true;
|
||||
|
||||
//check if library wasn't loaded in this instance
|
||||
for (int i = 0 ; i < new_apilib_cnt ; i++)
|
||||
if (!strcmp(new_apilib_ptrs[i]->apilib_name, apilib_name))
|
||||
for (int i = 0 ; i < apilib_cnt ; i++)
|
||||
if (!strcmp(apilib_ptrs[i]->apilib_name, apilib_name))
|
||||
return true;
|
||||
|
||||
ApiLibrary* apilib;
|
||||
bool already_loaded = false;
|
||||
ApiLibrary* apilib = NULL;
|
||||
|
||||
DBGPRINTF(("Loading api library: %s... ", apilib_name));
|
||||
|
||||
//check if library wasn't previously loaded
|
||||
for (int i = 0 ; i < apilib_cnt ; i++)
|
||||
char dllpath[MAX_PATH];
|
||||
int size = sizeof(ApiLibrary) + strlen(apilib_name);
|
||||
|
||||
apilib = (ApiLibrary*) malloc(size);
|
||||
|
||||
if (!apilib)
|
||||
goto __error;
|
||||
|
||||
strcpy(apilib->apilib_name, apilib_name);
|
||||
|
||||
apilib->get_dll_path(dllpath);
|
||||
apilib->mod_handle = LoadLibrary(dllpath);
|
||||
|
||||
if (!apilib->mod_handle)
|
||||
{
|
||||
if (!strcmp(apilib_ptrs[i]->apilib_name, apilib_name))
|
||||
{
|
||||
DBGPRINTF(("already loaded... "));
|
||||
apilib = apilib_ptrs[i];
|
||||
already_loaded = true;
|
||||
}
|
||||
DBGPRINTF(("Failed to load api library\n"));
|
||||
goto __error;
|
||||
}
|
||||
|
||||
//if it wasn't loaded
|
||||
if (!already_loaded)
|
||||
fgat_t get_api_table;
|
||||
get_api_table = (fgat_t) GetProcAddress(
|
||||
apilib->mod_handle, "get_api_table");
|
||||
|
||||
if (!get_api_table)
|
||||
{
|
||||
char dllpath[MAX_PATH];
|
||||
int size = sizeof(ApiLibrary) + strlen(apilib_name);
|
||||
|
||||
apilib = (ApiLibrary*) malloc(size);
|
||||
|
||||
if (!apilib)
|
||||
goto __error;
|
||||
|
||||
strcpy(apilib->apilib_name, apilib_name);
|
||||
|
||||
strcpy(dllpath, kernelex_dir.get());
|
||||
strcat(dllpath, apilib_name);
|
||||
apilib->mod_handle = LoadLibrary(dllpath);
|
||||
|
||||
if (!apilib->mod_handle)
|
||||
{
|
||||
DBGPRINTF(("Failed to load api library\n"));
|
||||
goto __error;
|
||||
}
|
||||
|
||||
fgat_t get_api_table;
|
||||
get_api_table = (fgat_t) GetProcAddress(
|
||||
apilib->mod_handle, "get_api_table");
|
||||
|
||||
if (!get_api_table)
|
||||
{
|
||||
DBGPRINTF(("Failed to get api library entry point\n"));
|
||||
goto __error;
|
||||
}
|
||||
|
||||
const apilib_api_table* file_api_tables;
|
||||
file_api_tables = get_api_table();
|
||||
|
||||
if (!file_api_tables)
|
||||
{
|
||||
DBGPRINTF(("Failed to get api tables\n"));
|
||||
goto __error;
|
||||
}
|
||||
|
||||
apilib->api_tables = make_shared_api_tables(file_api_tables);
|
||||
|
||||
if (!apilib->api_tables)
|
||||
{
|
||||
DBGPRINTF(("Failed to create shared api tables\n"));
|
||||
goto __error;
|
||||
}
|
||||
|
||||
DBGPRINTF(("loaded @ 0x%08x... ", (DWORD) apilib->mod_handle));
|
||||
DBGPRINTF(("Failed to get api library entry point\n"));
|
||||
goto __error;
|
||||
}
|
||||
|
||||
const apilib_api_table* file_api_tables;
|
||||
file_api_tables = get_api_table();
|
||||
|
||||
if (!file_api_tables)
|
||||
{
|
||||
DBGPRINTF(("Failed to get api tables\n"));
|
||||
goto __error;
|
||||
}
|
||||
|
||||
apilib->api_tables = make_shared_api_tables(file_api_tables);
|
||||
|
||||
if (!apilib->api_tables)
|
||||
{
|
||||
DBGPRINTF(("Failed to create shared api tables\n"));
|
||||
goto __error;
|
||||
}
|
||||
|
||||
DBGPRINTF(("loaded @ 0x%08x... ", (DWORD) apilib->mod_handle));
|
||||
|
||||
//allocate space for new ApiLibraries
|
||||
if (new_apilib_cnt % ALLOC_CAPACITY == 0)
|
||||
if (apilib_cnt % ALLOC_CAPACITY == 0)
|
||||
{
|
||||
void* new_block = realloc(new_apilib_ptrs,
|
||||
(new_apilib_cnt + ALLOC_CAPACITY) * sizeof(ApiLibrary*));
|
||||
void* new_block = realloc(apilib_ptrs,
|
||||
(apilib_cnt + ALLOC_CAPACITY) * sizeof(ApiLibrary*));
|
||||
|
||||
if (!new_block)
|
||||
goto __error;
|
||||
|
||||
new_apilib_ptrs = (ApiLibrary**) new_block;
|
||||
apilib_ptrs = (ApiLibrary**) new_block;
|
||||
}
|
||||
|
||||
// DBGPRINTF(("Listing modules overridden by api library:\n"));
|
||||
@ -228,18 +191,23 @@ bool ApiLibraryManager::load_apilib(const char* apilib_name)
|
||||
}
|
||||
}
|
||||
|
||||
//set or update index value which is used by encode_address()
|
||||
//and to update mod_index in commit_changes()
|
||||
apilib->index = new_apilib_cnt;
|
||||
//set index value which is used by encode_address()
|
||||
apilib->index = apilib_cnt;
|
||||
|
||||
//set mod_index for newly loaded api libraries
|
||||
pmteModTable = *ppmteModTable;
|
||||
mr = MRFromHLib(apilib->mod_handle);
|
||||
DBGASSERT(mr);
|
||||
((IMTE_KEX*) pmteModTable[mr->mteIndex])->mod_index = 0xff00 + apilib->index;
|
||||
|
||||
//add to table of new ApiLibraries
|
||||
new_apilib_ptrs[new_apilib_cnt++] = apilib;
|
||||
apilib_ptrs[apilib_cnt++] = apilib;
|
||||
|
||||
DBGPRINTF(("ok\n"));
|
||||
return true;
|
||||
|
||||
__error:
|
||||
if (!already_loaded && apilib)
|
||||
if (apilib)
|
||||
{
|
||||
if (apilib->mod_handle)
|
||||
FreeLibrary(apilib->mod_handle);
|
||||
@ -250,16 +218,16 @@ __error:
|
||||
return false;
|
||||
}
|
||||
|
||||
ApiLibrary* ApiLibraryManager::get_new_apilib(const char* apilib_name)
|
||||
ApiLibrary* ApiLibraryManager::get_apilib(const char* apilib_name)
|
||||
{
|
||||
for (int i = 0 ; i < new_apilib_cnt ; i++)
|
||||
if (!strcmp(new_apilib_ptrs[i]->apilib_name, apilib_name))
|
||||
return new_apilib_ptrs[i];
|
||||
for (int i = 0 ; i < apilib_cnt ; i++)
|
||||
if (!strcmp(apilib_ptrs[i]->apilib_name, apilib_name))
|
||||
return apilib_ptrs[i];
|
||||
DBGPRINTF(("Api library %s not found\n", apilib_name));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ApiLibrary* ApiLibraryManager::get_apilib(int index)
|
||||
ApiLibrary* ApiLibraryManager::get_apilib_by_index(int index)
|
||||
{
|
||||
if (index < 0 || index >= apilib_cnt)
|
||||
return NULL;
|
||||
@ -284,7 +252,7 @@ bool ApiLibraryManager::are_api_tables_sorted(const apilib_api_table* tab)
|
||||
|
||||
apilib_api_table* ApiLibraryManager::make_shared_api_tables(const apilib_api_table* in)
|
||||
{
|
||||
bool copy_strings = (size_t) in < 0x80000000 ? true : false;
|
||||
bool copy_strings = IS_SHARED(in) ? false : true;
|
||||
bool sorted = are_api_tables_sorted(in);
|
||||
|
||||
if (!sorted)
|
||||
@ -398,28 +366,28 @@ int ApiLibraryManager::required_api_table_space(const apilib_api_table* tab, boo
|
||||
|
||||
bool ApiLibraryManager::add_overridden_module(const char* mod)
|
||||
{
|
||||
apilib_api_table*& std_api_table = new_apilib_ptrs[0]->api_tables;
|
||||
apilib_api_table*& std_api_table = apilib_ptrs[0]->api_tables;
|
||||
|
||||
//ensure that module isn't already on list
|
||||
for (int i = 0 ; i < new_overridden_mod_cnt ; i++)
|
||||
for (int i = 0 ; i < overridden_module_count ; i++)
|
||||
{
|
||||
if (!strcmpi(new_overridden_mod_nms[i], mod))
|
||||
if (!strcmpi(overridden_module_names[i], mod))
|
||||
return true;
|
||||
}
|
||||
|
||||
//allocate space for new overridden modules
|
||||
if (new_overridden_mod_cnt % ALLOC_CAPACITY == 0)
|
||||
if (overridden_module_count % ALLOC_CAPACITY == 0)
|
||||
{
|
||||
void* new_block = realloc(new_overridden_mod_nms,
|
||||
(new_overridden_mod_cnt + ALLOC_CAPACITY) * sizeof(char*));
|
||||
void* new_block = realloc(overridden_module_names,
|
||||
(overridden_module_count + ALLOC_CAPACITY) * sizeof(char*));
|
||||
|
||||
if (!new_block)
|
||||
return false;
|
||||
|
||||
new_overridden_mod_nms = (const char**) new_block;
|
||||
overridden_module_names = (const char**) new_block;
|
||||
|
||||
new_block = realloc(std_api_table,
|
||||
(new_overridden_mod_cnt + 1 + ALLOC_CAPACITY) * sizeof(apilib_api_table));
|
||||
(overridden_module_count + 1 + ALLOC_CAPACITY) * sizeof(apilib_api_table));
|
||||
//+ 1 because api_tables are NULL terminated
|
||||
|
||||
if (!new_block)
|
||||
@ -428,18 +396,18 @@ bool ApiLibraryManager::add_overridden_module(const char* mod)
|
||||
std_api_table = (apilib_api_table*) new_block;
|
||||
}
|
||||
|
||||
if (!parse_system_dll(mod, &std_api_table[new_overridden_mod_cnt]))
|
||||
if (!parse_system_dll(mod, &std_api_table[overridden_module_count]))
|
||||
{
|
||||
DBGPRINTF(("Failed to parse system DLL: %s\n", mod));
|
||||
return false;
|
||||
}
|
||||
|
||||
//add to table of overridden modules
|
||||
new_overridden_mod_nms[new_overridden_mod_cnt]
|
||||
= std_api_table[new_overridden_mod_cnt].target_library;
|
||||
new_overridden_mod_cnt++;
|
||||
overridden_module_names[overridden_module_count]
|
||||
= std_api_table[overridden_module_count].target_library;
|
||||
overridden_module_count++;
|
||||
|
||||
memset(&std_api_table[new_overridden_mod_cnt], 0, sizeof(apilib_api_table));
|
||||
memset(&std_api_table[overridden_module_count], 0, sizeof(apilib_api_table));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -481,9 +449,21 @@ bool ApiLibraryManager::parse_system_dll(const char* dll_name, apilib_api_table*
|
||||
DWORD* Names = (DWORD*) pemod.RvaToPointer(Exports->AddressOfNames);
|
||||
WORD* OrdinalTable = (WORD*) pemod.RvaToPointer(Exports->AddressOfNameOrdinals);
|
||||
DWORD* FunctionTable = (DWORD*) pemod.RvaToPointer(Exports->AddressOfFunctions);
|
||||
|
||||
unsigned long offset = PEh->OptionalHeader.ImageBase >= 0x80000000
|
||||
? PEh->OptionalHeader.ImageBase : 0;
|
||||
|
||||
//offset for shared libraries
|
||||
unsigned long offset = 0;
|
||||
|
||||
if (!mem_dll)
|
||||
{
|
||||
//check if we deal with shared library but it is not loaded yet
|
||||
if (IS_SHARED(PEh->OptionalHeader.ImageBase))
|
||||
offset = (unsigned long) LoadLibrary(dll_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IS_SHARED(mem_dll))
|
||||
offset = (unsigned long) mem_dll;
|
||||
}
|
||||
|
||||
//calculate required space
|
||||
int space = 0;
|
||||
@ -558,132 +538,3 @@ bool ApiLibraryManager::parse_system_dll(const char* dll_name, apilib_api_table*
|
||||
return true;
|
||||
}
|
||||
|
||||
void ApiLibraryManager::rollback_changes()
|
||||
{
|
||||
if (!initialized)
|
||||
return;
|
||||
|
||||
//STD api library case
|
||||
//unload new system module override tables <overridden_mod_cnt;new_overridden_mod_cnt)
|
||||
for (apilib_api_table* p = &new_apilib_ptrs[0]->api_tables
|
||||
[overridden_module_count] ; p->target_library ; p++)
|
||||
free((void*) p->named_apis); //consistent with parse_system_dll
|
||||
free(new_apilib_ptrs[0]->api_tables);
|
||||
free(new_apilib_ptrs[0]);
|
||||
|
||||
//other api libraries
|
||||
for (int i = 1 ; i < new_apilib_cnt ; i++)
|
||||
{
|
||||
if (apilib_ptrs)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 1 ; j < apilib_cnt ; j++)
|
||||
if (new_apilib_ptrs[i] == apilib_ptrs[j])
|
||||
break;
|
||||
|
||||
if (j != apilib_cnt)
|
||||
continue;
|
||||
}
|
||||
FreeLibrary(new_apilib_ptrs[i]->mod_handle);
|
||||
free(new_apilib_ptrs[i]->api_tables);
|
||||
free(new_apilib_ptrs[i]);
|
||||
}
|
||||
|
||||
free(new_apilib_ptrs);
|
||||
new_apilib_ptrs = NULL;
|
||||
new_apilib_cnt = 0;
|
||||
|
||||
for (int i = overridden_module_count ; i < new_overridden_mod_cnt ; i++)
|
||||
free((void*) new_overridden_mod_nms[i]);
|
||||
|
||||
free(new_overridden_mod_nms);
|
||||
new_overridden_mod_nms = NULL;
|
||||
new_overridden_mod_cnt = 0;
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
void ApiLibraryManager::commit_changes()
|
||||
{
|
||||
if (!initialized)
|
||||
return;
|
||||
|
||||
ApiLibrary** old_apilib_ptrs = apilib_ptrs;
|
||||
int old_apilib_cnt = apilib_cnt;
|
||||
|
||||
//LOCK ALL CRITICAL SECTIONS!
|
||||
apilib_ptrs = new_apilib_ptrs;
|
||||
apilib_cnt = new_apilib_cnt;
|
||||
if (overridden_module_names)
|
||||
free(overridden_module_names);
|
||||
overridden_module_names = new_overridden_mod_nms;
|
||||
overridden_module_count = new_overridden_mod_cnt;
|
||||
|
||||
//update old api library mod_index values to new
|
||||
//set all non-overridden modules to 'not checked'
|
||||
WORD imteMax = *pimteMax;
|
||||
IMTE** pmteModTable = *ppmteModTable;
|
||||
for (WORD i = 0 ; i < imteMax ; i++)
|
||||
{
|
||||
IMTE_KEX* imte = (IMTE_KEX*) pmteModTable[i];
|
||||
if (imte)
|
||||
{
|
||||
WORD index = imte->mod_index;
|
||||
if (index >= 0xff00 && index < 0xffff)
|
||||
{
|
||||
int api_lib_num = index & 0xff;
|
||||
DBGASSERT(api_lib_num != 0); //reserved for STD apilib
|
||||
DBGASSERT(api_lib_num >= old_apilib_cnt);
|
||||
imte->mod_index = old_apilib_ptrs[api_lib_num]->index + 0xff00;
|
||||
}
|
||||
else if (index == 0xffff)
|
||||
imte->mod_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//set mod_index for newly loaded api libraries
|
||||
for (int i = 1 ; i < apilib_cnt ; i++)
|
||||
{
|
||||
ApiLibrary* apilib = apilib_ptrs[i];
|
||||
MODREF* mr = MRFromHLib(apilib->mod_handle);
|
||||
DBGASSERT(mr);
|
||||
((IMTE_KEX*) pmteModTable[mr->mteIndex])->mod_index = 0xff00 + i;
|
||||
}
|
||||
//UNLOCK ALL CRITICAL SECTIONS!
|
||||
|
||||
new_overridden_mod_nms = NULL;
|
||||
new_overridden_mod_cnt = 0;
|
||||
new_apilib_ptrs = NULL;
|
||||
new_apilib_cnt = 0;
|
||||
|
||||
//STD api library case
|
||||
if (old_apilib_cnt > 0)
|
||||
{
|
||||
free(old_apilib_ptrs[0]->api_tables);
|
||||
free(old_apilib_ptrs[0]);
|
||||
}
|
||||
|
||||
//other api libraries
|
||||
for (int i = 1 ; i < old_apilib_cnt ; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 1 ; j < apilib_cnt ; j++)
|
||||
if (old_apilib_ptrs[i] == apilib_ptrs[j])
|
||||
break;
|
||||
|
||||
if (j != apilib_cnt)
|
||||
continue;
|
||||
|
||||
FreeLibrary(old_apilib_ptrs[i]->mod_handle);
|
||||
free(old_apilib_ptrs[i]->api_tables);
|
||||
free(old_apilib_ptrs[i]);
|
||||
}
|
||||
|
||||
if (old_apilib_ptrs)
|
||||
free(old_apilib_ptrs);
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
|
22
core/apilib.h
Executable file → Normal file
22
core/apilib.h
Executable file → Normal file
@ -30,6 +30,9 @@ struct ApiLibrary
|
||||
HMODULE mod_handle;
|
||||
int index;
|
||||
char apilib_name[1]; // variable size array
|
||||
|
||||
bool is_shared() const { return (DWORD) mod_handle >= 0x80000000; }
|
||||
void get_dll_path(char* out);
|
||||
};
|
||||
|
||||
class ApiLibraryManager
|
||||
@ -38,20 +41,15 @@ public:
|
||||
ApiLibraryManager();
|
||||
~ApiLibraryManager();
|
||||
bool load_apilib(const char* apilib_name);
|
||||
ApiLibrary* get_new_apilib(const char* apilib_name);
|
||||
static ApiLibrary* get_apilib(int index);
|
||||
void commit_changes();
|
||||
void rollback_changes();
|
||||
ApiLibrary* get_apilib(const char* apilib_name);
|
||||
ApiLibrary* get_apilib_by_index(int index);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
bool initialized;
|
||||
ApiLibrary** new_apilib_ptrs;
|
||||
int new_apilib_cnt;
|
||||
|
||||
static ApiLibrary** apilib_ptrs;
|
||||
static int apilib_cnt;
|
||||
ApiLibrary** apilib_ptrs;
|
||||
int apilib_cnt;
|
||||
|
||||
bool initialize();
|
||||
bool are_api_tables_sorted(const apilib_api_table* tab);
|
||||
@ -61,9 +59,9 @@ private:
|
||||
bool parse_system_dll(const char* dll_name, apilib_api_table* api_tab);
|
||||
};
|
||||
|
||||
extern int overridden_module_count;
|
||||
extern ApiLibraryManager apilibmgr;
|
||||
|
||||
extern const char** overridden_module_names;
|
||||
extern const char** new_overridden_mod_nms;
|
||||
extern int new_overridden_mod_cnt;
|
||||
extern int overridden_module_count;
|
||||
|
||||
#endif
|
||||
|
127
core/apilog.cpp
Normal file
127
core/apilog.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx 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; version 2 of the License.
|
||||
*
|
||||
* KernelEx 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 GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "apilog.h"
|
||||
#include "debug.h"
|
||||
#include "internals.h"
|
||||
#include "DebugWindow.h"
|
||||
|
||||
void* get_process_env_data(const char* env, void* (*c)())
|
||||
{
|
||||
//environment variable: ENV=ProcessID:DATA
|
||||
char buf[20];
|
||||
DWORD ret;
|
||||
DWORD ProcID;
|
||||
void* data = NULL;
|
||||
|
||||
ret = GetEnvironmentVariable(env, buf, sizeof(buf));
|
||||
if (ret == 0 || ret > sizeof(buf)
|
||||
|| sscanf(buf, "%x:%x", &ProcID, &data) != 2
|
||||
|| ProcID != GetCurrentProcessId())
|
||||
{
|
||||
//invalid/missing value - create new data
|
||||
data = c();
|
||||
if (data)
|
||||
{
|
||||
sprintf(buf, "%x:%x", GetCurrentProcessId(), data);
|
||||
SetEnvironmentVariable(env, buf);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void* heap_creator()
|
||||
{
|
||||
return HeapCreate(0, 0, 0);
|
||||
}
|
||||
|
||||
HANDLE get_process_debug_heap()
|
||||
{
|
||||
return get_process_env_data("KEXDBGH", heap_creator);
|
||||
}
|
||||
|
||||
void* tls_creator()
|
||||
{
|
||||
return (void*) TlsAlloc();
|
||||
}
|
||||
|
||||
DWORD get_process_debug_tls()
|
||||
{
|
||||
return (DWORD) get_process_env_data("KEXDBGT", tls_creator);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int snprintf(char *buffer, size_t n, const char* format, ...);
|
||||
|
||||
DWORD __stdcall log_api(const char* source, const char* target, const char* api_name, DWORD ret)
|
||||
{
|
||||
DebugWindow* dw = DebugWindow::get();
|
||||
if (!dw)
|
||||
return 0;
|
||||
|
||||
char msg[DEBUGMSG_MAXLEN];
|
||||
|
||||
const char* proc = ((*ppmteModTable)[(*pppdbCur)->pExeMODREF->mteIndex])->pszModName;
|
||||
snprintf(msg, sizeof(msg), "%s|%x|%s|%s|%s|%x", proc,
|
||||
GetCurrentThreadId(), source, target, api_name, ret);
|
||||
|
||||
dw->append(msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ThreadAddrStack::ThreadAddrStack()
|
||||
{
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
void __stdcall ThreadAddrStack::push_ret_addr(DWORD tls, DWORD addr)
|
||||
{
|
||||
ThreadAddrStack* tas = (ThreadAddrStack*) TlsGetValue(tls);
|
||||
if (!tas)
|
||||
{
|
||||
void* mem = HeapAlloc(get_process_debug_heap(), 0, sizeof(ThreadAddrStack));
|
||||
tas = new (mem) ThreadAddrStack;
|
||||
TlsSetValue(tls, mem);
|
||||
}
|
||||
tas->stack[tas->pos++] = addr;
|
||||
}
|
||||
|
||||
DWORD __stdcall ThreadAddrStack::pop_ret_addr(DWORD tls)
|
||||
{
|
||||
ThreadAddrStack* tas = (ThreadAddrStack*) TlsGetValue(tls);
|
||||
if (!tas || !tas->pos)
|
||||
return 0;
|
||||
return tas->stack[--tas->pos];
|
||||
}
|
||||
|
||||
PROC create_log_stub(const char* caller, const char* target, const char* api, PROC orig)
|
||||
{
|
||||
HANDLE heap = get_process_debug_heap();
|
||||
void* mem = HeapAlloc(heap, 0, sizeof(log_stub));
|
||||
return (PROC) new (mem) log_stub(caller,
|
||||
target, api, (unsigned long) orig,
|
||||
(unsigned long) log_api, get_process_debug_tls());
|
||||
}
|
84
core/apilog.h
Normal file
84
core/apilog.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx 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; version 2 of the License.
|
||||
*
|
||||
* KernelEx 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 GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __APILOG_H
|
||||
#define __APILOG_H
|
||||
|
||||
#include "resolver.h"
|
||||
|
||||
|
||||
class ThreadAddrStack
|
||||
{
|
||||
public:
|
||||
ThreadAddrStack();
|
||||
static void __stdcall push_ret_addr(DWORD tls, DWORD addr);
|
||||
static DWORD __stdcall pop_ret_addr(DWORD tls);
|
||||
|
||||
private:
|
||||
int pos;
|
||||
DWORD stack[31];
|
||||
};
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
/* Creates a stub for api logging. */
|
||||
class log_stub
|
||||
{
|
||||
public:
|
||||
log_stub(const char* source, const char* target, const char* name,
|
||||
unsigned long proc, unsigned long log_fun, DWORD tls)
|
||||
: call_orig(proc, true), jmp_logfun(log_fun),
|
||||
tas_store((unsigned long) ThreadAddrStack::push_ret_addr, true),
|
||||
tas_restore((unsigned long) ThreadAddrStack::pop_ret_addr, true)
|
||||
{
|
||||
c_push1 = c_push2 = c_push3 = c_push4 = c_push5 = 0x68;
|
||||
tls1 = tls2 = tls;
|
||||
v_source = source;
|
||||
v_target = target;
|
||||
v_name = name;
|
||||
c_pusheax1 = c_pusheax2 = 0x50;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned char c_push1;
|
||||
DWORD tls1;
|
||||
redir_stub tas_store; //arg1=tls, arg2=caller ret
|
||||
redir_stub call_orig;
|
||||
unsigned char c_pusheax1; //orig ret
|
||||
unsigned char c_push2;
|
||||
const char* v_name;
|
||||
unsigned char c_push3;
|
||||
const char* v_target;
|
||||
unsigned char c_push4;
|
||||
const char* v_source;
|
||||
unsigned char c_push5;
|
||||
DWORD tls2;
|
||||
redir_stub tas_restore; //restore caller ret
|
||||
unsigned char c_pusheax2;
|
||||
redir_stub jmp_logfun; //jmp to log_fun
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
PROC create_log_stub(const char* caller, const char* target, const char* api, PROC orig);
|
||||
|
||||
|
||||
#endif
|
0
core/core.def
Executable file → Normal file
0
core/core.def
Executable file → Normal file
100
core/core.dsp
Executable file → Normal file
100
core/core.dsp
Executable file → Normal file
@ -47,13 +47,13 @@ RSC=rc.exe
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x415 /d "NDEBUG"
|
||||
# ADD RSC /l 0x415 /d "NDEBUG"
|
||||
# ADD RSC /l 0x415 /i "../common" /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# 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 /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib ..\kexcrt\kexcrt.lib libc.lib /nologo /entry:"PreDllMain@12" /dll /map /machine:I386 /nodefaultlib /out:"Release/KernelEx.dll" /implib:"../common/KernelEx.lib" /ignore:4092 /OPT:NOWIN98
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib comctl32.lib ..\kexcrt\kexcrt.lib libc.lib /nologo /entry:"PreDllMain@12" /dll /map /machine:I386 /nodefaultlib /out:"Release/KernelEx.dll" /implib:"../common/KernelEx.lib" /ignore:4092 /OPT:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "Core - Win32 Debug"
|
||||
@ -74,13 +74,13 @@ LINK32=link.exe
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x415 /d "_DEBUG"
|
||||
# ADD RSC /l 0x415 /d "_DEBUG"
|
||||
# ADD RSC /l 0x415 /i "../common" /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# 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 /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib ..\kexcrt\kexcrt.lib libc.lib /nologo /entry:"PreDllMain@12" /dll /incremental:no /map /debug /machine:I386 /nodefaultlib /out:"Debug/KernelEx.dll" /implib:"../common/KernelEx.lib" /ignore:4092 /OPT:NOWIN98
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib comctl32.lib ..\kexcrt\kexcrt.lib libc.lib /nologo /entry:"PreDllMain@12" /dll /incremental:no /map /debug /machine:I386 /nodefaultlib /out:"Debug/KernelEx.dll" /implib:"../common/KernelEx.lib" /ignore:4092 /OPT:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
@ -106,40 +106,51 @@ SOURCE=.\apilib.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\apilog.cpp
|
||||
|
||||
!IF "$(CFG)" == "Core - Win32 Release"
|
||||
|
||||
# PROP Exclude_From_Build 1
|
||||
|
||||
!ELSEIF "$(CFG)" == "Core - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\core.def
|
||||
|
||||
!IF "$(CFG)" == "Core - Win32 Release"
|
||||
|
||||
# Begin Custom Build
|
||||
OutDir=.\Release
|
||||
ProjDir=.
|
||||
WkspDir=.
|
||||
InputPath=.\core.def
|
||||
|
||||
BuildCmds= \
|
||||
link /LIB /NOLOGO /MACHINE:IX86 /DEF:$(ProjDir)\k32ord.def /OUT:$(OutDir)\k32ord.lib
|
||||
|
||||
"$(OutDir)\k32ord.lib" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(OutDir)\k32ord.exp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
cl /nologo /c /TC /DK32ORD_IMPLIB /Fo$(OutDir)\k32ord.obj "$(WkspDir)\common\k32ord.h"
|
||||
link /DLL /NOENTRY /NOLOGO /IGNORE:4070 /MACHINE:IX86 /DEF:"$(WkspDir)\common\k32ord.def" /OUT:$(OutDir)\k32ord.dll /IMPLIB:$(OutDir)\k32ord.lib $(OutDir)\k32ord.obj
|
||||
del $(OutDir)\k32ord.exp
|
||||
del $(OutDir)\k32ord.obj
|
||||
del $(OutDir)\k32ord.dll
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "Core - Win32 Debug"
|
||||
|
||||
# Begin Custom Build
|
||||
OutDir=.\Debug
|
||||
ProjDir=.
|
||||
WkspDir=.
|
||||
InputPath=.\core.def
|
||||
|
||||
BuildCmds= \
|
||||
link /LIB /NOLOGO /MACHINE:IX86 /DEF:$(ProjDir)\k32ord.def /OUT:$(OutDir)\k32ord.lib
|
||||
|
||||
"$(OutDir)\k32ord.lib" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(OutDir)\k32ord.exp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
cl /nologo /c /TC /DK32ORD_IMPLIB /Fo$(OutDir)\k32ord.obj "$(WkspDir)\common\k32ord.h"
|
||||
link /DLL /NOENTRY /NOLOGO /IGNORE:4070 /MACHINE:IX86 /DEF:"$(WkspDir)\common\k32ord.def" /OUT:$(OutDir)\k32ord.dll /IMPLIB:$(OutDir)\k32ord.lib $(OutDir)\k32ord.obj
|
||||
del $(OutDir)\k32ord.exp
|
||||
del $(OutDir)\k32ord.obj
|
||||
del $(OutDir)\k32ord.dll
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
@ -173,12 +184,20 @@ SOURCE=.\debugproto.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\internals.cpp
|
||||
SOURCE=.\DebugWindow.cpp
|
||||
|
||||
!IF "$(CFG)" == "Core - Win32 Release"
|
||||
|
||||
# PROP Exclude_From_Build 1
|
||||
|
||||
!ELSEIF "$(CFG)" == "Core - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\k32ord.def
|
||||
# PROP Exclude_From_Build 1
|
||||
SOURCE=.\internals.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@ -206,6 +225,10 @@ SOURCE=.\sharedmem.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\storage.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\thunks.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -230,6 +253,10 @@ SOURCE=.\apilib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\apilog.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\debug.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -238,10 +265,27 @@ SOURCE=.\debugproto.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DebugWindow.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\internals.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\common\is_sorted.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\common\k32ord.def
|
||||
# PROP Exclude_From_Build 1
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\common\k32ord.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\common\kexcoresdk.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -262,6 +306,14 @@ SOURCE=.\sharedmem.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\common\sstring.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\storage.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\structs.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -270,7 +322,7 @@ SOURCE=.\thunks.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\version.h
|
||||
SOURCE=..\common\version.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
|
0
core/core.ini
Executable file → Normal file
0
core/core.ini
Executable file → Normal file
19
core/debug.cpp
Executable file → Normal file
19
core/debug.cpp
Executable file → Normal file
@ -19,32 +19,20 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define BUFLEN 256
|
||||
#include "debug.h"
|
||||
|
||||
extern "C"
|
||||
int vsnprintf(char *buffer, size_t n, const char *format, va_list ap);
|
||||
|
||||
void dbgvprintf(const char* format, void* _argp)
|
||||
{
|
||||
char msg[BUFLEN];
|
||||
char msg[DEBUGMSG_MAXLEN];
|
||||
va_list argp = (va_list) _argp;
|
||||
HANDLE console_out = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
int cnt = vsnprintf(msg, sizeof(msg), format, argp);
|
||||
|
||||
if (console_out == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
OutputDebugString(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dummy;
|
||||
WriteFile(console_out, msg, cnt < 0 ? BUFLEN - 1 : cnt, &dummy, NULL);
|
||||
}
|
||||
OutputDebugString(msg);
|
||||
}
|
||||
|
||||
void dbgprintf(const char* format, ...)
|
||||
@ -54,3 +42,4 @@ void dbgprintf(const char* format, ...)
|
||||
dbgvprintf(format, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
|
||||
|
11
core/debug.h
Executable file → Normal file
11
core/debug.h
Executable file → Normal file
@ -22,6 +22,8 @@
|
||||
#ifndef __DEBUG_H
|
||||
#define __DEBUG_H
|
||||
|
||||
#define DEBUGMSG_MAXLEN 256
|
||||
|
||||
#ifndef _DEBUG
|
||||
|
||||
#define DBGPRINTF(x) do { } while (0)
|
||||
@ -42,16 +44,9 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void dbgvprintf(const char* format, void* _argp);
|
||||
void dbgprintf(const char* format, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; /* extern "C" */
|
||||
#endif
|
||||
PROC create_log_stub(const char* caller, const char* target, const char* api, PROC orig);
|
||||
|
||||
|
||||
#endif
|
||||
|
2
core/debugproto.cpp
Executable file → Normal file
2
core/debugproto.cpp
Executable file → Normal file
@ -27,7 +27,7 @@
|
||||
|
||||
void kexDbgDumpConfigurations(void)
|
||||
{
|
||||
ApiConfigurationManager::dump_configurations();
|
||||
apiconfmgr.dump_configurations();
|
||||
}
|
||||
|
||||
void kexDbgDumpImtes(void)
|
||||
|
0
core/debugproto.h
Executable file → Normal file
0
core/debugproto.h
Executable file → Normal file
76
core/internals.cpp
Executable file → Normal file
76
core/internals.cpp
Executable file → Normal file
@ -22,7 +22,6 @@
|
||||
#include <windows.h>
|
||||
#include <cstdio>
|
||||
#include "internals.h"
|
||||
#include <tlhelp32.h>
|
||||
#include "resolver.h"
|
||||
#include "debug.h"
|
||||
#include "pemanip.h"
|
||||
@ -47,67 +46,6 @@ FreeLibRemove_t FreeLibRemove = NULL;
|
||||
sstring kernelex_dir("");
|
||||
sstring own_path("");
|
||||
|
||||
HANDLE fullcritlock_hndl = NULL;
|
||||
|
||||
//FIXME: CreateToolhelp32Snapshot + Process32First/Next should be replaced by
|
||||
// plstPdb + PnodGetLstElem() + SetLstCurElem() (see DumpProcesses())
|
||||
void FullCritLock()
|
||||
{
|
||||
PROCESSENTRY32 pe;
|
||||
BOOL result;
|
||||
|
||||
DBGPRINTF(("FullCritLock\n"));
|
||||
if (fullcritlock_hndl)
|
||||
{
|
||||
DBGPRINTF(("Error: lock already acquired\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
_EnterSysLevel(krnl32lock);
|
||||
fullcritlock_hndl = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
DBGASSERT(fullcritlock_hndl != INVALID_HANDLE_VALUE);
|
||||
|
||||
pe.dwSize = sizeof(pe);
|
||||
result = Process32First(fullcritlock_hndl, &pe);
|
||||
DBGASSERT(result != FALSE);
|
||||
do
|
||||
{
|
||||
PDB98* pdb;
|
||||
pdb = PIDtoPDB(pe.th32ProcessID);
|
||||
_EnterSysLevel(&pdb->CriticalSection);
|
||||
}
|
||||
while (Process32Next(fullcritlock_hndl, &pe));
|
||||
}
|
||||
|
||||
void FullCritUnlock()
|
||||
{
|
||||
PROCESSENTRY32 pe;
|
||||
BOOL result;
|
||||
|
||||
if (!fullcritlock_hndl)
|
||||
{
|
||||
DBGPRINTF(("Error: not locked\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
pe.dwSize = sizeof(pe);
|
||||
result = Process32First(fullcritlock_hndl, &pe);
|
||||
DBGASSERT(result != FALSE);
|
||||
do
|
||||
{
|
||||
PDB98* pdb;
|
||||
pdb = PIDtoPDB(pe.th32ProcessID);
|
||||
_LeaveSysLevel(&pdb->CriticalSection);
|
||||
}
|
||||
while (Process32Next(fullcritlock_hndl, &pe));
|
||||
|
||||
CloseHandle(fullcritlock_hndl);
|
||||
fullcritlock_hndl = NULL;
|
||||
|
||||
_LeaveSysLevel(krnl32lock);
|
||||
DBGPRINTF(("FullCritUnlock\n"));
|
||||
}
|
||||
|
||||
bool isWinMe()
|
||||
{
|
||||
return is_winme;
|
||||
@ -233,7 +171,7 @@ static CRITICAL_SECTION* find_krnl32lock()
|
||||
short pat[] = {0x55,0xA1,-2,-2,-2,-2,0x8B,0xEC,0x56,0x57,0x33,0xF6,0x50,0xE8};
|
||||
int pat_len = sizeof(pat) / sizeof(short);
|
||||
|
||||
DWORD* res = find_unique_pattern(iGetProcAddress(h_kernel32, "VirtualQueryEx"), pat_len, pat, pat_len, pat_name);
|
||||
DWORD* res = find_unique_pattern((void*) iGetProcAddress(h_kernel32, "VirtualQueryEx"), pat_len, pat, pat_len, pat_name);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
@ -251,7 +189,7 @@ static PDB98** find_curPDB()
|
||||
short pat[] = {0xA1,-2,-2,-2,-2,0xFF,0x30,0xE8,-1,-1,-1,-1,0xC3};
|
||||
int pat_len = sizeof(pat) / sizeof(short);
|
||||
|
||||
DWORD* res = find_unique_pattern(iGetProcAddress(h_kernel32, "GetCurrentProcessId"), pat_len, pat, pat_len, pat_name);
|
||||
DWORD* res = find_unique_pattern((void*) iGetProcAddress(h_kernel32, "GetCurrentProcessId"), pat_len, pat, pat_len, pat_name);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
@ -269,7 +207,7 @@ static IMTE*** find_mod_table()
|
||||
short pat[] = {0x8B,0x0D,-2,-2,-2,-2};
|
||||
int pat_len = sizeof(pat) / sizeof(short);
|
||||
|
||||
DWORD* res = find_unique_pattern(iGetProcAddress(h_kernel32, (LPSTR)23), 0x20, pat, pat_len, pat_name);
|
||||
DWORD* res = find_unique_pattern((void*) iGetProcAddress(h_kernel32, (LPSTR)23), 0x20, pat, pat_len, pat_name);
|
||||
|
||||
ret = (IMTE***)*res;
|
||||
DBGPRINTF(("%s @ 0x%08x\n", pat_name, ret));
|
||||
@ -284,7 +222,7 @@ static MRFromHLib_t find_MRFromHLib()
|
||||
short pat[] = {0xE8,-2,-2,-2,-2};
|
||||
int pat_len = sizeof(pat) / sizeof(short);
|
||||
|
||||
DWORD* res = find_unique_pattern(iGetProcAddress(h_kernel32, (LPSTR)23), 0x20, pat, pat_len, pat_name);
|
||||
DWORD* res = find_unique_pattern((void*) iGetProcAddress(h_kernel32, (LPSTR)23), 0x20, pat, pat_len, pat_name);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
@ -343,7 +281,7 @@ static PIDtoPDB_t find_PIDtoPDB()
|
||||
short pat[] = {0xFF,0x74,0x24,0x0C,0xE8,-2,-2,-2,-2};
|
||||
int pat_len = sizeof(pat) / sizeof(short);
|
||||
|
||||
DWORD* res = find_unique_pattern(iGetProcAddress(h_kernel32, "OpenProcess"), pat_len, pat, pat_len, pat_name);
|
||||
DWORD* res = find_unique_pattern((void*) iGetProcAddress(h_kernel32, "OpenProcess"), pat_len, pat, pat_len, pat_name);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
@ -381,7 +319,7 @@ static FreeLibTree_t find_FreeLibTree()
|
||||
short pat[] = {0x75,0x09,0x6A,0x06,0xE8,-1,-1,-1,-1,0xEB,0x08,0x50,0xE8,-2,-2,-2,-2,0x8B,0xF0};
|
||||
int pat_len = sizeof(pat) / sizeof(short);
|
||||
|
||||
DWORD* res = find_unique_pattern(iGetProcAddress(h_kernel32, "FreeLibrary"), 0x80, pat, pat_len, pat_name);
|
||||
DWORD* res = find_unique_pattern((void*) iGetProcAddress(h_kernel32, "FreeLibrary"), 0x80, pat, pat_len, pat_name);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
@ -471,7 +409,7 @@ static bool find_kernelex_install_dir()
|
||||
|
||||
DBGPRINTF(("KernelEx directory: %s\n", path));
|
||||
strcat(path, "\\");
|
||||
kernelex_dir = path;
|
||||
kernelex_dir = strupr(path);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
27
core/internals.h
Executable file → Normal file
27
core/internals.h
Executable file → Normal file
@ -26,14 +26,17 @@
|
||||
#include "sharedmem.h"
|
||||
#include "sstring.hpp"
|
||||
#include "resource.h"
|
||||
#include "k32ord.h"
|
||||
|
||||
/** MSVC for-loop workaround. */
|
||||
/** MSVC 6.0 for-loop workaround. */
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER < 1201
|
||||
#define for if (0); else for
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define IS_SHARED(x) (((DWORD)x) >= 0x80000000)
|
||||
|
||||
extern HINSTANCE hInstance;
|
||||
|
||||
extern IMTE*** ppmteModTable;
|
||||
@ -45,8 +48,6 @@ extern WORD* pimteMax;
|
||||
extern sstring kernelex_dir;
|
||||
extern sstring own_path;
|
||||
|
||||
void FullCritLock();
|
||||
void FullCritUnlock();
|
||||
void ShowError(UINT id, ...);
|
||||
bool isWinMe();
|
||||
|
||||
@ -79,24 +80,4 @@ extern FreeLibRemove_t FreeLibRemove;
|
||||
|
||||
MODREF* MRfromCallerAddr(DWORD addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void __stdcall _EnterSysLevel(CRITICAL_SECTION*);
|
||||
void __stdcall _LeaveSysLevel(CRITICAL_SECTION*);
|
||||
|
||||
ULONG __stdcall VxDCall1(ULONG);
|
||||
ULONG __stdcall VxDCall2(ULONG, ULONG);
|
||||
ULONG __stdcall VxDCall3(ULONG, ULONG, ULONG);
|
||||
ULONG __stdcall VxDCall4(ULONG, ULONG, ULONG, ULONG);
|
||||
ULONG __stdcall VxDCall5(ULONG, ULONG, ULONG, ULONG, ULONG);
|
||||
ULONG __stdcall VxDCall6(ULONG, ULONG, ULONG, ULONG, ULONG, ULONG);
|
||||
ULONG __stdcall VxDCall7(ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG);
|
||||
ULONG __stdcall VxDCall8(ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,14 +0,0 @@
|
||||
LIBRARY KERNEL32.dll
|
||||
|
||||
EXPORTS
|
||||
CommonUnimpStub@0 @17 NONAME
|
||||
VxDCall1@4 @1 NONAME
|
||||
VxDCall2@8 @2 NONAME
|
||||
VxDCall3@12 @3 NONAME
|
||||
VxDCall4@16 @4 NONAME
|
||||
VxDCall5@20 @5 NONAME
|
||||
VxDCall6@24 @6 NONAME
|
||||
VxDCall7@28 @7 NONAME
|
||||
VxDCall8@32 @8 NONAME
|
||||
_EnterSysLevel@4 @97 NONAME
|
||||
_LeaveSysLevel@4 @98 NONAME
|
11
core/kexcoresdk.cpp
Executable file → Normal file
11
core/kexcoresdk.cpp
Executable file → Normal file
@ -33,6 +33,15 @@ unsigned long kexGetKEXVersion()
|
||||
return VERSION_CODE;
|
||||
}
|
||||
|
||||
int kexIsDebugCore()
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void kexDebugPrint(const char* format, ...)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
@ -68,7 +77,7 @@ void kexGetModuleSettings(const char* module,
|
||||
{
|
||||
appsetting as = SettingsDB::instance.get_appsetting(module);
|
||||
if (!as.conf)
|
||||
strcpy(conf_name, "default");
|
||||
conf_name[0] = '\0';
|
||||
else
|
||||
strncpy(conf_name, as.conf->get_name(), 256);
|
||||
*ldr_flags = as.flags;
|
||||
|
56
core/main.cpp
Executable file → Normal file
56
core/main.cpp
Executable file → Normal file
@ -25,6 +25,7 @@
|
||||
#include "debug.h"
|
||||
#include "apiconfmgr.h"
|
||||
#include "internals.h"
|
||||
#include "DebugWindow.h"
|
||||
|
||||
extern int internals_init();
|
||||
extern void internals_uninit();
|
||||
@ -33,15 +34,11 @@ extern void resolver_uninit();
|
||||
extern void resolver_hook();
|
||||
extern void resolver_unhook();
|
||||
|
||||
extern BOOL resolver_process_attach();
|
||||
|
||||
static int init_count = 0;
|
||||
|
||||
static void prepare()
|
||||
{
|
||||
ApiConfigurationManager acm;
|
||||
acm.reload_api_configurations();
|
||||
}
|
||||
|
||||
//these should be visible only in debug builds
|
||||
//these should be visible externally only in debug builds
|
||||
#ifdef _DEBUG
|
||||
extern "C" _KEXCOREIMP
|
||||
#endif
|
||||
@ -56,12 +53,17 @@ int kexInit()
|
||||
if (!internals_init())
|
||||
goto __error1;
|
||||
|
||||
prepare();
|
||||
if (!apiconfmgr.load_api_configurations())
|
||||
goto __error2;
|
||||
|
||||
if (!resolver_init())
|
||||
goto __error2;
|
||||
|
||||
resolver_hook();
|
||||
|
||||
#ifdef _DEBUG
|
||||
DebugWindow::create();
|
||||
#endif
|
||||
|
||||
DBGPRINTF(("Initialized successfully\n"));
|
||||
return ++init_count;
|
||||
@ -73,7 +75,7 @@ __error1:
|
||||
return 0;
|
||||
}
|
||||
|
||||
//these should be visible only in debug builds
|
||||
//these should be visible externally only in debug builds
|
||||
#ifdef _DEBUG
|
||||
extern "C" _KEXCOREIMP
|
||||
#endif
|
||||
@ -87,6 +89,9 @@ int kexUninit()
|
||||
DBGPRINTF(("Uninitializing\n"));
|
||||
resolver_unhook();
|
||||
resolver_uninit();
|
||||
#ifdef _DEBUG
|
||||
DebugWindow::destroy();
|
||||
#endif
|
||||
internals_uninit();
|
||||
return --init_count;
|
||||
}
|
||||
@ -114,7 +119,7 @@ void load_MPRServices()
|
||||
RegOpenKey(hk_serv, subkey, &hk_this);
|
||||
size = sizeof(dllname);
|
||||
if (RegQueryValueEx(hk_this, "DllName", NULL, NULL, (BYTE*)dllname, &size)
|
||||
== ERROR_SUCCESS && strcmpi(dllname, own_path.get()) != 0)
|
||||
== ERROR_SUCCESS && strcmpi(dllname, own_path) != 0)
|
||||
{
|
||||
LoadLibrary(dllname);
|
||||
}
|
||||
@ -130,7 +135,7 @@ void load_MPRServices()
|
||||
*/
|
||||
static bool ensure_shared_memory(DWORD addr)
|
||||
{
|
||||
if (addr < 0x80000000)
|
||||
if (!IS_SHARED(addr))
|
||||
{
|
||||
MessageBox(NULL, "KernelEx not loaded into shared memory!",
|
||||
"Critical Error", MB_ICONERROR | MB_OK);
|
||||
@ -187,18 +192,19 @@ BOOL APIENTRY PreDllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
|
||||
|
||||
if (reason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
if (!ensure_shared_memory((DWORD)instance))
|
||||
return FALSE;
|
||||
|
||||
if (is_failsafe_mode())
|
||||
return FALSE;
|
||||
|
||||
DisableThreadLibraryCalls(instance);
|
||||
|
||||
if (load_count((DWORD) instance) == 1)
|
||||
{
|
||||
//first reference => do init
|
||||
hInstance = instance;
|
||||
|
||||
if (!ensure_shared_memory((DWORD)instance))
|
||||
return FALSE;
|
||||
|
||||
if (is_failsafe_mode())
|
||||
return FALSE;
|
||||
|
||||
if (detect_old_version())
|
||||
return FALSE;
|
||||
|
||||
@ -212,6 +218,11 @@ BOOL APIENTRY PreDllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
|
||||
|
||||
get_own_path();
|
||||
}
|
||||
else
|
||||
{
|
||||
//referenced by other module => call resolver
|
||||
ret = resolver_process_attach();
|
||||
}
|
||||
}
|
||||
else if (reason == DLL_PROCESS_DETACH)
|
||||
{
|
||||
@ -231,6 +242,8 @@ BOOL APIENTRY DllMain(HINSTANCE instance, DWORD reason, BOOL load_static)
|
||||
{
|
||||
if (reason == DLL_PROCESS_ATTACH && GetModuleHandle("MPREXE.EXE"))
|
||||
{
|
||||
//auto start if loaded by MPREXE
|
||||
|
||||
//load all other MPR services before further execution
|
||||
load_MPRServices();
|
||||
|
||||
@ -238,15 +251,6 @@ BOOL APIENTRY DllMain(HINSTANCE instance, DWORD reason, BOOL load_static)
|
||||
if (!kexInit())
|
||||
return FALSE;
|
||||
|
||||
//in case KernelEx was loaded globally we don't want to unload it ever
|
||||
IMTE** pmteModTable = *ppmteModTable;
|
||||
pmteModTable[MRFromHLib(hInstance)->mteIndex]->cUsage++;
|
||||
|
||||
//we don't want to unload the api libraries as well
|
||||
ApiLibrary* apilib;
|
||||
for (int i = 1 ; apilib = ApiLibraryManager::get_apilib(i) ; i++)
|
||||
pmteModTable[MRFromHLib(apilib->mod_handle)->mteIndex]->cUsage++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
227
core/resolver.cpp
Executable file → Normal file
227
core/resolver.cpp
Executable file → Normal file
@ -29,6 +29,7 @@
|
||||
#include "../setup/loadstub.h"
|
||||
#include "thunks.h"
|
||||
#include "SettingsDB.h"
|
||||
#include "storage.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -39,11 +40,13 @@ static PLONG jtab;
|
||||
static LONG old_jtab[4];
|
||||
|
||||
|
||||
|
||||
/** Get API configuration for selected module.
|
||||
* @param module Target module.
|
||||
* @return Pointer to API configuration or NULL to not use extended API.
|
||||
* @param cp Value receives configuration information for extended API.
|
||||
* @return True to use extended API, false use standard API.
|
||||
*/
|
||||
static ApiConfiguration* get_config(MODREF* moduleMR)
|
||||
static bool get_config(MODREF* moduleMR, config_params& cp)
|
||||
{
|
||||
IMTE** pmteModTable = *ppmteModTable;
|
||||
PDB98* ppdbCur = *pppdbCur;
|
||||
@ -52,6 +55,10 @@ static ApiConfiguration* get_config(MODREF* moduleMR)
|
||||
ApiConfiguration* conf;
|
||||
BYTE flags;
|
||||
|
||||
//shared modules should use standard api
|
||||
if (IS_SHARED(module->baseAddress))
|
||||
return false;
|
||||
|
||||
//unless override flag is set try to get module configuration first
|
||||
if (!(process->flags & LDR_OVERRIDE_PROC_MOD))
|
||||
{
|
||||
@ -59,13 +66,13 @@ static ApiConfiguration* get_config(MODREF* moduleMR)
|
||||
{
|
||||
appsetting as = SettingsDB::instance.get_appsetting(module->pszFileName);
|
||||
module->config = as.conf;
|
||||
module->flags = as.flags | LDR_VALID_FLAG;
|
||||
module->flags = as.flags;
|
||||
}
|
||||
conf = module->config;
|
||||
flags = module->flags;
|
||||
|
||||
if (flags & LDR_KEX_DISABLE)
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
conf = NULL;
|
||||
@ -77,13 +84,13 @@ static ApiConfiguration* get_config(MODREF* moduleMR)
|
||||
{
|
||||
appsetting as = SettingsDB::instance.get_appsetting(process->pszFileName);
|
||||
process->config = as.conf;
|
||||
process->flags = as.flags | LDR_VALID_FLAG;
|
||||
process->flags = as.flags;
|
||||
}
|
||||
conf = process->config;
|
||||
flags = process->flags;
|
||||
|
||||
if (flags & LDR_KEX_DISABLE)
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
//if no process configuration then get parent configuration
|
||||
@ -97,18 +104,13 @@ static ApiConfiguration* get_config(MODREF* moduleMR)
|
||||
IMTE_KEX* parent = (IMTE_KEX*) pmteModTable[ppdbParent->pExeMODREF->mteIndex];
|
||||
conf = parent->config;
|
||||
flags = parent->flags;
|
||||
flags &= ~LDR_LOG_APIS; //don't inherit LOG flag
|
||||
|
||||
if (flags & LDR_KEX_DISABLE)
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & LDR_LOG_APIS)
|
||||
{
|
||||
//TODO: not implemented yet
|
||||
DBGPRINTF(("Resolver flag LDR_LOG_APIS not implemented\n"));
|
||||
}
|
||||
|
||||
if (flags & LDR_FILTER_APIS)
|
||||
{
|
||||
//TODO: not implemented yet
|
||||
@ -117,9 +119,18 @@ static ApiConfiguration* get_config(MODREF* moduleMR)
|
||||
|
||||
//finally if everything else fails take default configuration
|
||||
if (!conf)
|
||||
conf = ApiConfigurationManager::get_default_configuration();
|
||||
{
|
||||
if (apiconfmgr.are_extensions_disabled())
|
||||
return false;
|
||||
conf = apiconfmgr.get_default_configuration();
|
||||
}
|
||||
|
||||
return conf;
|
||||
DBGASSERT(conf != NULL);
|
||||
cp.apiconf = conf;
|
||||
#ifdef _DEBUG
|
||||
cp.log_apis = (flags & LDR_LOG_APIS) != 0;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Finds overridden module index for target module.
|
||||
@ -145,6 +156,15 @@ static WORD resolve_mod_index(IMTE_KEX* target)
|
||||
return target->mod_index = 0xffff;
|
||||
}
|
||||
|
||||
/** Resolves address where target function is in non-shared api library.
|
||||
* Checks if api library is loaded for process, if it isn't it is loaded.
|
||||
* Code executes either under process CS (dynamic resolve) or system CS
|
||||
* (static resolve).
|
||||
* @param addr Encoded api library ID + offset in this api library
|
||||
* @param caller Module that requests api from api library.
|
||||
* @param refmod
|
||||
* @return Valid address to function for calling process.
|
||||
*/
|
||||
static PROC resolve_nonshared_addr(DWORD addr, MODREF* caller, PMODREF** refmod)
|
||||
{
|
||||
MODREF* mr;
|
||||
@ -159,9 +179,9 @@ static PROC resolve_nonshared_addr(DWORD addr, MODREF* caller, PMODREF** refmod)
|
||||
DBGASSERT(addr >= 0xc0000000);
|
||||
api_lib_num = (addr >> 24) - 0xc0;
|
||||
DBGASSERT(api_lib_num > 0); //ensure apilib ID isn't STD's
|
||||
apilib = ApiLibraryManager::get_apilib(api_lib_num);
|
||||
apilib = apilibmgr.get_apilib_by_index(api_lib_num);
|
||||
DBGASSERT(apilib != NULL);
|
||||
DBGASSERT((DWORD) apilib->mod_handle < 0x80000000);
|
||||
DBGASSERT(!apilib->is_shared());
|
||||
idx = 0xff00 + api_lib_num;
|
||||
|
||||
//first check if api library has already been loaded
|
||||
@ -181,8 +201,11 @@ static PROC resolve_nonshared_addr(DWORD addr, MODREF* caller, PMODREF** refmod)
|
||||
|
||||
//if not - load it
|
||||
|
||||
strcpy(dllpath, kernelex_dir.get());
|
||||
strcat(dllpath, apilib->apilib_name);
|
||||
DBGPRINTF(("Loading non-shared apilib: %s req. by: %s [PID=%08x]\n",
|
||||
apilib->apilib_name, pmteModTable[caller->mteIndex]->pszModName,
|
||||
GetCurrentProcessId()));
|
||||
|
||||
apilib->get_dll_path(dllpath);
|
||||
|
||||
_EnterSysLevel(krnl32lock);
|
||||
mr = MRLoadTree(dllpath);
|
||||
@ -196,16 +219,41 @@ static PROC resolve_nonshared_addr(DWORD addr, MODREF* caller, PMODREF** refmod)
|
||||
|
||||
if (refmod) //static resolve (implicit)
|
||||
{
|
||||
for (int i = 0 ; i < caller->cImportedModules ; i++)
|
||||
buffer[i] = caller->ImplicitImports[i].pMR;
|
||||
|
||||
//FIXME: this will cause problems if apilib references another non-shared apilib!!
|
||||
//it is okay to use global buffer because static resolve code is protected by k32 lock
|
||||
**refmod = mr;
|
||||
*refmod += buffer - &caller->ImplicitImports[0].pMR;
|
||||
|
||||
//not buffered yet?
|
||||
if (!(*refmod >= buffer && *refmod < buffer + sizeof(buffer)))
|
||||
{
|
||||
//make a copy
|
||||
for (int i = 0 ; i < caller->cImportedModules ; i++)
|
||||
buffer[i] = caller->ImplicitImports[i].pMR;
|
||||
|
||||
//set reference to copy - copy will be seen by continuing resolve process
|
||||
*refmod += buffer - &caller->ImplicitImports[0].pMR;
|
||||
}
|
||||
|
||||
DBGPRINTF(("Implicit load: replacing tree %s => %s [PID=%08x]\n",
|
||||
pmteModTable[caller->ImplicitImports[*refmod - buffer].pMR->mteIndex]
|
||||
->pszModName, apilib->apilib_name,
|
||||
GetCurrentProcessId()));
|
||||
|
||||
//remember tree which we overwrite - we will initialize it ourselves
|
||||
//in resolver_process_attach as a result of initializing our tree
|
||||
//requirement: Core is in IAT of the apilib !!!
|
||||
storage* s = storage::get_storage(true);
|
||||
DBGASSERT(s != NULL);
|
||||
s->data[s->size++] = (void*) caller->ImplicitImports[*refmod - buffer].pMR;
|
||||
|
||||
//modify original - modifications will be seen by dll initializer
|
||||
//which will initialize our mr tree
|
||||
caller->ImplicitImports[*refmod - buffer].pMR = mr;
|
||||
}
|
||||
else //dynamic resolve (GetProcAddress)
|
||||
{
|
||||
DBGPRINTF(("Explicit load: initializing tree %s [PID=%08x]\n",
|
||||
apilib->apilib_name, GetCurrentProcessId()));
|
||||
|
||||
if (FLoadTreeNotify(mr, 0))
|
||||
{
|
||||
FreeLibTree(mr);
|
||||
@ -225,6 +273,48 @@ static PROC resolve_nonshared_addr(DWORD addr, MODREF* caller, PMODREF** refmod)
|
||||
return (PROC)(img_base + (addr & 0x00ffffff));
|
||||
}
|
||||
|
||||
/** Performs resolver actions on new process attach.
|
||||
* @return TRUE on success, FALSE otherwise.
|
||||
*/
|
||||
BOOL resolver_process_attach()
|
||||
{
|
||||
//initialize all modules replaced by api libraries
|
||||
bool loaded = false;
|
||||
storage* s = storage::get_storage(false);
|
||||
if (!s)
|
||||
return TRUE;
|
||||
|
||||
for (int i = 0 ; i < s->size ; i++)
|
||||
{
|
||||
DBGPRINTF(("Post-Initializing %s [PID=%08x]\n",
|
||||
(*ppmteModTable)[((MODREF*) s->data[i])->mteIndex]->pszModName,
|
||||
GetCurrentProcessId()));
|
||||
|
||||
if (FLoadTreeNotify((MODREF*) s->data[i], 1))
|
||||
return FALSE;
|
||||
loaded = true;
|
||||
}
|
||||
storage::return_storage();
|
||||
|
||||
if (!loaded)
|
||||
return TRUE;
|
||||
|
||||
//reference all shared api libraries
|
||||
ApiLibrary* lib;
|
||||
int i = 1;
|
||||
while ((lib = apilibmgr.get_apilib_by_index(i++)) != NULL)
|
||||
{
|
||||
if (lib->is_shared())
|
||||
{
|
||||
char dllpath[MAX_PATH];
|
||||
lib->get_dll_path(dllpath);
|
||||
LoadLibrary(dllpath);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static PROC WINAPI OriExportFromOrdinal(IMAGE_NT_HEADERS* PEh, WORD ordinal)
|
||||
{
|
||||
DWORD img_base;
|
||||
@ -382,7 +472,7 @@ DWORD encode_address(DWORD addr, const ApiLibrary* apilib)
|
||||
}
|
||||
|
||||
//non-shared apilib
|
||||
if ((DWORD) apilib->mod_handle < 0x80000000)
|
||||
if (!apilib->is_shared())
|
||||
{
|
||||
//max non-shared apilib size 16MB
|
||||
DBGASSERT(addr - (DWORD) apilib->mod_handle < 0x01000000);
|
||||
@ -403,7 +493,7 @@ inline PROC decode_address(DWORD p, IMAGE_NT_HEADERS* target_NThdr, MODREF* call
|
||||
if ((p & 0xffff0000) == 0xffff0000)
|
||||
return OriExportFromOrdinal(target_NThdr, LOWORD(p));
|
||||
//non-shared system library
|
||||
if (p < 0x80000000)
|
||||
if (!IS_SHARED(p))
|
||||
return (PROC)(p + target_NThdr->OptionalHeader.ImageBase);
|
||||
//non-shared api library
|
||||
if (p >= 0xc0000000)
|
||||
@ -420,8 +510,8 @@ PROC WINAPI ExportFromOrdinal(IMTE_KEX* target, MODREF* caller, PMODREF** refmod
|
||||
if (!caller)
|
||||
caller = (*pppdbCur)->pExeMODREF;
|
||||
|
||||
ApiConfiguration* apiconf = get_config(caller);
|
||||
if (apiconf)
|
||||
config_params cp;
|
||||
if (get_config(caller, cp))
|
||||
{
|
||||
WORD mod_index = target->mod_index;
|
||||
|
||||
@ -431,8 +521,8 @@ PROC WINAPI ExportFromOrdinal(IMTE_KEX* target, MODREF* caller, PMODREF** refmod
|
||||
DBGASSERT(mod_index);
|
||||
mod_index--;
|
||||
|
||||
if (!apiconf->is_table_empty(mod_index))
|
||||
ret = decode_address(apiconf->get(mod_index, ordinal),
|
||||
if (!cp.apiconf->is_table_empty(mod_index))
|
||||
ret = decode_address(cp.apiconf->get(mod_index, ordinal),
|
||||
target->pNTHdr, caller, refmod);
|
||||
else
|
||||
ret = OriExportFromOrdinal(target->pNTHdr, ordinal);
|
||||
@ -441,9 +531,11 @@ PROC WINAPI ExportFromOrdinal(IMTE_KEX* target, MODREF* caller, PMODREF** refmod
|
||||
ret = OriExportFromOrdinal(target->pNTHdr, ordinal);
|
||||
|
||||
if (!ret && refmod)
|
||||
{
|
||||
DBGPRINTF(("%s: unresolved export %s:%d\n",
|
||||
((*ppmteModTable)[caller->mteIndex])->pszModName,
|
||||
target->pszModName, ordinal));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -456,8 +548,8 @@ PROC WINAPI ExportFromName(IMTE_KEX* target, MODREF* caller, PMODREF** refmod, W
|
||||
if (!caller)
|
||||
caller = (*pppdbCur)->pExeMODREF;
|
||||
|
||||
ApiConfiguration* apiconf = get_config(caller);
|
||||
if (apiconf)
|
||||
config_params cp;
|
||||
if (get_config(caller, cp))
|
||||
{
|
||||
WORD mod_index = target->mod_index;
|
||||
|
||||
@ -467,69 +559,32 @@ PROC WINAPI ExportFromName(IMTE_KEX* target, MODREF* caller, PMODREF** refmod, W
|
||||
DBGASSERT(mod_index);
|
||||
mod_index--;
|
||||
|
||||
if (!apiconf->is_table_empty(mod_index))
|
||||
ret = decode_address(apiconf->get(mod_index, hint, name),
|
||||
if (!cp.apiconf->is_table_empty(mod_index))
|
||||
ret = decode_address(cp.apiconf->get(mod_index, hint, name),
|
||||
target->pNTHdr, caller, refmod);
|
||||
else
|
||||
ret = OriExportFromName(target->pNTHdr, hint, name);
|
||||
#ifdef _DEBUG
|
||||
if (ret && cp.log_apis)
|
||||
{
|
||||
IMTE_KEX* icaller = (IMTE_KEX*)((*ppmteModTable)[caller->mteIndex]);
|
||||
ret = create_log_stub(icaller->pszModName, target->pszModName, name, ret);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
ret = OriExportFromName(target->pNTHdr, hint, name);
|
||||
|
||||
if (!ret && refmod)
|
||||
{
|
||||
DBGPRINTF(("%s: unresolved export %s:%s\n",
|
||||
((*ppmteModTable)[caller->mteIndex])->pszModName,
|
||||
target->pszModName, name));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
//todo: vGetProcAddress_new
|
||||
PROC WINAPI GetProcAddress_new(HMODULE hModule, LPCSTR lpProcName)
|
||||
{
|
||||
DWORD caller = *((DWORD*)&hModule - 1);
|
||||
PDB98* ppdbCur = *pppdbCur;
|
||||
MODREF* mod_mr;
|
||||
IMAGE_NT_HEADERS* peh;
|
||||
PROC ret;
|
||||
|
||||
_EnterSysLevel(&ppdbCur->CriticalSection);
|
||||
mod_mr = MRFromHLib(hModule);
|
||||
if (!mod_mr)
|
||||
{
|
||||
_SetError(ERROR_INVALID_HANDLE);
|
||||
ret = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
IMTE_KEX* target = (IMTE_KEX*) pmteModTable[mod_mr->mteIndex];
|
||||
|
||||
if (HIWORD(lpProcName))
|
||||
{
|
||||
ret = ExportFromName(target, (IMTE_KEX*) IMTEfromCallerAddr(caller), 0, lpProcName);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = ExportFromOrdinal(target, (IMTE_KEX*) IMTEfromCallerAddr(caller), (WORD) lpProcName);
|
||||
}
|
||||
if (!ppdbCur->DebuggeeCB || _CheckMustComplete())
|
||||
{
|
||||
if (!ret)
|
||||
_SetError(ERROR_PROC_NOT_FOUND);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = _DEBCreateDIT(*((DWORD*)ppdbCur->DebuggeeCB + 5), ret);
|
||||
}
|
||||
|
||||
}
|
||||
_LeaveSysLevel(&ppdbCur->CriticalSection);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
PROC WINAPI iGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
|
||||
{
|
||||
IMAGE_DOS_HEADER* dos_hdr;
|
||||
@ -539,7 +594,7 @@ PROC WINAPI iGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
|
||||
nt_hdr = (IMAGE_NT_HEADERS*)((int)dos_hdr + dos_hdr->e_lfanew);
|
||||
|
||||
if ((DWORD)lpProcName < 0x10000)
|
||||
return OriExportFromOrdinal(nt_hdr, (WORD)lpProcName);
|
||||
return OriExportFromOrdinal(nt_hdr, LOWORD(lpProcName));
|
||||
return OriExportFromName(nt_hdr, 0, lpProcName);
|
||||
}
|
||||
|
||||
@ -592,17 +647,17 @@ void dump_imtes(void)
|
||||
int total = 0;
|
||||
|
||||
dbgprintf("Dumping IMTEs...\n");
|
||||
dbgprintf("%-6s %-12s %s %s %s\n", "No.", "Process", "Module", "Config", "Flags");
|
||||
dbgprintf("%-4s %-12s %-7s %s %s\n", "No.", "Process", "Config", "Fl", "Module");
|
||||
for (WORD i = 0 ; i < imteMax ; i++)
|
||||
{
|
||||
IMTE_KEX* imte = (IMTE_KEX*) pmteModTable[i];
|
||||
if (imte)
|
||||
{
|
||||
dbgprintf("#%-5d %-12s %s %s %02x\n", i,
|
||||
pmteModTable[imte->pMR->ppdb->pExeMODREF->mteIndex]->pszSModName,
|
||||
imte->pszFileName,
|
||||
dbgprintf("#%-3d %-12s %-7s %02x %s\n", i,
|
||||
pmteModTable[imte->pMR->ppdb->pExeMODREF->mteIndex]->pszSModName,
|
||||
imte->config ? imte->config->get_name() : "unknown",
|
||||
imte->flags);
|
||||
imte->flags,
|
||||
imte->pszFileName);
|
||||
total++;
|
||||
}
|
||||
}
|
||||
|
11
core/resolver.h
Executable file → Normal file
11
core/resolver.h
Executable file → Normal file
@ -51,7 +51,8 @@ struct IMTE_KEX : public IMTE
|
||||
class redir_stub
|
||||
{
|
||||
public:
|
||||
redir_stub(unsigned long target) : c_eax(0xb8), v_eax(target), c_jmp(0xe0ff) {}
|
||||
redir_stub(unsigned long target, bool make_call = false) : c_eax(0xb8),
|
||||
v_eax(target), c_jmp(make_call ? 0xd0ff : 0xe0ff) {}
|
||||
|
||||
private:
|
||||
unsigned char c_eax;
|
||||
@ -59,6 +60,14 @@ private:
|
||||
unsigned short c_jmp;
|
||||
};
|
||||
|
||||
struct config_params
|
||||
{
|
||||
ApiConfiguration* apiconf;
|
||||
#ifdef _DEBUG
|
||||
bool log_apis;
|
||||
#endif
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
DWORD encode_address(DWORD addr, const ApiLibrary* apilib);
|
||||
|
15
core/resource.h
Executable file → Normal file
15
core/resource.h
Executable file → Normal file
@ -5,14 +5,23 @@
|
||||
#define IDS_NOTREADY 1
|
||||
#define IDS_STUBMISMATCH 2
|
||||
#define IDS_OLDVER 3
|
||||
#define IDD_DEBUG 101
|
||||
#define IDR_LOGMENU 102
|
||||
#define IDD_DEBUGFILTER 103
|
||||
#define IDC_LOG 1003
|
||||
#define IDC_DFINCLUDE 1004
|
||||
#define IDC_DFEXCLUDE 1005
|
||||
#define IDM_TOFILE 40001
|
||||
#define IDM_CLEAR 40002
|
||||
#define IDM_FILTER 40003
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_RESOURCE_VALUE 104
|
||||
#define _APS_NEXT_COMMAND_VALUE 40004
|
||||
#define _APS_NEXT_CONTROL_VALUE 1006
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
10
core/sharedmem.cpp
Executable file → Normal file
10
core/sharedmem.cpp
Executable file → Normal file
@ -95,3 +95,13 @@ void operator delete(void* ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void* operator new[](size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void operator delete[](void* ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
2
core/sharedmem.h
Executable file → Normal file
2
core/sharedmem.h
Executable file → Normal file
@ -36,7 +36,7 @@ void* realloc(void* ptr, size_t size);
|
||||
void* recalloc(void* ptr, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
61
core/storage.cpp
Normal file
61
core/storage.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx 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; version 2 of the License.
|
||||
*
|
||||
* KernelEx 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 GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include "storage.h"
|
||||
#include "internals.h"
|
||||
#include "debug.h"
|
||||
|
||||
struct PDB_KEX : PDB98
|
||||
{
|
||||
void* kex_data_storage;
|
||||
};
|
||||
|
||||
const int storage::storage_size = 0x1000;
|
||||
|
||||
storage* storage::get_storage(bool alloc)
|
||||
{
|
||||
PDB_KEX* pdb = (PDB_KEX*) *pppdbCur;
|
||||
storage* s = (storage*) pdb->kex_data_storage;
|
||||
|
||||
if (!s && alloc)
|
||||
{
|
||||
pdb->kex_data_storage = VirtualAlloc(NULL, storage_size,
|
||||
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
DBGASSERT(pdb->kex_data_storage != NULL);
|
||||
memset(pdb->kex_data_storage, 0, storage_size);
|
||||
s = (storage*) pdb->kex_data_storage;
|
||||
s->size = 0;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void storage::return_storage()
|
||||
{
|
||||
PDB_KEX* pdb = (PDB_KEX*) *pppdbCur;
|
||||
if (pdb->kex_data_storage)
|
||||
{
|
||||
BOOL ret = VirtualFree(pdb->kex_data_storage, 0, MEM_RELEASE);
|
||||
DBGASSERT(ret != FALSE);
|
||||
pdb->kex_data_storage = NULL;
|
||||
}
|
||||
}
|
17
core/version.h → core/storage.h
Executable file → Normal file
17
core/version.h → core/storage.h
Executable file → Normal file
@ -19,11 +19,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __VERSION_H
|
||||
#define __VERSION_H
|
||||
#ifndef __STORAGE_H
|
||||
#define __STORAGE_H
|
||||
|
||||
#define VERSION_STR "4.0 RC 2"
|
||||
#define VERSION_CODE 0x0400000C
|
||||
#define RCVERSION 4, 0, 1, 2
|
||||
class storage
|
||||
{
|
||||
public:
|
||||
int size;
|
||||
void* data[1]; //dummy table
|
||||
|
||||
static const int storage_size;
|
||||
static storage* get_storage(bool alloc);
|
||||
static void return_storage();
|
||||
};
|
||||
|
||||
#endif
|
0
core/structs.h
Executable file → Normal file
0
core/structs.h
Executable file → Normal file
0
core/thunks.cpp
Executable file → Normal file
0
core/thunks.cpp
Executable file → Normal file
0
core/thunks.h
Executable file → Normal file
0
core/thunks.h
Executable file → Normal file
0
core/wildcmp.cpp
Executable file → Normal file
0
core/wildcmp.cpp
Executable file → Normal file
0
core/wildcmp.h
Executable file → Normal file
0
core/wildcmp.h
Executable file → Normal file
Reference in New Issue
Block a user