ReactOS  0.4.15-dev-5496-g599ba9c
delayimp.cpp File Reference
#include <apitest.h>
#include <strsafe.h>
#include <delayimp.h>
#include <mmsystem.h>
#include <winver.h>
#include <shlwapi.h>
#include <intshcut.h>
#include <sfc.h>
#include <imagehlp.h>
#include <mmddk.h>
#include <pseh/pseh2.h>
Include dependency graph for delayimp.cpp:

Go to the source code of this file.

Classes

struct  UnProtect
 

Macros

#define FACILITY_VISUALCPP   ((LONG)0x6d)
 
#define VcppException(sev, err)   ((sev) | (FACILITY_VISUALCPP<<16) | err)
 
#define WINMM_DLLNAME   "WINMM.dll"
 
#define LAST_DLI   333
 
#define CheckDli   (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : CheckDli_imp
 
#define CheckDliDone   (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : CheckDliDone_imp
 

Functions

chartarget (PDelayLoadInfo pdli)
 
static void SetExpectedDli (unsigned *order)
 
static void CheckDli_imp (unsigned dliNotify, PDelayLoadInfo pdli, BOOL ErrorHandler)
 
static void CheckDliDone_imp ()
 
INT_PTR WINAPI MyFunction ()
 
BOOL WINAPI MySfcIsKeyProtected (HKEY KeyHandle, LPCWSTR SubKeyName, REGSAM KeySam)
 
FARPROC WINAPI DliHook (unsigned dliNotify, PDelayLoadInfo pdli)
 
FARPROC WINAPI DliFailHook (unsigned dliNotify, PDelayLoadInfo pdli)
 
LONG ExceptionFilter (IN PEXCEPTION_POINTERS ExceptionInfo, ULONG ExceptionCode)
 
template<typename PTR >
PTR Rva2Addr (PIMAGE_DOS_HEADER dos, RVA rva)
 
 START_TEST (delayimp)
 

Variables

bool g_BreakFunctionName = false
 
bool g_BrokenFunctionName = false
 
bool g_BypassMost = false
 
bool g_ExceptionIsModule = false
 
bool g_ImportByName = true
 
const charg_ExpectedDll = NULL
 
const charg_ExpectedName = NULL
 
char g_Target [100] = { 0 }
 
unsignedg_DliHookExpected = NULL
 
size_t g_DliHookIndex = 0
 
static HMODULE g_VersionDll
 
PfnDliHook __pfnDliNotifyHook2
 
bool g_UsePointers = false
 
unsigned g_winmm_get_cur_task [] = { dliStartProcessing, dliNotePreLoadLibrary, dliNotePreGetProcAddress, dliNoteEndProcessing, LAST_DLI }
 
unsigned g_winmm_midi_out_close [] = { dliStartProcessing, dliNotePreGetProcAddress, dliNoteEndProcessing, LAST_DLI }
 
unsigned g_winmm_mide_in_close [] = { dliStartProcessing, dliNotePreGetProcAddress, dliFailGetProc, dliNoteEndProcessing, LAST_DLI }
 
unsigned g_sfc_key [] = { dliStartProcessing, dliNotePreLoadLibrary, dliFailLoadLib, dliNotePreGetProcAddress, dliNoteEndProcessing, LAST_DLI }
 
unsigned g_sfc_file [] = { dliStartProcessing, dliNotePreGetProcAddress, dliNoteEndProcessing, LAST_DLI }
 
unsigned g_version_a [] = { dliStartProcessing, dliNotePreLoadLibrary, dliNotePreGetProcAddress, dliFailGetProc, dliNoteEndProcessing, LAST_DLI }
 
unsigned g_version_w [] = { dliStartProcessing, dliNotePreGetProcAddress, dliFailGetProc, dliNoteEndProcessing, LAST_DLI }
 
unsigned g_scard [] = { dliStartProcessing, dliNoteEndProcessing, LAST_DLI }
 
unsigned g_shlwapi [] = { dliStartProcessing, dliNotePreLoadLibrary, dliNotePreGetProcAddress, dliNoteEndProcessing, LAST_DLI }
 
unsigned g_imagehlp [] = { dliStartProcessing, dliNotePreLoadLibrary, dliFailLoadLib, LAST_DLI }
 

Macro Definition Documentation

◆ CheckDli

#define CheckDli   (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : CheckDli_imp

Definition at line 128 of file delayimp.cpp.

◆ CheckDliDone

#define CheckDliDone   (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : CheckDliDone_imp

Definition at line 129 of file delayimp.cpp.

◆ FACILITY_VISUALCPP

#define FACILITY_VISUALCPP   ((LONG)0x6d)

Definition at line 28 of file delayimp.cpp.

◆ LAST_DLI

#define LAST_DLI   333

Definition at line 88 of file delayimp.cpp.

◆ VcppException

#define VcppException (   sev,
  err 
)    ((sev) | (FACILITY_VISUALCPP<<16) | err)

Definition at line 32 of file delayimp.cpp.

◆ WINMM_DLLNAME

#define WINMM_DLLNAME   "WINMM.dll"

Definition at line 38 of file delayimp.cpp.

Function Documentation

◆ CheckDli_imp()

static void CheckDli_imp ( unsigned  dliNotify,
PDelayLoadInfo  pdli,
BOOL  ErrorHandler 
)
static

Definition at line 97 of file delayimp.cpp.

98 {
99  if (!g_DliHookExpected) return;
100 
101  winetest_ok(dliNotify == g_DliHookExpected[g_DliHookIndex], "Expected dliNotify to be %u, was: %u for %s\n",
102  g_DliHookExpected[g_DliHookIndex], dliNotify, target(pdli));
103  if (ErrorHandler)
104  {
105  winetest_ok(dliNotify == dliFailGetProc || dliNotify == dliFailLoadLib,
106  "Expected code %u to be processed by the Hook, not the ErrorHandler for %s\n", dliNotify, target(pdli));
107  }
108  else
109  {
110  winetest_ok(dliNotify == dliStartProcessing || dliNotify == dliNotePreLoadLibrary ||
111  dliNotify == dliNotePreGetProcAddress || dliNotify == dliNoteEndProcessing,
112  "Expected code %u to be processed by the ErrorHandler, not the Hook for %s\n", dliNotify, target(pdli));
113  }
115  g_DliHookIndex++;
116 }
size_t g_DliHookIndex
Definition: delayimp.cpp:87
void __winetest_cdecl winetest_ok(int condition, const char *msg,...)
#define LAST_DLI
Definition: delayimp.cpp:88
unsigned * g_DliHookExpected
Definition: delayimp.cpp:86
char * target(PDelayLoadInfo pdli)
Definition: delayimp.cpp:50

◆ CheckDliDone_imp()

static void CheckDliDone_imp ( )
static

Definition at line 118 of file delayimp.cpp.

119 {
120  if (!g_DliHookExpected) return;
122  "Expected g_DliHookExpected[g_DliHookIndex] to be %u, was: %u for %s\n",
125  g_Target[0] = '\0';
126 }
char g_Target[100]
Definition: delayimp.cpp:48
size_t g_DliHookIndex
Definition: delayimp.cpp:87
void __winetest_cdecl winetest_ok(int condition, const char *msg,...)
#define LAST_DLI
Definition: delayimp.cpp:88
#define NULL
Definition: types.h:112
unsigned * g_DliHookExpected
Definition: delayimp.cpp:86
char * target(PDelayLoadInfo pdli)
Definition: delayimp.cpp:50

◆ DliFailHook()

FARPROC WINAPI DliFailHook ( unsigned  dliNotify,
PDelayLoadInfo  pdli 
)

Definition at line 258 of file delayimp.cpp.

259 {
260  ok(pdli && pdli->cb >= 36,
261  "Expected a valid pointer with a struct that is big enough: %p, %lu\n", pdli, pdli ? pdli->cb : 0u);
262  if (!pdli || pdli->cb < 36) return NULL;
263 
264  CheckDli(dliNotify, pdli, TRUE);
265 
266  /* Redirections / fixes */
267  if (dliNotify == dliFailLoadLib)
268  {
269  if (!_stricmp(pdli->szDll, "l_m_os.dll"))
270  return (FARPROC)LoadLibraryA("sfc_os.dll");
271  }
272  else if (dliNotify == dliFailGetProc)
273  {
274  if (pdli->dlp.fImportByName && pdli->hmodCur == (HMODULE)1)
275  {
276  return GetProcAddress(g_VersionDll, pdli->dlp.szProcName);
277  }
278  }
279 
280  /* Parameter validation */
281  ok(pdli->ppfn != NULL, "Expected ppfn to be valid, was NULL for %s\n", target(pdli));
282  ok(pdli->szDll != NULL, "Expected szDll to be valid, was NULL for %s\n", target(pdli));
283  if (pdli->dlp.fImportByName)
284  ok(pdli->dlp.szProcName != NULL, "Expected szProcName to be valid, was NULL for %s\n", target(pdli));
285  else
286  ok(pdli->dlp.dwOrdinal != 0, "Expected dwOrdinal to be valid, was NULL for %s\n", target(pdli));
287  switch(dliNotify)
288  {
289  case dliFailLoadLib:
290  ok(pdli->hmodCur == NULL, "Expected hmodCur to be NULL, was: %p for %s\n", pdli->hmodCur, target(pdli));
291  ok(pdli->pfnCur == NULL, "Expected pfnCur to be NULL, was: %p for %s\n", pdli->pfnCur, target(pdli));
293  "Expected dwLastError to be ERROR_MOD_NOT_FOUND, was: %lu for %s\n", pdli->dwLastError, target(pdli));
294  break;
295  case dliFailGetProc:
296  ok(pdli->hmodCur != NULL, "Expected hmodCur to be valid, was NULL for %s\n", target(pdli));
297  ok(pdli->pfnCur == NULL, "Expected pfnCur to be NULL, was: %p for %s\n", pdli->pfnCur, target(pdli));
299  "Expected dwLastError to be ERROR_PROC_NOT_FOUND, was: %lu for %s\n", pdli->dwLastError, target(pdli));
300  break;
301  }
302 
303  return NULL;
304 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
FARPROC pfnCur
Definition: delayimp.h:73
#define TRUE
Definition: types.h:120
BOOL fImportByName
Definition: delayimp.h:57
#define _stricmp
Definition: cat.c:22
#define CheckDli
Definition: delayimp.cpp:128
LPCSTR szProcName
Definition: delayimp.h:60
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
DelayLoadProc dlp
Definition: delayimp.h:71
DWORD dwLastError
Definition: delayimp.h:74
HMODULE hmodCur
Definition: delayimp.h:72
DWORD cb
Definition: delayimp.h:67
LPCSTR szDll
Definition: delayimp.h:70
DWORD dwOrdinal
Definition: delayimp.h:61
#define ERROR_PROC_NOT_FOUND
Definition: winerror.h:199
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112
FARPROC * ppfn
Definition: delayimp.h:69
#define ERROR_MOD_NOT_FOUND
Definition: compat.h:104
GLenum target
Definition: glext.h:7315
#define GetProcAddress(x, y)
Definition: compat.h:753
static HMODULE g_VersionDll
Definition: delayimp.cpp:144
int(* FARPROC)()
Definition: compat.h:36

Referenced by START_TEST().

◆ DliHook()

FARPROC WINAPI DliHook ( unsigned  dliNotify,
PDelayLoadInfo  pdli 
)

Definition at line 145 of file delayimp.cpp.

146 {
147  ok(pdli && pdli->cb >= 36, "Expected a valid pointer with a struct that is big enough: %p, %lu\n",
148  pdli, pdli ? pdli->cb : 0u);
149  if (!pdli || pdli->cb < 36) return NULL;
150 
151  CheckDli(dliNotify, pdli, FALSE);
152 
154  {
155  g_BreakFunctionName = false;
156  g_BrokenFunctionName = true;
157  char* procname = (char*)pdli->dlp.szProcName;
158  UnProtect prot(procname);
159  char c = procname[0];
160  procname[0] = isupper(c) ? tolower(c) : toupper(c);
161  }
162 
163  /* Validate dll name when required */
165  {
166  ok(!strcmp(g_ExpectedDll, pdli->szDll), "Expected szDll to be '%s', but was: '%s'\n", g_ExpectedDll, pdli->szDll);
167  ok(pdli->dlp.fImportByName, "Expected import by name (%s!%s)\n", g_ExpectedDll, g_ExpectedName);
168  if (pdli->dlp.fImportByName)
169  {
170  ok(!strcmp(g_ExpectedName, pdli->dlp.szProcName), "Expected szProcName to be '%s', but was: '%s'\n",
171  g_ExpectedName, pdli->dlp.szProcName);
172  }
173  }
174 
175 
176  if (dliNotify == dliStartProcessing)
177  {
178  /* Test loadlib fail */
179  if (!_stricmp(pdli->szDll, "sfc_os.dll"))
180  {
181  char* dll = (char*)pdli->szDll;
182  UnProtect u(dll);
183  dll[0] = 'l'; dll[1] = '_'; dll[2] = 'm';
184  }
185  if (!_stricmp(pdli->szDll, "imagehlp.dll"))
186  {
187  char* dll = (char*)pdli->szDll;
188  UnProtect u(dll);
189  dll[0] = 'x'; dll[1] = 'x'; dll[2] = 'x'; dll[3] = 'x'; dll[4] = 'x';
190  }
191  /* Test bypass */
192  if (!_stricmp(pdli->szDll, "dbghelp.dll"))
193  return MyFunction;
194  }
195  else if (dliNotify == dliNotePreLoadLibrary)
196  {
197  /* Show that this value is actually used! */
198  if (!_stricmp(pdli->szDll, "version.dll"))
199  {
200  g_VersionDll = LoadLibraryA("version.dll");
201  return (FARPROC)1;
202  }
203 
204  }
205  else if (dliNotify == dliNotePreGetProcAddress)
206  {
207  if (pdli->dlp.fImportByName && !strcmp(pdli->dlp.szProcName, "SfcIsKeyProtected"))
208  {
210  }
211  }
212 
213  /* Parameter validation */
214  ok(pdli->ppfn != NULL, "Expected ppfn to be valid, was NULL for %s\n", target(pdli));
215  ok(pdli->szDll != NULL, "Expected szDll to be valid, was NULL for %s\n", target(pdli));
216  ok(pdli->dwLastError == ERROR_SUCCESS,
217  "Expected dwLastError to be ERROR_SUCCESS, was: %lu for %s\n", pdli->dwLastError, target(pdli));
218  ok(g_ImportByName == !!pdli->dlp.fImportByName, "Expected pdli->dlp.fImportByName to equal g_ImportByname\n");
219  if (pdli->dlp.fImportByName)
220  ok(pdli->dlp.szProcName != NULL, "Expected szProcName to be valid, was NULL for %s\n", target(pdli));
221  else
222  ok(pdli->dlp.dwOrdinal != 0, "Expected dwOrdinal to be valid, was NULL for %s\n", target(pdli));
223  switch(dliNotify)
224  {
225  case dliStartProcessing:
226  ok(pdli->hmodCur == NULL, "Expected hmodCur to be NULL, was: %p for %s\n", pdli->hmodCur, target(pdli));
227  ok(pdli->pfnCur == NULL, "Expected pfnCur to be NULL, was: %p for %s\n", pdli->pfnCur, target(pdli));
228  break;
230  ok(pdli->hmodCur == NULL, "Expected hmodCur to be NULL, was: %p for %s\n", pdli->hmodCur, target(pdli));
231  ok(pdli->pfnCur == NULL, "Expected pfnCur to be NULL, was: %p for %s\n", pdli->pfnCur, target(pdli));
232  break;
234  ok(pdli->hmodCur != NULL, "Expected hmodCur to be valid, was NULL for %s\n", target(pdli));
235  ok(pdli->pfnCur == NULL, "Expected pfnCur to be NULL, was: %p for %s\n", pdli->pfnCur, target(pdli));
236  break;
238  if (!g_BypassMost)
239  ok(pdli->hmodCur != NULL, "Expected hmodCur to be valid, was NULL for %s\n", target(pdli));
240  ok(pdli->pfnCur != NULL, "Expected pfnCur to be a valid pointer, was NULL for %s\n", target(pdli));
242  {
244  ok(targetProc != NULL, "This should not happen, the function i need is unavail! (%s!%s)\n",
246  ok(targetProc == pdli->pfnCur, "Expected pfnCur to be %p, was %p for %s\n", targetProc, pdli->pfnCur, target(pdli));
247  ok(pdli->ppfn && targetProc == *pdli->ppfn,
248  "Expected ppfn to be valid and to result in %p, was: %p(%p) for %s\n",
249  target, pdli->ppfn, pdli->ppfn ? *pdli->ppfn : NULL, target(pdli));
250  }
251  break;
252  default:
253  break;
254  }
255  return NULL;
256 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
FARPROC pfnCur
Definition: delayimp.h:73
BOOL WINAPI MySfcIsKeyProtected(HKEY KeyHandle, LPCWSTR SubKeyName, REGSAM KeySam)
Definition: delayimp.cpp:138
#define ERROR_SUCCESS
Definition: deptool.c:10
bool g_BypassMost
Definition: delayimp.cpp:43
BOOL fImportByName
Definition: delayimp.h:57
#define _stricmp
Definition: cat.c:22
static HMODULE dll
Definition: str.c:188
#define FALSE
Definition: types.h:117
#define CheckDli
Definition: delayimp.cpp:128
bool g_ImportByName
Definition: delayimp.cpp:45
INT_PTR WINAPI MyFunction()
Definition: delayimp.cpp:133
LPCSTR szProcName
Definition: delayimp.h:60
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
DelayLoadProc dlp
Definition: delayimp.h:71
DWORD dwLastError
Definition: delayimp.h:74
HMODULE hmodCur
Definition: delayimp.h:72
int toupper(int c)
Definition: utclib.c:881
#define isupper(c)
Definition: acclib.h:71
bool g_BrokenFunctionName
Definition: delayimp.cpp:42
const GLubyte * c
Definition: glext.h:8905
DWORD cb
Definition: delayimp.h:67
LPCSTR szDll
Definition: delayimp.h:70
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD dwOrdinal
Definition: delayimp.h:61
#define ok(value,...)
Definition: atltest.h:57
bool g_BreakFunctionName
Definition: delayimp.cpp:41
#define NULL
Definition: types.h:112
FARPROC * ppfn
Definition: delayimp.h:69
const char * g_ExpectedName
Definition: delayimp.cpp:47
GLenum target
Definition: glext.h:7315
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define GetProcAddress(x, y)
Definition: compat.h:753
const char * g_ExpectedDll
Definition: delayimp.cpp:46
static HMODULE g_VersionDll
Definition: delayimp.cpp:144
int tolower(int c)
Definition: utclib.c:902
int(* FARPROC)()
Definition: compat.h:36

Referenced by START_TEST().

◆ ExceptionFilter()

LONG ExceptionFilter ( IN PEXCEPTION_POINTERS  ExceptionInfo,
ULONG  ExceptionCode 
)

Definition at line 307 of file delayimp.cpp.

308 {
310  ok(ExceptionCode == expected, "Expected code to be 0x%lx, was: 0x%lx\n", expected, ExceptionCode);
311  ok(ExceptionInfo != NULL, "Expected to get exception info\n");
312  ok(ExceptionInfo->ExceptionRecord != NULL, "Expected to get a valid record info\n");
313 
314  if (ExceptionCode != expected)
315  {
316  skip("Skipping other checks, this was not the exception we expected!\n");
318  }
319 
320  if (ExceptionInfo && ExceptionInfo->ExceptionRecord)
321  {
322  PEXCEPTION_RECORD ExceptionRecord = ExceptionInfo->ExceptionRecord;
323  ok(ExceptionRecord->ExceptionCode == expected, "Expected ExceptionCode to be 0x%lx, was 0x%lx\n",
324  expected, ExceptionRecord->ExceptionCode);
325  /* We can still continue. */
326  ok(ExceptionRecord->ExceptionFlags == 0, "Expected ExceptionFlags to be 0, was: 0x%lx\n",
327  ExceptionRecord->ExceptionFlags);
328  ok(ExceptionRecord->NumberParameters == 1, "Expected 1 parameter, got %lu\n",
329  ExceptionRecord->NumberParameters);
330  if (ExceptionRecord->NumberParameters == 1)
331  {
332  PDelayLoadInfo LoadInfo = (PDelayLoadInfo)ExceptionRecord->ExceptionInformation[0];
333  ok(LoadInfo && LoadInfo->cb >= 36, "Expected a valid pointer with a struct that is big enough: %p, %lu\n",
334  LoadInfo, LoadInfo ? LoadInfo->cb : 0);
335 
336  if (g_ExpectedDll)
337  ok(!strcmp(g_ExpectedDll, LoadInfo->szDll), "Expected szDll to be '%s', but was: '%s'\n",
338  g_ExpectedDll, LoadInfo->szDll);
339  if (g_ExpectedName)
340  {
341  ok(LoadInfo->dlp.fImportByName, "Expected import by name\n");
342  if (LoadInfo->dlp.fImportByName)
343  {
344  ok(!strcmp(g_ExpectedName, LoadInfo->dlp.szProcName),
345  "Expected szProcName to be '%s', but was: '%s'\n", g_ExpectedName, LoadInfo->dlp.szProcName);
346 
348  {
349  HMODULE mod = LoadLibraryA("imagehlp.dll");
350  LoadInfo->pfnCur = GetProcAddress(mod, g_ExpectedName);
351  }
352  else
353  {
354  char buf[100];
356  sprintf(buf, "%c%s", first, g_ExpectedName + 1);
358  }
360  }
361  }
362  }
363  }
364 
366 }
FARPROC pfnCur
Definition: delayimp.h:73
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1772
const GLint * first
Definition: glext.h:5794
struct DelayLoadInfo * PDelayLoadInfo
BOOL fImportByName
Definition: delayimp.h:57
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:87
bool g_ExceptionIsModule
Definition: delayimp.cpp:44
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD ExceptionCode
Definition: compat.h:208
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define ERROR_SEVERITY_ERROR
Definition: ntbasedef.h:596
LPCSTR szProcName
Definition: delayimp.h:60
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
DelayLoadProc dlp
Definition: delayimp.h:71
int toupper(int c)
Definition: utclib.c:881
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
#define isupper(c)
Definition: acclib.h:71
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD cb
Definition: delayimp.h:67
LPCSTR szDll
Definition: delayimp.h:70
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:210
#define ERROR_PROC_NOT_FOUND
Definition: winerror.h:199
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112
#define skip(...)
Definition: atltest.h:64
const char * g_ExpectedName
Definition: delayimp.cpp:47
#define ERROR_MOD_NOT_FOUND
Definition: compat.h:104
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
DWORD ExceptionFlags
Definition: compat.h:209
#define GetProcAddress(x, y)
Definition: compat.h:753
#define VcppException(sev, err)
Definition: delayimp.cpp:32
DWORD NumberParameters
Definition: compat.h:212
const char * g_ExpectedDll
Definition: delayimp.cpp:46
int tolower(int c)
Definition: utclib.c:902
static int mod
Definition: i386-dis.c:1289
BOOL expected
Definition: store.c:2063

Referenced by __C_specific_handler(), and START_TEST().

◆ MyFunction()

INT_PTR WINAPI MyFunction ( )

Definition at line 133 of file delayimp.cpp.

134 {
135  return 123;
136 }

Referenced by DliHook().

◆ MySfcIsKeyProtected()

BOOL WINAPI MySfcIsKeyProtected ( HKEY  KeyHandle,
LPCWSTR  SubKeyName,
REGSAM  KeySam 
)

Definition at line 138 of file delayimp.cpp.

139 {
140  return 12345;
141 }

Referenced by DliHook().

◆ Rva2Addr()

template<typename PTR >
PTR Rva2Addr ( PIMAGE_DOS_HEADER  dos,
RVA  rva 
)

Definition at line 380 of file delayimp.cpp.

381 {
382  /* Old delayload type */
383  if (g_UsePointers)
384  return reinterpret_cast<PTR>(rva);
385  return reinterpret_cast<PTR>((reinterpret_cast<PBYTE>(dos) + rva));
386 }
bool g_UsePointers
Definition: delayimp.cpp:377
IMAGE_DOS_HEADER dos
Definition: module.c:49

◆ SetExpectedDli()

static void SetExpectedDli ( unsigned order)
static

Definition at line 90 of file delayimp.cpp.

91 {
93  g_DliHookIndex = 0;
94  g_Target[0] = '\0';
95 }
GLuint GLdouble GLdouble GLint GLint order
Definition: glext.h:11194
char g_Target[100]
Definition: delayimp.cpp:48
size_t g_DliHookIndex
Definition: delayimp.cpp:87
unsigned * g_DliHookExpected
Definition: delayimp.cpp:86

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( delayimp  )

Definition at line 402 of file delayimp.cpp.

403 {
405  /* Verify that both scenario's work */
406  ok(__pfnDliNotifyHook2 == DliHook, "Expected __pfnDliNotifyHook2 to be DliHook(%p), but was: %p\n",
408  ok(__pfnDliFailureHook2 == NULL, "Expected __pfnDliFailureHook2 to be NULL, but was: %p\n",
410 
412 
413 
415 
416  ok(dos->e_magic == IMAGE_DOS_SIGNATURE, "Expected a DOS header\n");
418  return;
419 
422 
423  /* Test some advanced features (loading / unloading) */
424  if (delaydir->Size != 0)
425  {
426 #if defined(_DELAY_IMP_VER) && _DELAY_IMP_VER == 2 && defined(DELAYLOAD_SUPPORTS_UNLOADING)
427  /* First, before mangling the delayload stuff, let's try some v2 functions */
429  ok(mod == NULL, "Expected mod to be NULL, was %p\n", mod);
430  /* Now, a mistyped module (case sensitive!) */
431  HRESULT hr = __HrLoadAllImportsForDll("WiNmM.DlL");
432  ok(hr == HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND), "Expected hr to be HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND), was %lu\n", hr);
434  ok(mod == NULL, "Expected mod to be NULL, was %p\n", mod);
435 
436  /* Let's load it */
437  hr = __HrLoadAllImportsForDll(WINMM_DLLNAME);
438  ok(hr == S_OK, "Expected hr to be S_OK, was %lu\n", hr);
440  ok(mod != NULL, "Expected mod to be valid, was NULL\n");
441 
442  BOOL status = __FUnloadDelayLoadedDLL2(WINMM_DLLNAME);
443  ok(status == TRUE, "Expected __FUnloadDelayLoadedDLL2 to succeed\n");
445  ok(mod == NULL, "Expected mod to be NULL, was %p\n", mod);
446 #else
447  trace("Binary compiled without support for unloading\n");
448 #endif
449  }
450  else
451  {
452  skip("No IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT found, some advanced features might not work!\n");
453  }
454 
455  /* Test the normal flow without a dll loaded */
458  g_ExpectedName = "mmGetCurrentTask";
459  DWORD task = mmGetCurrentTask();
460  ok(task == GetCurrentThreadId(), "Expected ret to be current thread id (0x%lx), was 0x%lx\n", GetCurrentThreadId(), task);
461  CheckDliDone();
462 
463  /* Test the normal flow with a dll loaded */
466  g_ExpectedName = "midiOutClose";
467  DWORD err = midiOutClose((HMIDIOUT)(ULONG_PTR)0xdeadbeef);
468  ok(err == MMSYSERR_INVALHANDLE, "Expected err to be MMSYSERR_INVALHANDLE, was 0x%lx\n", err);
469  CheckDliDone();
470 
471  /* Make sure GetProcAddress fails, also ignore the Failure hook, use the exception to set the address */
474  g_ExpectedName = "MixerClose";
475  g_BreakFunctionName = true;
476  _SEH2_TRY
477  {
478  err = mixerClose((HMIXER)(ULONG_PTR)0xdeadbeef);
479  }
481  {
483  }
484  _SEH2_END;
485  ok(err == MMSYSERR_INVALHANDLE, "Expected err to be MMSYSERR_INVALHANDLE, was 0x%lx\n", err);
486  CheckDliDone();
487  ok(g_BreakFunctionName == false, "Expected the functionname to be changed\n");
488 
489  /* Make the LoadLib fail, manually load the library in the Failure Hook,
490  Respond to the dliNotePreGetProcAddress with an alternate function address */
493  ok(ret == 12345, "Expected ret to be 12345, was %u\n", ret); /* The original function returns FALSE! */
494  CheckDliDone();
495 
496  /* Show that it works with the manually returned dll */
499  ok(ret == FALSE, "Expected ret to be FALSE, was %u\n", ret);
500  CheckDliDone();
501 
502  /* Return a fake dll handle, so that we can see when it is being used, and manually return a function in the Failure Hook */
505  ok(ret == FALSE, "Expected ret to be FALSE, was %u\n", ret);
506  CheckDliDone();
507 
508  /* Manually return a function in the failure hook, when the module is the previously set bad one */
511  ok(ret == FALSE, "Expected ret to be FALSE, was %u\n", ret);
512  CheckDliDone();
513 
514  if (HIWORD(SymGetOptions) == NULL)
515  {
516  skip("SymGetOptions until CORE-6504 is fixed\n");
517  }
518  else
519  {
520  /* Completely bypass most hooks, by directly replying with a function address */
522  g_BypassMost = true;
523  DWORD opt = SymGetOptions();
524  g_BypassMost = false;
525  ok(opt == 123, "Expected opt to be 123, was %lu\n", opt); /* The original function returns ERROR_INVALID_HANDLE */
526  CheckDliDone();
527  }
528 
529  /* Import by ordinal */
530  g_ImportByName = false;
532  PARSEDURLA pua = { sizeof(pua), 0 };
533  HRESULT hr = ParseURLA("", &pua);
534  ok(hr == URL_E_INVALID_SYNTAX, "Expected tmp to be URL_E_INVALID_SYNTAX, was %lx\n", hr);
535  CheckDliDone();
536  g_ImportByName = true;
537 
538  /* Handle LoadLib failure with an exception handler */
539  if (HIWORD(MapAndLoad) == NULL)
540  {
541  skip("MapAndLoad until CORE-6504 is fixed\n");
542  }
543  else
544  {
546  LOADED_IMAGE img = {0};
547  ret = 123;
548  g_ExceptionIsModule = true;
549  g_ExpectedDll = "xxxxxhlp.dll";
550  g_ExpectedName = "MapAndLoad";
551  _SEH2_TRY
552  {
553  ret = MapAndLoad("some_not_existing_file.aabbcc", NULL, &img, FALSE, TRUE);
554  }
556  {
557  ;
558  }
559  _SEH2_END;
560  g_ExceptionIsModule = false;
561  ok(ret == FALSE, "Expected ret to be FALSE, was %u\n", ret);
562  CheckDliDone();
563  }
564 }
_SEH2_TRY
Definition: create.c:4226
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
unsigned g_winmm_get_cur_task[]
Definition: delayimp.cpp:389
HRESULT hr
Definition: shlfolder.c:183
#define TRUE
Definition: types.h:120
static void SetExpectedDli(unsigned *order)
Definition: delayimp.cpp:90
unsigned g_imagehlp[]
Definition: delayimp.cpp:398
#define CheckDliDone
Definition: delayimp.cpp:129
UINT WINAPI mixerClose(HMIXER hMix)
Definition: winmm.c:389
HRESULT WINAPI ParseURLA(LPCSTR x, PARSEDURLA *y)
Definition: url.c:161
#define WINMM_DLLNAME
Definition: delayimp.cpp:38
bool g_BypassMost
Definition: delayimp.cpp:43
unsigned g_winmm_mide_in_close[]
Definition: delayimp.cpp:391
unsigned g_sfc_key[]
Definition: delayimp.cpp:392
#define MMSYSERR_INVALHANDLE
Definition: mmsystem.h:101
_SEH2_END
Definition: create.c:4400
unsigned g_version_w[]
Definition: delayimp.cpp:395
IMAGE_NT_HEADERS nt
Definition: module.c:50
BOOL WINAPI MapAndLoad(PCSTR pszImageName, PCSTR pszDllPath, PLOADED_IMAGE pLoadedImage, BOOL bDotDll, BOOL bReadOnly)
Definition: access.c:131
unsigned g_version_a[]
Definition: delayimp.cpp:394
FARPROC WINAPI DliFailHook(unsigned dliNotify, PDelayLoadInfo pdli)
Definition: delayimp.cpp:258
uint32_t ULONG_PTR
Definition: typedefs.h:65
bool g_ExceptionIsModule
Definition: delayimp.cpp:44
unsigned g_sfc_file[]
Definition: delayimp.cpp:393
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
LONG ExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo, ULONG ExceptionCode)
Definition: delayimp.cpp:307
unsigned g_shlwapi[]
Definition: delayimp.cpp:397
#define FALSE
Definition: types.h:117
bool g_ImportByName
Definition: delayimp.cpp:45
unsigned int BOOL
Definition: ntddk_ex.h:94
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
struct _IMAGE_DOS_HEADER * PIMAGE_DOS_HEADER
#define URL_E_INVALID_SYNTAX
Definition: intshcut.h:32
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:459
unsigned g_scard[]
Definition: delayimp.cpp:396
#define trace
Definition: atltest.h:70
GLint GLvoid * img
Definition: gl.h:1956
LONG HRESULT
Definition: typedefs.h:79
UINT WINAPI midiOutClose(HMIDIOUT hMidiOut)
Definition: winmm.c:981
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL WINAPI SfcIsKeyProtected(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired)
Definition: sfc_os.c:117
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
Definition: ntimage.h:488
unsigned g_winmm_midi_out_close[]
Definition: delayimp.cpp:390
BOOL WINAPI GetFileVersionInfoA(LPCSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:853
int ret
IMAGE_DOS_HEADER dos
Definition: module.c:49
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
#define err(...)
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
FARPROC WINAPI DliHook(unsigned dliNotify, PDelayLoadInfo pdli)
Definition: delayimp.cpp:145
PfnDliHook __pfnDliNotifyHook2
Definition: delayimp.h:80
PfnDliHook __pfnDliFailureHook2
Definition: delayimp.h:81
#define S_OK
Definition: intsafe.h:52
#define GetModuleHandle
Definition: winbase.h:3698
DWORD WINAPI SymGetOptions(void)
Definition: dbghelp.c:600
#define ok(value,...)
Definition: atltest.h:57
bool g_BreakFunctionName
Definition: delayimp.cpp:41
#define NULL
Definition: types.h:112
BOOL WINAPI SfcGetNextProtectedFile(HANDLE RpcHandle, PPROTECTED_FILE_DATA ProtFileData)
Definition: sfc_os.c:142
BOOL WINAPI GetFileVersionInfoW(LPCWSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:845
#define skip(...)
Definition: atltest.h:64
const char * g_ExpectedName
Definition: delayimp.cpp:47
#define ERROR_MOD_NOT_FOUND
Definition: compat.h:104
#define HIWORD(l)
Definition: typedefs.h:247
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
DWORD APIENTRY mmGetCurrentTask(VOID)
Definition: winmm.c:2915
const char * g_ExpectedDll
Definition: delayimp.cpp:46
BYTE * PBYTE
Definition: pedump.c:66
static int mod
Definition: i386-dis.c:1289
PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS
Definition: ntddk_ex.h:187
Definition: ps.c:97

◆ target()

Definition at line 50 of file delayimp.cpp.

51 {
52  if (g_Target[0] == '\0' && pdli)
53  {
54  if (pdli->dlp.fImportByName)
55  sprintf(g_Target, "%s!%s", pdli->szDll, pdli->dlp.szProcName);
56  else
57  sprintf(g_Target, "%s!#%lu", pdli->szDll, pdli->dlp.dwOrdinal);
58  }
59  return g_Target;
60 }
char g_Target[100]
Definition: delayimp.cpp:48
BOOL fImportByName
Definition: delayimp.h:57
#define sprintf(buf, format,...)
Definition: sprintf.c:55
LPCSTR szProcName
Definition: delayimp.h:60
DelayLoadProc dlp
Definition: delayimp.h:71
LPCSTR szDll
Definition: delayimp.h:70
DWORD dwOrdinal
Definition: delayimp.h:61

Referenced by CheckDli_imp(), and CheckDliDone_imp().

Variable Documentation

◆ __pfnDliNotifyHook2

PfnDliHook __pfnDliNotifyHook2

Definition at line 80 of file delayimp.h.

Referenced by __delayLoadHelper2(), and START_TEST().

◆ g_BreakFunctionName

bool g_BreakFunctionName = false

Definition at line 41 of file delayimp.cpp.

Referenced by DliHook(), and START_TEST().

◆ g_BrokenFunctionName

bool g_BrokenFunctionName = false

Definition at line 42 of file delayimp.cpp.

Referenced by DliHook().

◆ g_BypassMost

bool g_BypassMost = false

Definition at line 43 of file delayimp.cpp.

Referenced by DliHook(), and START_TEST().

◆ g_DliHookExpected

unsigned* g_DliHookExpected = NULL

Definition at line 86 of file delayimp.cpp.

Referenced by CheckDli_imp(), CheckDliDone_imp(), and SetExpectedDli().

◆ g_DliHookIndex

size_t g_DliHookIndex = 0

Definition at line 87 of file delayimp.cpp.

Referenced by CheckDli_imp(), CheckDliDone_imp(), and SetExpectedDli().

◆ g_ExceptionIsModule

bool g_ExceptionIsModule = false

Definition at line 44 of file delayimp.cpp.

Referenced by ExceptionFilter(), and START_TEST().

◆ g_ExpectedDll

const char* g_ExpectedDll = NULL

Definition at line 46 of file delayimp.cpp.

Referenced by DliHook(), ExceptionFilter(), and START_TEST().

◆ g_ExpectedName

const char* g_ExpectedName = NULL

Definition at line 47 of file delayimp.cpp.

Referenced by DliHook(), ExceptionFilter(), and START_TEST().

◆ g_imagehlp

Definition at line 398 of file delayimp.cpp.

Referenced by START_TEST().

◆ g_ImportByName

bool g_ImportByName = true

Definition at line 45 of file delayimp.cpp.

Referenced by DliHook(), and START_TEST().

◆ g_scard

Definition at line 396 of file delayimp.cpp.

Referenced by START_TEST().

◆ g_sfc_file

Definition at line 393 of file delayimp.cpp.

Referenced by START_TEST().

◆ g_sfc_key

◆ g_shlwapi

◆ g_Target

char g_Target[100] = { 0 }

Definition at line 48 of file delayimp.cpp.

Referenced by CheckDliDone_imp(), SetExpectedDli(), and target().

◆ g_UsePointers

bool g_UsePointers = false

Definition at line 377 of file delayimp.cpp.

Referenced by Rva2Addr().

◆ g_version_a

◆ g_version_w

◆ g_VersionDll

HMODULE g_VersionDll
static

Definition at line 144 of file delayimp.cpp.

Referenced by DliFailHook(), and DliHook().

◆ g_winmm_get_cur_task

Definition at line 389 of file delayimp.cpp.

Referenced by START_TEST().

◆ g_winmm_mide_in_close

Definition at line 391 of file delayimp.cpp.

Referenced by START_TEST().

◆ g_winmm_midi_out_close

Definition at line 390 of file delayimp.cpp.

Referenced by START_TEST().