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. 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 20:44:22 -0000 @@ -21,6 +21,7 @@ #include <assert.h> #include <stdarg.h> +#include <ctype.h> #include "windef.h" #include "winbase.h" @@ -283,6 +284,50 @@ 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 */ + return 0; + } + + if (*a != *b) + return *a - *b; + + a++; + b++; + } while (1); +} /************************************************************************* * find_named_export @@ -301,7 +346,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 +355,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;