This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch: delay import for dlltool


Hi,

I have created a patch for dlltool that implements delay loading dlls.
It creates import stubs in a similar way to how it's done with normal
imports.
It's only implemented for x86 so far, but the implementation allows easy
porting.

The resulting application will link to __delayLoadHelper2, which I also
implemented as a library. It's compatible to ms __delayLoadHelper2.
I have attached the patch and the library as reference.

Let me know if something is missing.

btw, I have just send back the assignment from FSF, will probably take a
several days (I'm from Germany)

Regards,
Timo

Index: dlltool.c
===================================================================
--- dlltool.c	(Revision 6)
+++ dlltool.c	(Arbeitskopie)
@@ -352,6 +352,7 @@
 static int no_idata5;
 static char *exp_name;
 static char *imp_name;
+static char *delayimp_name;
 static char *identify_imp_name;
 static bfd_boolean identify_strict;
 
@@ -499,6 +500,13 @@
   0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
 };
 
+static const unsigned char i386_dljtab[] =
+{
+  0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp __imp__function
+  0xB8, 0x00, 0x00, 0x00, 0x00,       // mov eax, offset __imp__function
+  0xE9, 0x00, 0x00, 0x00, 0x00        // jmp __tailMerge__dllname
+};
+
 static const unsigned char arm_jtab[] =
 {
   0x00, 0xc0, 0x9f, 0xe5,	/* ldr  ip, [pc] */
@@ -565,6 +573,16 @@
 static bfd_vma ppc_glue_insn = 0x80410004;
 #endif
 
+static const char i386_trampoline[] =  
+  "\tpushl %%ecx\n"
+  "\tpushl %%edx\n"
+  "\tpushl %%eax\n"
+  "\tpushl $__DELAY_IMPORT_DESCRIPTOR_%s\n"
+  "\tcall ___delayLoadHelper2@8\n"
+  "\tpopl %%edx\n"
+  "\tpopl %%ecx\n"
+  "\tjmp *%%eax\n";
+
 struct mac
   {
     const char *type;
@@ -584,6 +602,12 @@
     const unsigned char *how_jtab;
     int how_jtab_size; /* Size of the jtab entry.  */
     int how_jtab_roff; /* Offset into it for the ind 32 reloc into idata 5.  */
+    const unsigned char *how_dljtab;
+    int how_dljtab_size; /* Size of the jtab entry.  */
+    int how_dljtab_roff1; /* Offset into it for the ind 32 reloc into idata 5.  */
+    int how_dljtab_roff2; /* Offset into it for the ind 32 reloc into idata 5.  */
+    int how_dljtab_roff3; /* Offset into it for the ind 32 reloc into idata 5.  */
+    const char *trampoline;
   };
 
 static const struct mac
@@ -595,7 +619,8 @@
     "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
     ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
     "pe-arm-little", bfd_arch_arm,
-    arm_jtab, sizeof (arm_jtab), 8
+    arm_jtab, sizeof (arm_jtab), 8,
+    0, 0, 0, 0, 0, 0
   }
   ,
   {
@@ -603,7 +628,8 @@
     "i386", ".byte", ".short", ".long", ".asciz", "#",
     "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
     "pe-i386",bfd_arch_i386,
-    i386_jtab, sizeof (i386_jtab), 2
+    i386_jtab, sizeof (i386_jtab), 2,
+    i386_dljtab, sizeof (i386_dljtab), 2, 7, 12, i386_trampoline
   }
   ,
   {
@@ -611,7 +637,8 @@
     "ppc", ".byte", ".short", ".long", ".asciz", "#",
     "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
     "pe-powerpcle",bfd_arch_powerpc,
-    ppc_jtab, sizeof (ppc_jtab), 0
+    ppc_jtab, sizeof (ppc_jtab), 0,
+    0, 0, 0, 0, 0, 0
   }
   ,
   {
@@ -620,7 +647,8 @@
     "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
     ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
     "pe-arm-little", bfd_arch_arm,
-    thumb_jtab, sizeof (thumb_jtab), 12
+    thumb_jtab, sizeof (thumb_jtab), 12,
+    0, 0, 0, 0, 0, 0
   }
   ,
 #define MARM_INTERWORK 4
@@ -629,7 +657,8 @@
     "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
     ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
     "pe-arm-little", bfd_arch_arm,
-    arm_interwork_jtab, sizeof (arm_interwork_jtab), 12
+    arm_interwork_jtab, sizeof (arm_interwork_jtab), 12,
+    0, 0, 0, 0, 0, 0
   }
   ,
   {
@@ -638,7 +667,8 @@
     "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
     ".global", ".space", ".align\t2",".align\t4", "",
     "pe-mcore-big", bfd_arch_mcore,
-    mcore_be_jtab, sizeof (mcore_be_jtab), 8
+    mcore_be_jtab, sizeof (mcore_be_jtab), 8,
+    0, 0, 0, 0, 0, 0
   }
   ,
   {
@@ -647,7 +677,8 @@
     "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
     ".global", ".space", ".align\t2",".align\t4", "-EL",
     "pe-mcore-little", bfd_arch_mcore,
-    mcore_le_jtab, sizeof (mcore_le_jtab), 8
+    mcore_le_jtab, sizeof (mcore_le_jtab), 8,
+    0, 0, 0, 0, 0, 0
   }
   ,
   {
@@ -656,7 +687,8 @@
     "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
     ".global", ".space", ".align\t2",".align\t4", "",
     "elf32-mcore-big", bfd_arch_mcore,
-    mcore_be_jtab, sizeof (mcore_be_jtab), 8
+    mcore_be_jtab, sizeof (mcore_be_jtab), 8,
+    0, 0, 0, 0, 0, 0
   }
   ,
   {
@@ -665,7 +697,8 @@
     "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
     ".global", ".space", ".align\t2",".align\t4", "-EL",
     "elf32-mcore-little", bfd_arch_mcore,
-    mcore_le_jtab, sizeof (mcore_le_jtab), 8
+    mcore_le_jtab, sizeof (mcore_le_jtab), 8,
+    0, 0, 0, 0, 0, 0
   }
   ,
   {
@@ -674,7 +707,8 @@
     "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
     ".global", ".space", ".align\t2",".align\t4", "",
     "epoc-pe-arm-little", bfd_arch_arm,
-    arm_jtab, sizeof (arm_jtab), 8
+    arm_jtab, sizeof (arm_jtab), 8,
+    0, 0, 0, 0, 0, 0
   }
   ,
   {
@@ -683,7 +717,8 @@
     "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
     ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
     "pe-arm-wince-little", bfd_arch_arm,
-    arm_jtab, sizeof (arm_jtab), 8
+    arm_jtab, sizeof (arm_jtab), 8,
+    0, 0, 0, 0, 0, 0
   }
   ,
   {
@@ -691,10 +726,11 @@
     "i386:x86-64", ".byte", ".short", ".long", ".asciz", "#",
     "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
     "pe-x86-64",bfd_arch_i386,
-    i386_jtab, sizeof (i386_jtab), 2
+    i386_jtab, sizeof (i386_jtab), 2,
+    i386_dljtab, sizeof (i386_dljtab), 2, 7, 12, i386_trampoline
   }
   ,
-  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
 };
 
 typedef struct dlist
@@ -756,10 +792,11 @@
 static const char *xlate (const char *);
 static char *make_label (const char *, const char *);
 static char *make_imp_label (const char *, const char *);
-static bfd *make_one_lib_file (export_type *, int);
+static bfd *make_one_lib_file (export_type *, int, int);
 static bfd *make_head (void);
 static bfd *make_tail (void);
-static void gen_lib_file (void);
+static bfd *make_delay_head (void);
+static void gen_lib_file (int);
 static void dll_name_list_append (dll_name_list_type *, bfd_byte *);
 static int  dll_name_list_count (dll_name_list_type *);
 static void dll_name_list_print (dll_name_list_type *);
@@ -923,9 +960,11 @@
 #define HOW_BFD_READ_TARGET	0  /* Always default.  */
 #define HOW_BFD_WRITE_TARGET	mtable[machine].how_bfd_target
 #define HOW_BFD_ARCH		mtable[machine].how_bfd_arch
-#define HOW_JTAB		mtable[machine].how_jtab
-#define HOW_JTAB_SIZE		mtable[machine].how_jtab_size
-#define HOW_JTAB_ROFF		mtable[machine].how_jtab_roff
+#define HOW_JTAB		(delay ? mtable[machine].how_dljtab : mtable[machine].how_jtab)
+#define HOW_JTAB_SIZE		(delay ? mtable[machine].how_dljtab_size : mtable[machine].how_jtab_size)
+#define HOW_JTAB_ROFF		(delay ? mtable[machine].how_dljtab_roff1 : mtable[machine].how_jtab_roff)
+#define HOW_JTAB_ROFF2		(delay ? mtable[machine].how_dljtab_roff2 : 0)
+#define HOW_JTAB_ROFF3		(delay ? mtable[machine].how_dljtab_roff3 : 0)
 #define ASM_SWITCHES		mtable[machine].how_default_as_switches
 
 static char **oav;
@@ -2296,7 +2335,7 @@
 }
 
 static bfd *
-make_one_lib_file (export_type *exp, int i)
+make_one_lib_file (export_type *exp, int i, int delay)
 {
   bfd *      abfd;
   asymbol *  exp_label;
@@ -2462,7 +2501,7 @@
     {
       sinfo *si = secdata + i;
       asection *sec = si->sec;
-      arelent *rel;
+      arelent *rel, *rel2 = 0, *rel3 = 0;
       arelent **rpp;
 
       switch (i)
@@ -2477,13 +2516,26 @@
 	      /* Add the reloc into idata$5.  */
 	      rel = xmalloc (sizeof (arelent));
 
-	      rpp = xmalloc (sizeof (arelent *) * 2);
+	      rpp = xmalloc (sizeof (arelent *) * (delay ? 4 : 2));
 	      rpp[0] = rel;
 	      rpp[1] = 0;
 
 	      rel->address = HOW_JTAB_ROFF;
 	      rel->addend = 0;
 
+	      if (delay)
+	        {
+	          rel2 = xmalloc (sizeof (arelent));
+	          rpp[1] = rel2;
+	          rel2->address = HOW_JTAB_ROFF2;
+	          rel2->addend = 0;
+	          rel3 = xmalloc (sizeof (arelent));
+	          rpp[2] = rel3;
+	          rel3->address = HOW_JTAB_ROFF3;
+	          rel3->addend = 0;
+	          rpp[3] = 0;
+	        }
+
 	      if (machine == MPPC)
 		{
 		  rel->howto = bfd_reloc_type_lookup (abfd,
@@ -2501,12 +2553,41 @@
 		  rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
 		  rel->sym_ptr_ptr = secdata[IDATA5].sympp;
 		}
+
+	      if (delay)
+	        {
+	          rel2->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
+	          rel2->sym_ptr_ptr = rel->sym_ptr_ptr;
+	          rel3->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32_PCREL);
+	          rel3->sym_ptr_ptr = iname_lab_pp;
+	        }
+
 	      sec->orelocation = rpp;
+	      sec->reloc_count = delay ? 3 : 1;
+	    }
+	  break;
+
+	case IDATA5:
+	  if (delay)
+	    {
+	      si->data = xmalloc (4);
+	      si->size = 4;
 	      sec->reloc_count = 1;
+	      memset (si->data, 0, si->size);
+	      si->data[0] = 6;
+	      rel = xmalloc (sizeof (arelent));
+	      rpp = xmalloc (sizeof (arelent *) * 2);
+	      rpp[0] = rel;
+	      rpp[1] = 0;
+	      rel->address = 0;
+	      rel->addend = 0;
+	      rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
+	      rel->sym_ptr_ptr = secdata[TEXT].sympp;
+	      sec->orelocation = rpp;
+	      break;
 	    }
-	  break;
+	  /* else fall through */
 	case IDATA4:
-	case IDATA5:
 	  /* An idata$4 or idata$5 is one word long, and has an
 	     rva to idata$6.  */
 
@@ -2584,6 +2665,7 @@
 	    }
 	  break;
 	case IDATA7:
+	  if (delay) break;
 	  si->size = 4;
 	  si->data = xmalloc (4);
 	  memset (si->data, 0, si->size);
@@ -2810,6 +2892,78 @@
   return bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
 }
 
+bfd *
+make_delay_head (void)
+{
+  FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
+
+  if (f == NULL)
+    {
+      fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
+      return NULL;
+    }
+
+  /* Output the __tailMerge__xxx function */
+  fprintf (f, "%s Import trampoline\n", ASM_C);
+  fprintf (f, "\t.section	.text\n");
+  fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
+  fprintf (f, "%s:\n", head_label);
+  fprintf (f, mtable[machine].trampoline, imp_name_lab);
+
+  /* Output the delay import descriptor */
+  fprintf (f, "\n%s DELAY_IMPORT_DESCRIPTOR\n", ASM_C);
+  fprintf (f, ".section .text$2\n");
+  fprintf (f,"%s __DELAY_IMPORT_DESCRIPTOR_%s\n", ASM_GLOBAL,imp_name_lab);
+  fprintf (f, "__DELAY_IMPORT_DESCRIPTOR_%s:\n", imp_name_lab);
+  fprintf (f, "\t%s 1\t%s grAttrs\n", ASM_LONG, ASM_C);
+  fprintf (f, "\t%s__%s_iname%s\t%s rvaDLLName\n",
+	   ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
+  fprintf (f, "\t%s__DLL_HANDLE_%s%s\t%s rvaHmod\n",
+	   ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
+  fprintf (f, "\t%s__IAT_%s%s\t%s rvaIAT\n",
+	   ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
+  fprintf (f, "\t%s__INT_%s%s\t%s rvaINT\n",
+	   ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
+  fprintf (f, "\t%s\t0\t%s rvaBoundIAT\n", ASM_LONG, ASM_C);
+  fprintf (f, "\t%s\t0\t%s rvaUnloadIAT\n", ASM_LONG, ASM_C);
+  fprintf (f, "\t%s\t0\t%s dwTimeStamp\n", ASM_LONG, ASM_C);
+
+  /* Output the dll_handle */
+  fprintf (f, "\n.section .data\n");
+  fprintf (f, "__DLL_HANDLE_%s:\n", imp_name_lab);
+  fprintf (f, "\t%s\t0\t%s Handle\n", ASM_LONG, ASM_C);
+  fprintf (f, "\n");
+
+  fprintf (f, "%sStuff for compatibility\n", ASM_C);
+
+  if (!no_idata5)
+    {
+      fprintf (f, "\t.section\t.idata$5\n");
+#ifdef DLLTOOL_MX86_64
+      fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list.  */
+#else
+      fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list.  */
+#endif
+      fprintf (f, "__IAT_%s:\n", imp_name_lab);
+    }
+
+  if (!no_idata4)
+    {
+      fprintf (f, "\t.section\t.idata$4\n");
+      fprintf (f, "\t%s\t0\n", ASM_LONG);
+      fprintf (f, "\t.section	.idata$4\n");
+      fprintf (f, "__INT_%s:\n", imp_name_lab);
+    }
+
+  fprintf (f, "\t.section	.idata$2\n");
+
+  fclose (f);
+
+  assemble_file (TMP_HEAD_S, TMP_HEAD_O);
+
+  return bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
+}
+
 static bfd *
 make_tail (void)
 {
@@ -2875,7 +3029,7 @@
 }
 
 static void
-gen_lib_file (void)
+gen_lib_file (int delay)
 {
   int i;
   export_type *exp;
@@ -2900,7 +3054,14 @@
   outarch->is_thin_archive = 0;
 
   /* Work out a reasonable size of things to put onto one line.  */
-  ar_head = make_head ();
+  if (delay)
+    {
+      ar_head = make_delay_head();
+    }
+  else
+    {
+      ar_head = make_head();
+    }
   ar_tail = make_tail();
 
   if (ar_head == NULL || ar_tail == NULL)
@@ -2912,7 +3073,7 @@
       /* Don't add PRIVATE entries to import lib.  */
       if (exp->private)
 	continue;
-      n = make_one_lib_file (exp, i);
+      n = make_one_lib_file (exp, i, delay);
       n->archive_next = head;
       head = n;
       if (ext_prefix_alias)
@@ -2931,7 +3092,7 @@
 	  alias_exp.hint = exp->hint;
 	  alias_exp.forward = exp->forward;
 	  alias_exp.next = exp->next;
-	  n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE);
+	  n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE, delay);
 	  n->archive_next = head;
 	  head = n;
 	}
@@ -3645,6 +3806,7 @@
   fprintf (file, _("   -k --kill-at              Kill @<n> from exported names.\n"));
   fprintf (file, _("   -A --add-stdcall-alias    Add aliases without @<n>.\n"));
   fprintf (file, _("   -p --ext-prefix-alias <prefix> Add aliases with <prefix>.\n"));
+  fprintf (file, _("   -y --output-delaylib      Create delay import stubs.\n"));
   fprintf (file, _("   -S --as <name>            Use <name> for assembler.\n"));
   fprintf (file, _("   -f --as-flags <flags>     Pass <flags> to the assembler.\n"));
   fprintf (file, _("   -C --compat-implib        Create backward compatible import library.\n"));
@@ -3710,6 +3872,7 @@
   {"mcore-elf", required_argument, NULL, 'M'},
   {"compat-implib", no_argument, NULL, 'C'},
   {"temp-prefix", required_argument, NULL, 't'},
+  {"output-delaylib", required_argument, NULL, 'y'},
   {NULL,0,NULL,0}
 };
 
@@ -3739,7 +3902,7 @@
 #ifdef DLLTOOL_MCORE_ELF
 			   "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHhM:L:F:",
 #else
-			   "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHh",
+			   "m:e:l:y:aD:d:z:b:xp:cCuUkAS:f:nI:vVHh",
 #endif
 			   long_options, 0))
 	 != EOF)
@@ -3860,6 +4023,9 @@
 	case 'C':
 	  create_compat_implib = 1;
 	  break;
+	case 'y':
+	  delayimp_name = optarg;
+	  break;
 	default:
 	  usage (stderr, 1);
 	  break;
@@ -3934,9 +4100,33 @@
 	    *p = '_';
 	}
       head_label = make_label("_head_", imp_name_lab);
-      gen_lib_file ();
+      gen_lib_file (0);
     }
 
+  if (delayimp_name)
+    {
+      /* Make delayimp_name safe for use as a label.  */
+      char *p;
+
+      if (mtable[machine].how_dljtab == 0)
+        {
+          inform (_("Warning, machine type (%d) not supported for delayimport."), machine);
+        }
+      else
+        {
+          killat = 1;
+          imp_name = delayimp_name;
+          imp_name_lab = xstrdup (imp_name);
+          for (p = imp_name_lab; *p; p++)
+            {
+              if (!ISALNUM (*p))
+                *p = '_';
+            }
+          head_label = make_label("__tailMerge_", imp_name_lab);
+          gen_lib_file (1);
+        }
+    }
+
   if (output_def)
     gen_def_file ();
 
/*
 * PROJECT:         ReactOS SDK Library
 * LICENSE:         LGPL, see LGPL.txt in top level directory.
 * FILE:            lib/sdk/delayimp/delayimp.c
 * PURPOSE:         Library for delay importing from dlls
 * PROGRAMMERS:     Timo Kreuzer <timo.kreuzer@reactos.org>
 *
 */

#include <windows.h>
#include <delayimp.h>

/**** load helper ****/

FARPROC WINAPI
__delayLoadHelper2(PCImgDelayDescr pidd, PImgThunkData pIATEntry)
{
	DelayLoadInfo dli;
	int index;
	PImgThunkData pIAT;
	PImgThunkData pINT;
	HMODULE *phMod;
	FARPROC pProc;

	pIAT = PFromRva(pidd->rvaIAT);
	pINT = PFromRva(pidd->rvaINT);
	phMod = PFromRva(pidd->rvaHmod);
	index = IndexFromPImgThunkData(pIATEntry, pIAT);

	dli.cb = sizeof(dli);
	dli.pidd = pidd;
	dli.ppfn = (FARPROC*)pIATEntry->u1.Function;
	dli.szDll = PFromRva(pidd->rvaDLLName);
	dli.dlp.fImportByName = !(pINT[index].u1.Ordinal & IMAGE_ORDINAL_FLAG);
	if (dli.dlp.fImportByName)
	{
		/* u1.AdressOfData points to a IMAGE_IMPORT_BY_NAME struct */
		PIMAGE_IMPORT_BY_NAME piibn = PFromRva((RVA)pINT[index].u1.AddressOfData);
		dli.dlp.szProcName = (LPCSTR)&piibn->Name;
	}
	else
	{
		dli.dlp.dwOrdinal = pINT[index].u1.Ordinal & ~IMAGE_ORDINAL_FLAG;
	}
	dli.hmodCur = *phMod;
	dli.pfnCur = (FARPROC)pIAT[index].u1.Function;
	dli.dwLastError = GetLastError();
	pProc = __pfnDliNotifyHook2(dliStartProcessing, &dli);
	if (pProc)
	{
		pIAT[index].u1.Function = (DWORD_PTR)pProc;
		return pProc;
	}

	if (dli.hmodCur == NULL)
	{
		dli.hmodCur = LoadLibraryA(dli.szDll);
		if (!dli.hmodCur)
		{
			dli.dwLastError = GetLastError();
			__pfnDliFailureHook2(dliFailLoadLib, &dli);
//			if (ret)
//			{
//			}
			// FIXME: raise exception;
			return NULL;
		}
		*phMod = dli.hmodCur;
	}

	/* dli.dlp.szProcName might also contain the ordinal */
	pProc = GetProcAddress(dli.hmodCur, dli.dlp.szProcName);
	if (!pProc)
	{
		dli.dwLastError = GetLastError();
		__pfnDliFailureHook2(dliFailGetProc, &dli);
		// FIXME: handle return value & raise exception
		return NULL;
	}
	pIAT[index].u1.Function = (DWORD_PTR)pProc;

	return pProc;
}

/*** The default hooks ***/

FARPROC WINAPI
DefaultDliNotifyHook2(unsigned dliNotify, PDelayLoadInfo pdli)
{
	return NULL;
}

FARPROC WINAPI
DefaultDliFailureHook2(unsigned dliNotify, PDelayLoadInfo pdli)
{
	return NULL;
}

PfnDliHook __pfnDliNotifyHook2 = DefaultDliNotifyHook2;
PfnDliHook __pfnDliFailureHook2 = DefaultDliFailureHook2;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]