diff dynload/dynload_syms_pe.c @ 0:3e629dc19168

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:24:28 +0100
parents
children 6c7591cef6a8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dynload/dynload_syms_pe.c	Thu Mar 19 22:24:28 2015 +0100
@@ -0,0 +1,110 @@
+/*
+
+ Package: dyncall
+ Library: dynload
+ File: dynload/dynload_syms_pe.c
+ Description: 
+ License:
+
+   Copyright (c) 2007-2015 Daniel Adler <dadler@uni-goettingen.de>, 
+                           Tassilo Philipp <tphilipp@potion-studios.com>
+                           Olivier Chafik <olivier.chafik@gmail.com>
+
+   Permission to use, copy, modify, and distribute this software for any
+   purpose with or without fee is hereby granted, provided that the above
+   copyright notice and this permission notice appear in all copies.
+
+   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+*/
+
+
+
+#include "dynload.h"
+#include "dynload_alloc.h"
+
+#include <windows.h>
+
+struct DLLib_
+{
+  IMAGE_DOS_HEADER dos_header;
+};
+
+
+struct DLSyms_
+{
+  DLLib*                pLib;
+  const char*           pBase;
+  const DWORD*          pNames;
+  const DWORD*          pFuncs;
+  const unsigned short* pOrds;
+  size_t                count;
+};
+
+
+DLSyms* dlSymsInit(const char* libPath)
+{
+  DLLib* pLib = dlLoadLibrary(libPath);
+  DLSyms* pSyms = (DLSyms*)dlAllocMem(sizeof(DLSyms));
+  const char* base = (const char*) pLib;
+  IMAGE_DOS_HEADER*       pDOSHeader      = (IMAGE_DOS_HEADER*) base;  
+  IMAGE_NT_HEADERS*       pNTHeader       = (IMAGE_NT_HEADERS*) ( base + pDOSHeader->e_lfanew );  
+  IMAGE_DATA_DIRECTORY*   pExportsDataDir = &pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
+  IMAGE_EXPORT_DIRECTORY* pExports        = (IMAGE_EXPORT_DIRECTORY*) (base + pExportsDataDir->VirtualAddress);  
+
+  pSyms->pBase  = base;
+  pSyms->pNames = (DWORD*)(base + pExports->AddressOfNames);
+  pSyms->pFuncs = (DWORD*)(base + pExports->AddressOfFunctions);
+  pSyms->pOrds  = (unsigned short*)(base + pExports->AddressOfNameOrdinals);
+  pSyms->count  = (size_t)pExports->NumberOfNames;
+  pSyms->pLib   = pLib;
+
+  return pSyms;
+}
+
+
+void dlSymsCleanup(DLSyms* pSyms)
+{
+  if(pSyms) {
+    dlFreeLibrary(pSyms->pLib);
+    dlFreeMem(pSyms);
+  }
+}
+
+
+int dlSymsCount(DLSyms* pSyms)
+{
+  return (int)pSyms->count;
+}
+
+
+const char* dlSymsName(DLSyms* pSyms, int index)
+{
+  return (const char*)((const char*)pSyms->pBase + pSyms->pNames[index]);
+}
+
+
+void* dlSymsValue(DLSyms* pSyms, int index)
+{
+  return (void*)(pSyms->pBase + pSyms->pFuncs[pSyms->pOrds[index]]);
+}
+
+
+const char* dlSymsNameFromValue(DLSyms* pSyms, void* value) 
+{
+  int i, c=dlSymsCount(pSyms);
+  for(i=0; i<c; ++i)
+  {
+    if(dlSymsValue(pSyms, i) == value)
+      return dlSymsName(pSyms, i);
+  }
+
+  /* Not found. */
+  return NULL;
+}