On Sun, Nov 09, 2003 at 09:49:40PM +0100, Marcus Meissner wrote: > Hi, > > WDMs sometimes import other WDM or kernel libraries with funname@xx > names. Support this by removing @xx additions during function lookup > and compare. Take care not to break C++ exports. > > Ciao, Marcus > > Changelog: > Handle function imports/exports with @<numargbytes> at the > end of their names. There was a superflous return 0; in the b case. Ciao, Marcus Index: dlls/ntdll/loader.c =================================================================== RCS file: /home/wine/wine/dlls/ntdll/loader.c,v retrieving revision 1.55 diff -u -r1.55 loader.c --- dlls/ntdll/loader.c 4 Nov 2003 04:50:19 -0000 1.55 +++ dlls/ntdll/loader.c 9 Nov 2003 21:08:15 -0000 @@ -21,6 +21,7 @@ #include <assert.h> #include <stdarg.h> +#include <ctype.h> #include "windef.h" #include "winbase.h" @@ -283,6 +284,49 @@ return proc; } +/************************************************************************* + * no_at_strcmp + * + * This function compares 2 function names, skipping @args notifications + * if present. WDM drivers occasionaly have those. Be aware that @ + * might be present in regular C++ names. + */ +static int no_at_strcmp(const char *a, const char *b) { + do { + if (((*a == '\0') && (*b == '\0'))) + return 0; + + if (((*a == '@') && (*b == '\0'))) { + const char *xa = a+1; + + /* check if we just have numbers afterwards + * (think C++ mangling) */ + while (*xa && isdigit(*xa)) + xa++; + if (!*xa) + return 0; + /* else: fallthrough */ + } + + if (((*b == '@') && (*a == '\0'))) { + const char *xb = b+1; + + /* check if we just have numbers afterwards + * (think C++ mangling) */ + while (*xb && isdigit(*xb)) + xb++; + if (!*xb) + return 0; + /* else: fallthrough */ + } + + if (*a != *b) + return *a - *b; + + a++; + b++; + } while (1); +} /************************************************************************* * find_named_export @@ -301,7 +345,7 @@ if (hint >= 0 && hint <= max) { char *ename = get_rva( module, names[hint] ); - if (!strcmp( ename, name )) + if (!no_at_strcmp( ename, name )) return find_ordinal_export( module, exports, exp_size, ordinals[hint] ); } @@ -310,7 +354,7 @@ { int res, pos = (min + max) / 2; char *ename = get_rva( module, names[pos] ); - if (!(res = strcmp( ename, name ))) + if (!(res = no_at_strcmp( ename, name ))) return find_ordinal_export( module, exports, exp_size, ordinals[pos] ); if (res > 0) max = pos - 1; else min = pos + 1;