This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Patch: delay import for dlltool
- From: Timo Kreuzer <timo dot kreuzer at web dot de>
- To: binutils at sourceware dot org
- Date: Sun, 16 Aug 2009 20:22:50 +0200
- Subject: 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;