/*
    gendef - Generate list of exported symbols from a Portable Executable.
    Copyright (C) 2009, 2010, 2011, 2012, 2013  mingw-w64 project

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include "compat_string.h"
#include "gendef.h"

typedef struct sImpDef {
  struct sImpDef *next;
  char *name;
  char *data;
  size_t length;
} sImpDef;

static sImpDef *theImpDef = NULL;

typedef struct sDefPaths {
  struct sDefPaths *next;
  char path[1];
} sDefPaths;

static sDefPaths *thePathDefs;

static int find_path_def (const char *path);
static int add_path_def (const char *path);

static sImpDef *is_def_loaded (const char *);
static sImpDef *gendef_loaddef (const char *);
static FILE *fopen_def (const char *name);
static uint32_t get_uint32_by_str (const char *txt);

int
gendef_getsymbol_info (const char *dllname, const char *symbolname, int *isData, uint32_t *at)
{
  char *r1 = NULL, *r2 = NULL, *def;
  sImpDef *id;
  size_t symlen;
  int ret = 0;

  if (!dllname)
    return 0;
  if (!symbolname || *symbolname == 0)
    {
      char *h = strchr (dllname, '.');
      if (!h)
	return 0;
      r1 = strdup (h + 1);
      if (*r1 == '#')
	{
	  r2 = (char *) malloc (strlen (r1) + 5);
	  sprintf (r2, "ord_%s", r1 + 1);
	  free (r1);
	  r1 = r2;
	}
      symbolname = r1;
      r2 = (char *) malloc (strlen (dllname) + 5);
      strcpy (r2, dllname);
      strcpy (strchr (r2, '.'), ".dll");
      dllname = r2;
    }
  def = (char *) malloc (strlen (dllname) + 5);
  strcpy (def, dllname);
  strlwr (def);
  if (strchr (def, '.') == NULL)
    strcat (def, ".def");
  else
    strcpy (strchr (def, '.'), ".def");
  symlen = strlen (symbolname);
  id = gendef_loaddef (def);
  if (id)
    {
      char *t = id->data;
      while (t != NULL && *t != 0)
	{
	  t = strchr (t, '\n');
	  if (t)
	    t++;
	  if (t && strncmp (t, symbolname, symlen) == 0)
	    {
	      if ((t[symlen] > 0 && t[symlen] <= 0x20) || t[symlen] == '@')
		{
		  t += symlen + 1;
		  *at = get_uint32_by_str (t);
		  while (*t != 0 && *t != '\n')
		    {
		      if (!strncmp (t, "DATA", 4))
			{
			  *isData = 1;
			  break;
			}
		      t++;
		    }
		  ret = 1;
		  break;
		}

	    }
	}
    }
  if (def)
    free (def);
  if (r2 != NULL && r1 != r2)
    free (r2);
  if (r1 != NULL)
    free (r1);
  return ret;
}

static FILE *
fopen_def (const char *name)
{
  sDefPaths *l = thePathDefs;
  FILE *fp;
  if ((fp = fopen (name, "rb")) != NULL)
    return fp;
  while (l != NULL)
    {
      char *h = (char *) malloc (strlen (name) + strlen (l->path) + 1);
      if (h)
	{
	  strcpy (h, l->path);
	  strcat (h, name);
	  fp = fopen (h, "rb");
	  free (h);
	  if (fp)
	    return fp;
	}
      l = l->next;
    }
  return NULL;
}

static sImpDef *
gendef_loaddef (const char *name)
{
  sImpDef *n;
  FILE *fp;
  char *lname;
  size_t len;
  char *txt;
  if (!name || *name == 0)
    return NULL;
  lname = strdup (name);
  if (!lname)
    return NULL;
  strlwr (lname);
  n = is_def_loaded (lname);
  if (n)
    {
      free (lname);
      return n;
    }
  fp = fopen_def (name);
  if (!fp)
    {
      free (lname);
      return NULL;
    }
  fseek (fp, 0, SEEK_END);
  len = (size_t) ftell (fp);
  fseek (fp, 0, SEEK_SET);
  txt = (char *) malloc (len + 1);
  if (!txt)
    {
      fclose (fp);
      free (lname);
      return NULL;
    }
  if ((size_t) fread (txt, 1, len, fp) != len)
    {
      fclose (fp);
      free (lname);
      free (txt);
      return NULL;
    }
  fclose (fp);
  txt[len] = 0;

  n = (sImpDef *) malloc (sizeof (sImpDef));
  if (!n)
    {
      free (lname);
      free (txt);
      return NULL;
    }
  memset (n, 0, sizeof (sImpDef));
  n->name = lname;
  n->data = txt;
  n->length = len;
  n->next = theImpDef;
  theImpDef = n;
  return n;
}

static sImpDef *
is_def_loaded (const char *dname)
{
  sImpDef *h = theImpDef;
  while (h != NULL)
    {
      if (!strcasecmp (h->name, dname))
	break;
      h = h->next;
    }
  return h;
}

static uint32_t
get_uint32_by_str (const char *txt)
{
  uint32_t ret = 0;
  while (*txt != 0 && *txt >= '0' && *txt <= '9')
    {
      ret *= 10;
      ret += (uint32_t) (txt[0] - '0');
      ++txt;
    }
  return ret;
}

int
gendef_addpath_def (const char *path)
{
  if (find_path_def (path))
    return 1;
  return add_path_def (path);
}

static int
find_path_def (const char *path)
{
  char *h, *p;
  sDefPaths *l = thePathDefs;
  if (!l)
    return 0;
  h = (char *) malloc (strlen (path) + 2);
  if (!h)
    return 0;
  strcpy (h, path);
  for (p = h; *p != 0; p++)
    if (p[0] == '\\')
      p[0] = '/';
  if (p != h && p[-1] != '/')
    strcat (p, "/");
  while (l != NULL)
    {
      if (!strcmp (l->path, h))
        {
	  free (h);
	  return 1;
        }
      l = l->next;
    }
  free (h);
  return 0;
}

static int
add_path_def (const char *path)
{
  char *h, *p;
  sDefPaths *l;
  h = (char *) malloc (strlen (path) + 2);
  if (!h)
    return 0;
  strcpy (h, path);
  for (p = h; *p != 0; p++)
    if (p[0] == '\\')
      p[0] = '/';
  if (p != h && p[-1] != '/')
    strcat (p, "/");
  l = (sDefPaths *) malloc (sizeof (sDefPaths) + strlen (h) + 1);
  if (!l)
    {
      free (h);
      return 0;
    }
  memset (l, 0, sizeof (sDefPaths));
  strcpy (l->path, h);
  free (h);
  l->next = thePathDefs;
  thePathDefs = l;
  return 1;
}

