From aebb257da0067c98c292bc62ad73200cc3a9dba7 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sat, 21 Mar 2015 19:15:39 +0000 Subject: DEF-file automatic creator git-svn-id: http://svn.miranda-ng.org/main/trunk@12473 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- tools/MakeDef/MakeDef.exe | Bin 0 -> 16384 bytes tools/MakeDef/MakeDef.sln | 28 ++ tools/MakeDef/MakeDef.vcxproj | 246 ++++++++++++++++ tools/MakeDef/MakeDef.vcxproj.filters | 51 ++++ tools/MakeDef/MakeDef64.exe | Bin 0 -> 18944 bytes tools/MakeDef/MakeDefs.cpp | 524 ++++++++++++++++++++++++++++++++++ tools/MakeDef/h_collection.h | 222 ++++++++++++++ tools/MakeDef/h_object.h | 101 +++++++ tools/MakeDef/h_types.h | 49 ++++ tools/MakeDef/h_util.h | 50 ++++ tools/MakeDef/lib_str.cpp | 113 ++++++++ tools/MakeDef/newstr.cpp | 8 + tools/MakeDef/tcollect.cpp | 221 ++++++++++++++ tools/MakeDef/tnsrtcol.cpp | 78 +++++ tools/MakeDef/tsmall.cpp | 155 ++++++++++ 15 files changed, 1846 insertions(+) create mode 100644 tools/MakeDef/MakeDef.exe create mode 100644 tools/MakeDef/MakeDef.sln create mode 100644 tools/MakeDef/MakeDef.vcxproj create mode 100644 tools/MakeDef/MakeDef.vcxproj.filters create mode 100644 tools/MakeDef/MakeDef64.exe create mode 100644 tools/MakeDef/MakeDefs.cpp create mode 100644 tools/MakeDef/h_collection.h create mode 100644 tools/MakeDef/h_object.h create mode 100644 tools/MakeDef/h_types.h create mode 100644 tools/MakeDef/h_util.h create mode 100644 tools/MakeDef/lib_str.cpp create mode 100644 tools/MakeDef/newstr.cpp create mode 100644 tools/MakeDef/tcollect.cpp create mode 100644 tools/MakeDef/tnsrtcol.cpp create mode 100644 tools/MakeDef/tsmall.cpp (limited to 'tools/MakeDef') diff --git a/tools/MakeDef/MakeDef.exe b/tools/MakeDef/MakeDef.exe new file mode 100644 index 0000000000..b173e5286e Binary files /dev/null and b/tools/MakeDef/MakeDef.exe differ diff --git a/tools/MakeDef/MakeDef.sln b/tools/MakeDef/MakeDef.sln new file mode 100644 index 0000000000..777d3f4082 --- /dev/null +++ b/tools/MakeDef/MakeDef.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Express 2013 for Windows Desktop +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MakeDef", "MakeDef.vcxproj", "{E7DF4F0F-845D-5338-DC65-68AB9EC22FEB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E7DF4F0F-845D-5338-DC65-68AB9EC22FEB}.Debug|Win32.ActiveCfg = Debug|Win32 + {E7DF4F0F-845D-5338-DC65-68AB9EC22FEB}.Debug|Win32.Build.0 = Debug|Win32 + {E7DF4F0F-845D-5338-DC65-68AB9EC22FEB}.Debug|x64.ActiveCfg = Debug|x64 + {E7DF4F0F-845D-5338-DC65-68AB9EC22FEB}.Debug|x64.Build.0 = Debug|x64 + {E7DF4F0F-845D-5338-DC65-68AB9EC22FEB}.Release|Win32.ActiveCfg = Release|Win32 + {E7DF4F0F-845D-5338-DC65-68AB9EC22FEB}.Release|Win32.Build.0 = Release|Win32 + {E7DF4F0F-845D-5338-DC65-68AB9EC22FEB}.Release|x64.ActiveCfg = Release|x64 + {E7DF4F0F-845D-5338-DC65-68AB9EC22FEB}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tools/MakeDef/MakeDef.vcxproj b/tools/MakeDef/MakeDef.vcxproj new file mode 100644 index 0000000000..0283f2552e --- /dev/null +++ b/tools/MakeDef/MakeDef.vcxproj @@ -0,0 +1,246 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + {E7DF4F0F-845D-5338-DC65-68AB9EC22FEB} + + + + Application + MultiByte + v120_xp + + + Application + MultiByte + v120_xp + + + Application + MultiByte + true + false + v120_xp + + + Application + MultiByte + true + false + v120_xp + + + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)\Obj\$(Platform)\$(Configuration)\ + false + $(SolutionDir) + + + false + $(SolutionDir)\Obj\$(Platform)\$(Configuration)\ + MakeDef64 + $(SolutionDir) + + + $(SolutionDir)\Obj\$(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\ + + + true + $(SolutionDir)\Obj\$(Platform)\$(Configuration)\ + MakeDef64 + $(SolutionDir)$(Platform)\ + + + + MultiThreadedDLL + OnlyExplicitInline + true + true + Full + true + Level3 + %(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;__NO_MEM_MANAGER__;__STATIC__;%(PreprocessorDefinitions) + 4Bytes + Size + + + .\Release\MakeDef.tlb + + + 0x0419 + NDEBUG;%(PreprocessorDefinitions) + + + true + .\Release\MakeDef.bsc + + + true + Console + %(AdditionalDependencies) + /filealign:512 + true + true + + + + + MultiThreadedDLL + OnlyExplicitInline + true + true + Full + true + Level3 + %(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;__NO_MEM_MANAGER__;__STATIC__;%(PreprocessorDefinitions) + 4Bytes + Size + + + .\Release\MakeDef.tlb + + + 0x0419 + NDEBUG;%(PreprocessorDefinitions) + + + true + .\Release\MakeDef.bsc + + + true + Console + %(AdditionalDependencies) + /filealign:512 + true + true + + + + + MultiThreadedDebug + Default + false + Disabled + true + Level3 + true + EditAndContinue + %(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;__NO_MEM_MANAGER__;__STATIC__;%(PreprocessorDefinitions) + true + EnableFastChecks + + + .\Debug\MakeDef.tlb + + + 0x0419 + _DEBUG;%(PreprocessorDefinitions) + + + true + .\Debug\MakeDef.bsc + + + true + true + Console + %(AdditionalDependencies) + + + + + MultiThreadedDebug + Default + false + Disabled + true + Level3 + ProgramDatabase + %(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;__NO_MEM_MANAGER__;__STATIC__;%(PreprocessorDefinitions) + true + .\Debug\MakeDef.pch + EnableFastChecks + + + .\Debug\MakeDef.tlb + + + 0x0419 + _DEBUG;%(PreprocessorDefinitions) + + + true + .\Debug\MakeDef.bsc + + + true + true + Console + %(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tools/MakeDef/MakeDef.vcxproj.filters b/tools/MakeDef/MakeDef.vcxproj.filters new file mode 100644 index 0000000000..5e2e3c877a --- /dev/null +++ b/tools/MakeDef/MakeDef.vcxproj.filters @@ -0,0 +1,51 @@ + + + + + {b20887f8-d114-436d-9988-ff0add4c92d1} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {1057e693-5e66-4635-9a5b-978e8ee9eec6} + h;hpp;hxx;hm;inl + + + {ad2ccae3-6cb5-42c1-bec1-fce160b7de12} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/tools/MakeDef/MakeDef64.exe b/tools/MakeDef/MakeDef64.exe new file mode 100644 index 0000000000..e9e2e812f3 Binary files /dev/null and b/tools/MakeDef/MakeDef64.exe differ diff --git a/tools/MakeDef/MakeDefs.cpp b/tools/MakeDef/MakeDefs.cpp new file mode 100644 index 0000000000..0179a4d53f --- /dev/null +++ b/tools/MakeDef/MakeDefs.cpp @@ -0,0 +1,524 @@ +// MakeDefs.cpp : Defines the entry point for the application. +// + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include +#include +#include + +#include + +#include "h_collection.h" +#include "h_util.h" + +struct HExport +{ + char* mName; + char* mAliasName; + int mOrdinalValue; + int mExportedByOrdinal; + long mAddress; +}; + +struct HExportsColl1 : public SortedCollection +{ + HExportsColl1() : + SortedCollection( 0, 300 ) + {} + + virtual int compare( const void* p1, const void* p2 ) const + { return _stricmp(( char* )p1, ( char* )p2 ); + } + + virtual const void* keyOf( const void* pItem ) const + { return (( HExport* )pItem )->mName; + } +}; + +struct HExportsColl2 : public SortedCollection +{ + HExportsColl2() : + SortedCollection( 0, 300 ) + {} + + virtual int compare( const void* p1, const void* p2 ) const + { return _stricmp(( char* )p1, ( char* )p2 ); + } + + virtual const void* keyOf( const void* pItem ) const + { return (( HExport* )pItem )->mAliasName; + } +}; + +HExportsColl1 tOldDefs; +HExportsColl2 tOldDefsAliases; + +int gMaxOrdinal = -1; +int gNewExports = 0; +int gRebuild = 0; +int gNoSort = 0; +char* gImportDllName = NULL; + +HSmallAllocator gMM( 16000 ); + +//====[ Prints standard Win32 error message ]============================================ + +void PrintWin32Error(DWORD tErrorCode) +{ + char tBuffer[1024]; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, tBuffer, sizeof(tBuffer), NULL); + fputs(tBuffer, stderr); + fputc('\n', stderr); +} + +//====[ Deletes all mapping resources ]================================================== + +void UnloadFile(HANDLE hFile, HANDLE hMap, BYTE* pMap) +{ + if (pMap) + ::UnmapViewOfFile(pMap); + + if (hMap) + ::CloseHandle(hMap); + + if (hFile != INVALID_HANDLE_VALUE) + ::CloseHandle(hFile); +} + +//====[ Loads PE image file to memory mapping ]========================================== + +bool LoadFile(LPCTSTR pszPathName, HANDLE& phFile, HANDLE& phMap, BYTE*& ppMap) +{ + phFile = INVALID_HANDLE_VALUE; + phMap = NULL; + ppMap = NULL; + + DWORD tErrorCode; + + phFile = ::CreateFile(pszPathName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (phFile == INVALID_HANDLE_VALUE) { + tErrorCode = GetLastError(); + fprintf(stderr, "Error opening '%s': ", pszPathName); + PrintWin32Error(tErrorCode); + return false; + } + + if ((phMap = ::CreateFileMapping(phFile, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL) { + tErrorCode = GetLastError(); + fprintf(stderr, "Error creating file mapping over '%s': ", pszPathName); + PrintWin32Error(tErrorCode); + UnloadFile(phFile, phMap, ppMap); + return false; + } + + if ((ppMap = (BYTE*)::MapViewOfFile(phMap, FILE_MAP_READ, 0, 0, 0)) == NULL) { + tErrorCode = GetLastError(); + fprintf(stderr, "Error reading mapped file '%s': ", pszPathName); + PrintWin32Error(tErrorCode); + UnloadFile(phFile, phMap, ppMap); + return false; + } + + return true; +} + +//====[ Verifies DOS header ]============================================================ + +IMAGE_DOS_HEADER* GetImageDosHeader(void* pFilePtr) +{ + if (::IsBadReadPtr(pFilePtr, sizeof(IMAGE_DOS_HEADER))) + return NULL; + + IMAGE_DOS_HEADER* pIDH = (IMAGE_DOS_HEADER*)pFilePtr; + if (pIDH->e_magic != IMAGE_DOS_SIGNATURE) + return NULL; + + return pIDH; +} + +//====[ Verifies PE header ]============================================================= + +IMAGE_NT_HEADERS* GetImageNtHeaders(IMAGE_DOS_HEADER* pIDH) +{ + IMAGE_NT_HEADERS* pINTH = (IMAGE_NT_HEADERS*)((UINT_PTR)pIDH + pIDH->e_lfanew); + if (::IsBadReadPtr(pINTH, sizeof(UINT_PTR))) + return NULL; + + if (pINTH->Signature != IMAGE_NT_SIGNATURE) + return NULL; + + return pINTH; +} + +//====[ Maps virtual address to file offset ]============================================ + +UINT_PTR RVAtoAddress(UINT_PTR dwRVA, IMAGE_NT_HEADERS* pINTH, void* pMap) +{ + IMAGE_SECTION_HEADER* pISH = IMAGE_FIRST_SECTION(pINTH); + if (!pISH) + return 0; + + for (DWORD i = 0; i < pINTH->FileHeader.NumberOfSections; i++) { + UINT_PTR dwStart = pISH->VirtualAddress; + UINT_PTR dwEnd = dwStart + pISH->SizeOfRawData; + + if (dwRVA >= dwStart && dwRVA < dwEnd) + return (UINT_PTR)pMap + (UINT_PTR)pISH->PointerToRawData + dwRVA - dwStart; + + pISH++; + } + + return 0; +} + +static bool sCheckAddress(HExport* p1, void* p2) +{ + return p1->mAddress == *(long*)p2; +} + +void IterateFunction(FILE* file, char* pszName, int ordinal = -1) +{ + if (pszName == NULL) + return; + + HExport temp; + temp.mAliasName = temp.mName = pszName; + temp.mOrdinalValue = ordinal; + + HExport* tNewExport = tOldDefs.Search(pszName); + if (tNewExport == NULL) + tNewExport = tOldDefsAliases.Search(pszName); + + if (tNewExport == NULL) { + gNewExports++; + + if (gRebuild) { + tNewExport = new(gMM)HExport; + tNewExport->mAliasName = NULL; + tNewExport->mName = gMM.placeStr(pszName); + tNewExport->mExportedByOrdinal = true; + tNewExport->mOrdinalValue = ordinal; + tOldDefs.insert(tNewExport); + } + else fprintf(file, "%s @%d NONAME\n", pszName, ++gMaxOrdinal); + } + else if (gRebuild) + tNewExport->mOrdinalValue = ordinal; +} + +//====[ Lists all exports in a section ]================================================= + +static char sttMsgHdr[] = "Fatal error reading PE-image headers"; + +bool GetExport(FILE* file, IMAGE_NT_HEADERS* pINTH, BYTE* pMap, bool listExports) +{ + IMAGE_SECTION_HEADER* pISH = IMAGE_FIRST_SECTION(pINTH); + if (!pISH) + return false; + + IMAGE_DATA_DIRECTORY* tDir; + IMAGE_NT_HEADERS64* pINTH64 = NULL; + + if (pINTH->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) + pINTH64 = (IMAGE_NT_HEADERS64*)pINTH; + else if (pINTH->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) + pINTH64 = (IMAGE_NT_HEADERS64*)pINTH; + else + if (pINTH->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) { + fprintf(stderr, "%s: machine code '%08x' is not supported\n", sttMsgHdr, pINTH->FileHeader.Machine); + return false; + } + + int tDirectoryID = (listExports) ? IMAGE_DIRECTORY_ENTRY_EXPORT : IMAGE_DIRECTORY_ENTRY_IMPORT; + + if (pINTH64 != NULL) + tDir = &pINTH64->OptionalHeader.DataDirectory[tDirectoryID]; + else + tDir = &pINTH->OptionalHeader.DataDirectory[tDirectoryID]; + + if (tDir->Size == 0 || tDir->VirtualAddress == 0) + return false; + + DWORD i; + for (i = 0; i < pINTH->FileHeader.NumberOfSections; i++, pISH++) { + if (tDir->VirtualAddress >= pISH->VirtualAddress && + tDir->VirtualAddress + tDir->Size <= pISH->VirtualAddress + pISH->SizeOfRawData) + break; + } + + if (i == pINTH->FileHeader.NumberOfSections) { + fprintf(stderr, "%s: required PE-image section not found\n", sttMsgHdr); + return false; + } + + BYTE* tSection = pMap + tDir->VirtualAddress - (pISH->VirtualAddress - pISH->PointerToRawData); + + if (listExports) { + IMAGE_EXPORT_DIRECTORY* pIED = (IMAGE_EXPORT_DIRECTORY*)tSection; + if (pIED->NumberOfNames == 0) + return true; + + WORD* pOrdinals = (WORD*)::RVAtoAddress(pIED->AddressOfNameOrdinals, pINTH, pMap); + + DWORD* pAddrOfNames = (DWORD*)::RVAtoAddress(pIED->AddressOfNames, pINTH, pMap); + if (pAddrOfNames) { + for (DWORD i = 0; i < pIED->NumberOfNames; i++) { + int tOrdinal = -1; + if (pOrdinals != NULL) + tOrdinal = pOrdinals[i] + pIED->Base; + + IterateFunction(file, (char*)::RVAtoAddress(pAddrOfNames[i], pINTH, pMap), tOrdinal); + } + } + } + else { + for (IMAGE_IMPORT_DESCRIPTOR* pIID = (IMAGE_IMPORT_DESCRIPTOR*)tSection; + pIID->Characteristics != 0; + pIID++) { + if (gImportDllName != NULL) { + char* tDllName = (char*)tSection + pIID->Name - tDir->VirtualAddress; + if (tDllName == NULL) + return false; + + if (_stricmp(tDllName, gImportDllName) != 0) + continue; + } + + DWORD* pAddrOfFuncs = (DWORD*)(tSection + pIID->Characteristics - tDir->VirtualAddress); + while (*pAddrOfFuncs != 0) { + if (!(pAddrOfFuncs[0] & 0x80000000)) { + IMAGE_IMPORT_BY_NAME* tImport = (IMAGE_IMPORT_BY_NAME*)(tSection + *pAddrOfFuncs - tDir->VirtualAddress); + IterateFunction(file, (char*)&tImport->Name); + } + + pAddrOfFuncs++; + } + } + } + + fprintf(stderr, "\rFinished processing DLL, %d new exports added", gNewExports); + if (gNewExports > 0) + fprintf(stderr, "\nYou should relink your DLL\n\n"); + + return true; +} + +//====[ Main ]=========================================================================== + +int main(int argc, char** argv) +{ + fprintf(stderr, "DEF file intelligent creator v.1.4, copyright (c) George Hazan (ghazan@postman.ru), 1999-2004.\nSpecial thanks to Andrey No for PE image scanner sources\n\n"); + + //----[ Command line parsing ]-------------------------------------------------------- + + char* tDefFileName = NULL; + char* tDllFileName = NULL; + bool tUseExports = true; + + for (int i = 1; i < argc; i++) { + if (argv[i][0] != '/') { +LBL_Usage: + fprintf(stderr, "Usage: MakeDefs /DEF: /IMAGE: [/REBUILDALL] [/NOSORT] [ /IMPORTS [: ]]\n"); + return 200; + } + + if (_memicmp(&argv[i][1], "DEF:", 4) == 0) + tDefFileName = &argv[i][5]; + else if (_memicmp(&argv[i][1], "IMAGE:", 6) == 0) + tDllFileName = &argv[i][7]; + else if (_memicmp(&argv[i][1], "IMPORTS", 7) == 0) { + tUseExports = false; + gImportDllName = (argv[i][8] == ':') ? argv[i] + 9 : NULL; + } + else if (_memicmp(&argv[i][1], "REBUILDALL", 10) == 0) + gRebuild = 1; + else if (_memicmp(&argv[i][1], "NOSORT", 6) == 0) + gNoSort = 1; + else goto LBL_Usage; + } + + if (tDefFileName == NULL || tDllFileName == NULL) + goto LBL_Usage; + + //----[ Command line ok, opening data files ]----------------------------------------- + + int tResult = 0, tLineNo = 0; + + char tBuffer[1024]; + strncpy_s(tBuffer, "mkdXXXXXX", _TRUNCATE); + + char *tTemplate = _mktemp(tBuffer); + FILE* tTempFile = fopen(tTemplate, "wt"); + if (tTempFile == NULL) { + fprintf(stderr, "Unable to create temporary file %s\n", tTemplate); + return 100; + } + + FILE* tInFile = fopen(tDefFileName, "rt"); + if (tInFile == NULL) { + fprintf(stderr, "Creating new DEF file: '%s'...\n", tDefFileName); + + char tDrive[_MAX_DRIVE], tPath[_MAX_DIR], tFName[_MAX_FNAME], tExt[_MAX_EXT]; + _splitpath(tDllFileName, tDrive, tPath, tFName, tExt); + + fprintf(tTempFile, "LIBRARY %s.DLL\nDESCRIPTION\n\nEXPORTS\n", tFName); + gMaxOrdinal = 0; + } + else { + fprintf(stderr, "Processing DEF file: '%s'...\n", tDefFileName); + + while (fgets(tBuffer, sizeof(tBuffer), tInFile) != NULL) { + fputs(tBuffer, tTempFile); + tLineNo++; + + if (_stricmp(trim(tBuffer), "EXPORTS") == 0) + goto LBL_DefFileOk; + } + +LBL_DefFileBad: + fprintf(stderr, "'%s is not a valid DEF file\n", tDefFileName); + tResult = 101; + +LBL_ErrorExit: + fclose(tTempFile); + _unlink(tTemplate); + return tResult; + +LBL_DefFileOk: + if (gRebuild) + gMaxOrdinal = 0; + + while (fgets(tBuffer, sizeof(tBuffer), tInFile) != NULL) { + if (!gRebuild) + fputs(tBuffer, tTempFile); + + tLineNo++; + + char* p = trim(tBuffer); + if (*p == EOS || *p == ';') + continue; + + char* tEndIdent = p + strcspn(p, " \t"); + if (tEndIdent == p) { + fprintf(stderr, "Line %d: invalid export identifier\n", tLineNo); + goto LBL_DefFileBad; + } + + *tEndIdent++ = 0; + tEndIdent += strspn(tEndIdent, " \t"); + + HExport* tNewExport = new(gMM)HExport; + tNewExport->mName = gMM.placeStr(p); + + if (*tEndIdent == '=') { + p = ltrim(tEndIdent + 1); + tEndIdent = p + strcspn(p, " \t"); + if (tEndIdent == p) { + fprintf(stderr, "Line %d: invalid export identifier\n", tLineNo); + goto LBL_DefFileBad; + } + + *tEndIdent++ = 0; + tEndIdent += strspn(tEndIdent, " \t"); + + tNewExport->mAliasName = gMM.placeStr(p); + } + else tNewExport->mAliasName = ""; + + tOldDefs.insert(tNewExport); + tOldDefsAliases.insert(tNewExport); + + if (*tEndIdent != '@') { + fprintf(stderr, "Line %d: symbol '@' not found\n", tLineNo); + goto LBL_DefFileBad; + } + + p = ltrim(tEndIdent + 1); + if (*p == '?') + tNewExport->mOrdinalValue = -1; + else { + int tOrdinal; + if (sscanf(p, "%d", &tOrdinal) != 1) { + fprintf(stderr, "Line %d: invalid ordinal value\n", tLineNo); + goto LBL_DefFileBad; + } + + if (!gRebuild && tOrdinal > gMaxOrdinal) + gMaxOrdinal = tOrdinal; + + tNewExport->mOrdinalValue = tOrdinal; + } + + tEndIdent = p + strcspn(p, " \t"); + tNewExport->mExportedByOrdinal = (_stricmp(trim(tEndIdent), "NONAME") == 0); + } + + fclose(tInFile); + fprintf(stderr, "\rFinished processing '%s', maximum ordinal value is %d\n", tDefFileName, gMaxOrdinal); + } + + fprintf(stderr, "Scanning DLL...\n"); + + HANDLE hFile; + HANDLE hMap; + BYTE* pMap; + if (!LoadFile(tDllFileName, hFile, hMap, pMap)) { + fprintf(stderr, "'%s' does not exist or seems not to be a valid PE image\n", tDllFileName); + tResult = 102; + goto LBL_ErrorExit; + } + + IMAGE_DOS_HEADER* pIDH = GetImageDosHeader(pMap); + if (!pIDH) { + fprintf(stderr, "'%s' does not contain a valid DOS header\n", tDllFileName); + tResult = 103; + goto LBL_ErrorExit; + } + + IMAGE_NT_HEADERS* pINTH = GetImageNtHeaders(pIDH); + if (!pINTH) { + fprintf(stderr, "'%s' does not contain a valid PE image header\n", tDllFileName); + tResult = 104; + goto LBL_ErrorExit; + } + + if (!GetExport(tTempFile, pINTH, pMap, tUseExports)) { + fprintf(stderr, "Fatal error reading export table from '%s'\n", tDllFileName); + tResult = 105; + goto LBL_ErrorExit; + } + + UnloadFile(hFile, hMap, pMap); + + if (gRebuild) { + for (int i = 0; i < tOldDefs.getCount(); i++) { + HExport* E = tOldDefs[i]; + if (E->mAliasName[0] == EOS) + fputs(E->mName, tTempFile); + else + fprintf(tTempFile, "%s = %s", E->mName, E->mAliasName); + + if (E->mOrdinalValue == -1) + fputs(" @?", tTempFile); + else + fprintf(tTempFile, " @%d", (gNoSort) ? E->mOrdinalValue : i + 1); + + if (E->mExportedByOrdinal) + fputs(" NONAME", tTempFile); + + fputc('\n', tTempFile); + } + } + + fclose(tTempFile); + + if (gNewExports != 0 || gRebuild) { + _unlink(tDefFileName); + rename(tTemplate, tDefFileName); + return 1; + } + + _unlink(tTemplate); + return 0; +} diff --git a/tools/MakeDef/h_collection.h b/tools/MakeDef/h_collection.h new file mode 100644 index 0000000000..2e358bd6f2 --- /dev/null +++ b/tools/MakeDef/h_collection.h @@ -0,0 +1,222 @@ + +#if !defined( __TNSCOLL_H ) + #define __TNSCOLL_H + + #if !defined( __TOBJECT_H ) + #include "h_object.h" + #endif + + #if !defined( __TTYPES_H ) + #include "h_types.h" + #endif + + #define DEFAULT_COLL_SIZE 20 + #define DEFAULT_COLL_DELTA 10 + +typedef int ccIndex; +typedef bool ( *ccTestFunc )( void*, void* ); +typedef void ( *ccAppFunc )( void*, void* ); + +const ccIndex ccNotFound = -1; + +//============================================================================= +// HCollection +//============================================================================= + +struct HCollection : public HObject +{ + HCollection( ccIndex aLimit = DEFAULT_COLL_SIZE, ccIndex aDelta = DEFAULT_COLL_DELTA ); + ~HCollection(); + + void* at( ccIndex index ); + inline void* operator[] ( ccIndex index ) { return at( index ); } + + virtual ccIndex indexOf( const void* item ); + + bool atFree( ccIndex index ); + bool atRemove( ccIndex index ); + bool atInsert( ccIndex index, void *item ); + bool atPut( ccIndex index, void *item ); + + void tide( void ); + virtual void remove( void *item ); + virtual void removeAll(); + virtual void free( void *item ); + virtual void freeAll(); + + virtual bool insert( void *item ); + + virtual void* firstThat( ccTestFunc Test, void* arg ); + virtual void* lastThat( ccTestFunc Test, void* arg ); + virtual void forEach( ccAppFunc action, void* arg ); + + void pack(); + virtual void setLimit( ccIndex aLimit ); + + inline ccIndex getCount() const { return count; } + inline ccIndex getLimit() const { return limit; } + inline ccIndex lastAccessed() const { return lastItem; } + +protected: uchar** items; + ccIndex count; + ccIndex limit; + ccIndex delta; + ccIndex lastItem; + + friend class HCollWriter; + + virtual void freeItem( void *item ); + virtual bool shiftItem( ccIndex pItem, int direction ); + +public: bool shouldDelete; + +}; + +#if !defined( __NO_TEMPLATES__ ) + template + struct Collection : public HCollection + { + + inline Collection( ccIndex aLimit = DEFAULT_COLL_SIZE, ccIndex aDelta = DEFAULT_COLL_DELTA ) : + HCollection( aLimit, aDelta ) + {} + + inline T* operator[] ( ccIndex i ) { return ( T* )at( i ); } + + inline void ForEach( void ( *pFunc )( T*, void* ), void* arg ) + { forEach(( ccAppFunc )pFunc, arg ); + } + + inline T* FirstThat( bool ( *Test )( T*, void* ), void* arg ) + { return ( T* )firstThat(( ccTestFunc )Test, arg ); + } + + inline T* LastThat( bool ( *Test )( T*, void* ), void* arg ) + { return ( T* )lastThat(( ccTestFunc )Test, arg ); + } + }; + + template + struct ObjCollection : public Collection + { + + inline ObjCollection( ccIndex aLimit = DEFAULT_COLL_SIZE, ccIndex aDelta = DEFAULT_COLL_DELTA ) : + Collection( aLimit, aDelta ) + {} + + virtual void freeItem( void* pItem ) + { delete ( T* )pItem; + } + }; + +#endif + +//============================================================================= +// HSortedCollection +//============================================================================= + +struct HSortedCollection: public HCollection +{ + HSortedCollection( ccIndex aLimit, ccIndex aDelta ); + + bool duplicates; + + virtual bool search( const void* key, ccIndex& index ); + + void* search ( const void* key ); + void* operator[]( const void* key ) { return search( key ); } + + virtual const void* keyOf( const void* item ) const; + + virtual ccIndex indexOf( const void* item ); + + virtual bool insert( void* item ); + +protected: + virtual int compare( const void* key1, const void* key2 ) const; +}; + + #if !defined( __NO_TEMPLATES__ ) + + template + struct SortedCollection : public HSortedCollection + { + + inline SortedCollection( ccIndex aLimit = DEFAULT_COLL_SIZE, ccIndex aDelta = DEFAULT_COLL_DELTA ) : + HSortedCollection( aLimit, aDelta ) + {} + + inline T* operator[] ( ccIndex i ) { return ( T* )at( i ); } + + inline T* Search( const void* p ) + { return ( T* )HSortedCollection::search( p ); + } + + inline void ForEach( void ( *pFunc )( T*, void* ), void* arg ) + { forEach(( ccAppFunc )pFunc, arg ); + } + + inline T* FirstThat( bool ( *Test )( T*, void* ), void* arg ) + { return ( T* )firstThat(( ccTestFunc )Test, arg ); + } + + inline T* LastThat( bool ( *Test )( T*, void* ), void* arg ) + { return ( T* )lastThat(( ccTestFunc )Test, arg ); + } + }; + +//============================================================================= + + template + struct ObjSortedCollection : public SortedCollection + { + + inline ObjSortedCollection( ccIndex aLimit = DEFAULT_COLL_SIZE, ccIndex aDelta = DEFAULT_COLL_DELTA ) : + SortedCollection( aLimit, aDelta ) + {} + + virtual void freeItem( void* pItem ) + { delete ( T* )pItem; + } + }; + + //========================================================================== + + template + int CompareItems( const CollItem*, const CollItem* ); + + template + struct FSortedCollection : public SortedCollection + { + + inline FSortedCollection( ccIndex aLimit = DEFAULT_COLL_SIZE, ccIndex aDelta = DEFAULT_COLL_DELTA ) : + SortedCollection( aLimit, aDelta ) + {} + + virtual int compare( const void* p1, const void* p2 ) const + { return CompareItems(( const T* )p1, ( const T* )p2 ); + } + }; + + //========================================================================== + + #define DEF_SRTCOLL( CLS ) \ + struct CLS##Coll : public SortedCollection { \ + inline CLS##Coll( ccIndex pLimit = DEFAULT_COLL_SIZE, ccIndex pDelta = DEFAULT_COLL_DELTA ) : \ + SortedCollection( pLimit, pDelta ) \ + {} + + + #define DEF_SRTCOLL_WITH_KEY( CLS, FLD ) \ + struct CLS##Coll : public SortedCollection { \ + inline CLS##Coll( ccIndex pLimit = DEFAULT_COLL_SIZE, ccIndex pDelta = DEFAULT_COLL_DELTA ) : \ + SortedCollection( pLimit, pDelta ) \ + {} \ + \ + virtual const void* keyOf( const void* pItem ) const \ + { return (( CLS* )pItem )->FLD; } \ + } + + #endif +#endif // __TCOLLECT_H + diff --git a/tools/MakeDef/h_object.h b/tools/MakeDef/h_object.h new file mode 100644 index 0000000000..d786c62031 --- /dev/null +++ b/tools/MakeDef/h_object.h @@ -0,0 +1,101 @@ + +#if !defined( __TOBJECT_H ) + #define __TOBJECT_H + + #if !defined( __TTYPES_H ) + #include "h_types.h" + #endif + +class HSmallAllocator; + +struct HRegisteredObject +{ + #if !defined( __NO_MEM_MANAGER__ ) + void* operator new( size_t sz, HSmallAllocator& A ); + void* operator new( size_t sz ); + void operator delete( void* ptr ); + #endif +}; + +struct HObject : public HRegisteredObject +{ + virtual ~HObject() {} +}; + +//====[ Ïóë äëÿ óñêîðåíèÿ âûäåëåíèé ìàëåíüêèõ êóñî÷êîâ ïàìÿòè ]================ + +struct HDataPage +{ + HDataPage* next; + size_t free; +}; + +class HSmallAllocator : public HRegisteredObject +{ + friend struct HSmallAllocatorObject; + friend struct HSmartSmallAllocatorObject; + +protected: size_t pageSize; + HDataPage* first; + + void* allocateSpace( size_t ); +public: + HSmallAllocator( size_t = 1024 ); + ~HSmallAllocator(); + + char* placeStr( const char* ); + void* placeData( const void*, size_t ); + + friend void* operator new( size_t, HSmallAllocator& ); + + virtual void tide(); +}; + +struct HStaticSmallAllocator : public HSmallAllocator +{ + HStaticSmallAllocator( size_t pPageSize ); + + virtual void tide(); +}; + +struct HSmallAllocatorObject +{ + void* operator new( size_t, HSmallAllocator& ); + void* operator new[]( size_t, HSmallAllocator& ); + + inline void operator delete( void* ) + {} + + inline void operator delete[]( void* ) + {} +}; + +struct HSmartSmallAllocatorObject : public HSmallAllocatorObject +{ + void* operator new( size_t, HSmallAllocator& ); + void* operator new[]( size_t, HSmallAllocator& ); +}; + +inline HSmallAllocator& ALLOCATOR( void* Obj ) + { + void** p = ( void** )Obj; + + return *( HSmallAllocator* )p[ -1 ]; + } + +//====[ Ðåàëèçàöèÿ èíëàéíîâûõ ìåòîäîâ HRegisteredObject ]====================== + + #if !defined( __NO_MEM_MANAGER__ ) + inline void* HRegisteredObject::operator new( size_t sz, HSmallAllocator& A ) + { return ::operator new( sz, A ); + } + + inline void* HRegisteredObject::operator new( size_t sz ) + { return HNEW( char, sz ); + } + + inline void HRegisteredObject::operator delete( void* ptr ) + { ::delete ptr ); + } + #endif +#endif diff --git a/tools/MakeDef/h_types.h b/tools/MakeDef/h_types.h new file mode 100644 index 0000000000..4e65cfbe0d --- /dev/null +++ b/tools/MakeDef/h_types.h @@ -0,0 +1,49 @@ +#if !defined( __TTYPES_H ) +#define __TTYPES_H + +#include + +#pragma warning( disable:4190 4200 4201 4250 4251 4275 4291 4512 4514 4705 4710 ) +#define __FLAT__ +#define __LITTLE_ENDIAN__ + +#define __EXPORT__ __declspec(dllexport) +#define __IMPORT__ __declspec(dllimport) + +#define DO_EXPORT( T ) __declspec(dllexport) T +#define DO_IMPORT( T ) __declspec(dllimport) T + +#define __BYTE_BOUNDARY__ pack( 1 ) +#define __RESTORE_BOUNDARY__ pack() + +#if !defined( __USHORT_T ) +#define __USHORT_T +typedef unsigned short ushort; +#endif + +#if !defined( __UCHAR_T ) +#define __UCHAR_T +typedef unsigned char uchar; +#endif + +#if !defined( __UINT_T ) +#define __UINT_T +typedef unsigned int uint; +#endif + +#if !defined( __ULONG_T ) +#define __ULONG_T +typedef unsigned long ulong; +#endif + +#if !defined( EOS ) +#define EOS '\0' +#endif + +#if defined( __FLAT__ ) + #define maxCollectionSize 1000000000 +#else + #define maxCollectionSize 16384 +#endif + +#endif // __TTYPES_H diff --git a/tools/MakeDef/h_util.h b/tools/MakeDef/h_util.h new file mode 100644 index 0000000000..8f3862000c --- /dev/null +++ b/tools/MakeDef/h_util.h @@ -0,0 +1,50 @@ +#if !defined( __UTIL_H ) + #define __UTIL_H + + #if !defined( __STDARG_H ) + #include + #define __STDARG_H + #endif + + #if !defined( __TTYPES_H ) + #include "h_types.h" + #endif + +//-------------------------- Useful functions ---------------------------- + +char* copyString( char* dest, char* src, size_t size ); + +char* centerStr( char *dest, const char *src, size_t len ); +char* rightJust( char *string, size_t size ); +char* leftJust ( char *string, size_t size ); + +char* strToUpper( char* ); +char* strToLower( char* ); + +uchar charToUpper( uchar ); +uchar charToLower( uchar ); + +char* ltrim(char*); +char* rtrim(char*); +char* strdel(char*, size_t); +char* trim(char*); +char* newStr(const char*); +void placeString(char* pDest, char* pSrc, size_t pLen); + +bool fileExists(char* fileName); + +char* replaceExt(const char* fileName, char* ext, char* buffer); +int shareFile(const char* fileName, bool ifRead, bool ifWrite); + +//----------------- Ôóíêöèè äëÿ ðàáîòû ñ ðàñøèðåííûìè ñòðîêàìè ---------------- + +int cstrlen(const char *); +size_t getStrNumber(char* sText); +size_t getStrLength(char* sText); +char* xstrncpy(char* dest, const char* src, size_t iLen); + +long CRC32(uchar*, size_t); + +#define FIELD_DELTA( CLS, FLD ) (( int )( (( char* )( &(( CLS* )1 )->FLD )) - (( char* )( CLS* )1 ))) + +#endif // __UTIL_H diff --git a/tools/MakeDef/lib_str.cpp b/tools/MakeDef/lib_str.cpp new file mode 100644 index 0000000000..786ce44571 --- /dev/null +++ b/tools/MakeDef/lib_str.cpp @@ -0,0 +1,113 @@ +#include + +#include "h_util.h" + +void placeString(char* pDest, char* pSrc, size_t pLen) +{ + size_t tLen = strlen(pSrc); + if (tLen < pLen) + strcpy(pDest, pSrc); + else { + memcpy(pDest, pSrc, pLen); + pDest[pLen] = EOS; + } +} + +//================================================================================ + +char* rtrim(char *string) +{ + if (string == 0) + return 0; + + char* p = string + strlen(string) - 1; + + while (p >= string) { + if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') + *p-- = 0; + else + break; + } + return string; +} + +char* ltrim(char* string) +{ + if (string == 0) + return 0; + + char* p; + + for (p = string; *p && (*p == ' ' || *p == '\t' || *p == '\n'); p++) + *p = 0; + + return p; +} + +char* trim(char* string) +{ + return ltrim(rtrim(string)); +} + +char* strdel(char* string, size_t len) +{ + size_t slen = strlen(string); + if (len > slen) + len = slen; + + char* tempstr = newStr(string + len); + char* p = strcpy(string, tempstr); + delete tempstr; + return p; +} + +//================================================================================ + +char* rightJust(char *string, size_t l) +{ + size_t p = strlen(string) - 1; + char* s = &(string[p]); + + while (*s == ' ' && p >= 0) { s--; p--; } + p++; + + string[l] = 0; + memmove(string + l - p, string, p); + memset(string, ' ', l - p); + + return string; +} + +char* leftJust(char *string, size_t l) +{ + char* s = string; + size_t p = 0; + + while (*s == ' ' && p < l) { s++; p++; } + + strncpy(string, s, l - p + 1); + + return string; +} + +const size_t maxCenterStrLen = 256; + +char* centerStr(char* dst, const char* src, size_t len) +{ + size_t l = strlen(src); + if (l > maxCenterStrLen) + return strcpy(dst, src); + + char str[maxCenterStrLen + 1]; + char* tmpPtr = trim(strcpy(str, src)); + size_t sLen = strlen(tmpPtr); + + if (sLen < len && len != 0) { + memset(dst, ' ', len); + memcpy(dst + (len - sLen) / 2, tmpPtr, sLen); + } + else memcpy(dst, tmpPtr, sLen); + + dst[len] = 0; + return dst; +} diff --git a/tools/MakeDef/newstr.cpp b/tools/MakeDef/newstr.cpp new file mode 100644 index 0000000000..557ea17038 --- /dev/null +++ b/tools/MakeDef/newstr.cpp @@ -0,0 +1,8 @@ +#include + +#include "h_util.h" + +char* newStr( const char* s ) +{ + return (s == NULL) ? NULL : strcpy(new char[strlen(s) + 1], s); +} diff --git a/tools/MakeDef/tcollect.cpp b/tools/MakeDef/tcollect.cpp new file mode 100644 index 0000000000..b3c531ea2b --- /dev/null +++ b/tools/MakeDef/tcollect.cpp @@ -0,0 +1,221 @@ +#include +#include + +#include "h_collection.h" + +HCollection::HCollection(ccIndex aLimit, ccIndex aDelta) : + count(0), + limit(0), + items(NULL), + delta(aDelta), + shouldDelete(false), + lastItem(-1) +{ + setLimit(aLimit); +} + +HCollection::~HCollection() +{ + if (shouldDelete) + freeAll(); + + delete items; +} + +void* HCollection::at(ccIndex pIndex) +{ + if (pIndex < 0 || pIndex >= count) + return NULL; + + lastItem = pIndex; + return items[pIndex]; +} + +bool HCollection::atFree(ccIndex pIndex) +{ + void* item = at(pIndex); + if (!atRemove(pIndex)) + return false; + + freeItem(item); + return true; +} + +bool HCollection::atInsert(ccIndex pIndex, void* item) +{ + if (pIndex < 0) + return false; + + if (count == limit) { + if (delta == 0) + return false; + + setLimit(count + delta); + } + + if (pIndex < count) + shiftItem(pIndex, 1); + + count++; + + items[pIndex] = (uchar*)item; + lastItem = pIndex; + return true; +} + +bool HCollection::atPut(ccIndex pIndex, void* item) +{ + if (pIndex >= count) return false; + + items[pIndex] = (uchar*)item; + return true; +} + +bool HCollection::atRemove(ccIndex pIndex) +{ + if (pIndex < 0 || pIndex >= count) + return false; + + count--; + if (count > pIndex) + shiftItem(pIndex, -1); + + lastItem = pIndex; + return true; +} + +void HCollection::remove(void* item) +{ + atRemove(indexOf(item)); +} + +void HCollection::removeAll() +{ + count = 0; +} + +void* HCollection::firstThat(ccTestFunc Test, void* arg) +{ + for (ccIndex i = 0; i < count; i++) + if (Test(items[i], arg) == true) { + lastItem = i; + return items[i]; + } + + return NULL; +} + +void* HCollection::lastThat(ccTestFunc Test, void* arg) +{ + for (ccIndex i = count - 1; i >= 0; i--) + if (Test(items[i], arg) == true) { + lastItem = i; + return items[i]; + } + + return NULL; +} + +void HCollection::forEach(ccAppFunc action, void* arg) +{ + for (ccIndex i = 0; i < count; i++) + action(items[i], arg); + + lastItem = count - 1; +} + +void HCollection::free(void* item) +{ + remove(item); + freeItem(item); +} + +void HCollection::freeAll() +{ + for (ccIndex i = 0; i < count; i++) + freeItem(at(i)); + + count = 0; +} + +void HCollection::freeItem(void* item) +{ + delete item; +} + +ccIndex HCollection::indexOf(const void* item) +{ + for (ccIndex i = 0; i < count; i++) + if (item == items[i]) + return i; + + return -1; +} + +bool HCollection::insert(void* item) +{ + return atInsert(count, item); +} + +void HCollection::pack() +{ + uchar** curDst = items; + uchar** curSrc = items; + uchar** last = items + count; + + while (curSrc < last) { + if (*curSrc != 0) + *curDst++ = *curSrc; + *curSrc++; + } +} + +void HCollection::setLimit(ccIndex aLimit) +{ + if (aLimit < count) + aLimit = count; + + if (aLimit > maxCollectionSize) + aLimit = maxCollectionSize; + + if (aLimit != limit) { + uchar** aItems; + + if (aLimit == 0) aItems = NULL; + else { + aItems = new uchar*[aLimit]; + if (count != 0 && aItems != NULL && items != NULL) + memcpy(aItems, items, count* sizeof(void*)); + } + + delete items; + items = aItems; + limit = aLimit; + } +} + +bool HCollection::shiftItem(ccIndex pItemNo, int direction) +{ + if (items == NULL || pItemNo >= limit) + return false; + + switch (direction) { + case 1: // Ðàçäâèíóòü ìàññèâ íà îäèí ýëåìåíò + memmove(items + pItemNo + 1, items + pItemNo, sizeof(void*)*(count - pItemNo)); + items[pItemNo] = NULL; + return true; + + case -1: // Ñäâèíóòü ìàññèâ íà îäèí ýëåìåíò + memmove(items + pItemNo, items + pItemNo + 1, sizeof(void*)*(count - pItemNo)); + items[count] = NULL; + return true; + + default: return false; + } +} + +void HCollection::tide() +{ + delete items; items = NULL; + count = 0; +} diff --git a/tools/MakeDef/tnsrtcol.cpp b/tools/MakeDef/tnsrtcol.cpp new file mode 100644 index 0000000000..b614f8388b --- /dev/null +++ b/tools/MakeDef/tnsrtcol.cpp @@ -0,0 +1,78 @@ +#include +#include + +#include "h_collection.h" + +HSortedCollection::HSortedCollection( ccIndex aLimit, ccIndex aDelta ) : + HCollection( aLimit, aDelta ), + duplicates( false ) +{ +} + +int HSortedCollection::compare( const void *key1, const void *key2 ) const +{ + return strcmp(( const char* )key1, ( const char* )key2 ); +} + +ccIndex HSortedCollection::indexOf( const void *item ) +{ + ccIndex i; + + if ( search( keyOf( item ), i ) == false ) + return ccNotFound; + + if ( duplicates ) + while( i < count && item != items[i] ) + i++; + + return ( i < count ) ? i : ccNotFound; +} + +bool HSortedCollection::insert( void* item ) +{ + ccIndex i; + if ( search( keyOf( item ), i ) == 0 || duplicates ) + return atInsert( i, item ); + + return false; +} + +const void* HSortedCollection::keyOf( const void* item ) const +{ + return item; +} + +void* HSortedCollection::search( const void* key ) +{ + ccIndex temp; + + if ( search( key, temp ) == false ) + return 0; + + return items[ temp ]; +} + +bool HSortedCollection::search( const void* key, ccIndex& index ) +{ + ccIndex l = 0; + ccIndex h = count - 1; + bool res = false; + + while( l <= h ) + { ccIndex i = ( l+h )/2; + + int c = compare( keyOf( items[ i ] ), key ); + if ( c < 0 ) + l = i + 1; + else + { h = i - 1; + if ( c == 0 ) + { res = true; + lastItem = i; + if ( !duplicates ) + l = i; + } } } + + index = l; + return res; +} diff --git a/tools/MakeDef/tsmall.cpp b/tools/MakeDef/tsmall.cpp new file mode 100644 index 0000000000..7fac553572 --- /dev/null +++ b/tools/MakeDef/tsmall.cpp @@ -0,0 +1,155 @@ +#include +#include + +#include "h_object.h" +#include "h_util.h" + +HStaticSmallAllocator::HStaticSmallAllocator(size_t aPageSize) : + HSmallAllocator(aPageSize) +{ + char* tData = new char[sizeof(HDataPage) + aPageSize]; + + first = (HDataPage*)tData; + first->free = aPageSize; + first->next = NULL; +} + +void HStaticSmallAllocator::tide() +{ + HDataPage* p1; + + for (HDataPage* p = first->next; p != NULL; p = p1) { + p1 = p->next; + delete p; + } + + memset(&first->next, 0, pageSize + sizeof(void*)); + + first->free = pageSize; + first->next = NULL; +} + +//====[ HSmallAllocator ]====================================================== + +HSmallAllocator::HSmallAllocator(size_t aPageSize) : + first(NULL), + pageSize(aPageSize) +{} + +HSmallAllocator::~HSmallAllocator() +{ + tide(); +} + +char* HSmallAllocator::placeStr(const char* str) +{ + if (str == NULL) + str = ""; + + size_t len = strlen(str) + 1; + + void* p = allocateSpace(len); + if (p == NULL) + return NULL; + + memcpy(p, str, len); + return (char*)p; +} + +void* HSmallAllocator::placeData(const void* data, size_t len) +{ + void* p = allocateSpace(len); + if (p == NULL) + return NULL; + + if (data != NULL) + memcpy(p, data, len); + + return p; +} + +void* HSmallAllocator::allocateSpace(size_t bytes) +{ + HDataPage* p; + + if (bytes > pageSize) { + size_t dataLen = sizeof(HDataPage) + bytes; + char* data = new char[dataLen]; + memset(data, 0, dataLen); + + if (first == NULL) + first = (HDataPage*)data; + else { + for (p = first; p->next != NULL; p = p->next) + ; + + p->next = (HDataPage*)data; + } + + return data + sizeof(HDataPage); + } + + for (p = first; p != NULL; p = p->next) + if (p->free >= bytes) + break; + + if (p == NULL || p->free < bytes) { + size_t dataLen = sizeof(HDataPage) + pageSize; + char* data = new char[dataLen]; + memset(data, 0, dataLen); + + p = (HDataPage*)data; + p->free = pageSize; + + p->next = first; + first = p; + } + + char* res = (char*)(p + 1) + pageSize - p->free; p->free -= bytes; + return res; +} + +void HSmallAllocator::tide() +{ + HDataPage* p1; + + for (HDataPage* p = first; p != 0; p = p1) { + p1 = p->next; + delete p; + } + + first = NULL; +} + +//============================================================================= + +void* operator new(size_t bytes, HSmallAllocator& owner) +{ + return owner.allocateSpace(bytes); +} + +//============================================================================= + +void* HSmallAllocatorObject::operator new(size_t bytes, HSmallAllocator& owner) +{ + return owner.allocateSpace(bytes); +} + +void* HSmallAllocatorObject::operator new[](size_t bytes, HSmallAllocator& owner) { + return owner.allocateSpace(bytes); +} + +//============================================================================= + +void* HSmartSmallAllocatorObject::operator new(size_t bytes, HSmallAllocator& owner) +{ + char* result = (char*)owner.allocateSpace(bytes + sizeof(void*)); + *(HSmallAllocator**)result = &owner; + return result + sizeof(void*); +} + +void* HSmartSmallAllocatorObject::operator new[](size_t bytes, HSmallAllocator& owner) { + char* result = (char*)owner.allocateSpace(bytes + sizeof(void*)); + *(HSmallAllocator**)result = &owner; + return result + sizeof(void*); +} -- cgit v1.2.3