From 7acd74ee0743974b5e500f43d340560899ba9eee Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 15 Oct 2009 13:53:14 +0200 Subject: [PATCH] setupapi: Add support for using a wildcard in fake dll creation. This creates fake dlls for all the files we can't find and that haven't been created already. --- dlls/setupapi/fakedll.c | 121 ++++++++++++++++++++++++++++++++++++++++ tools/wine.inf.in | 78 +------------------------- 2 files changed, 123 insertions(+), 76 deletions(-) diff --git a/dlls/setupapi/fakedll.c b/dlls/setupapi/fakedll.c index fa89acea019..6397950ff41 100644 --- a/dlls/setupapi/fakedll.c +++ b/dlls/setupapi/fakedll.c @@ -23,6 +23,9 @@ #include #include +#ifdef HAVE_DIRENT_H +# include +#endif #ifdef HAVE_SYS_STAT_H # include #endif @@ -49,6 +52,7 @@ static const char fakedll_signature[] = "Wine placeholder DLL"; static const unsigned int file_alignment = 512; static const unsigned int section_alignment = 4096; +static const unsigned int max_dll_name_len = 64; static void *file_buffer; static size_t file_buffer_size; @@ -127,6 +131,16 @@ static char *dll_name_WtoA( char *nameA, const WCHAR *nameW, unsigned int len ) return nameA; } +/* convert a dll name A->W without depending on the current codepage */ +static WCHAR *dll_name_AtoW( WCHAR *nameW, const char *nameA, unsigned int len ) +{ + unsigned int i; + + for (i = 0; i < len; i++) nameW[i] = nameA[i]; + nameW[i] = 0; + return nameW; +} + /* add a dll to the list of dll that have been taken care of */ static BOOL add_handled_dll( const WCHAR *name ) { @@ -451,6 +465,111 @@ static HANDLE create_dest_file( const WCHAR *name ) return h; } +/* copy a fake dll file to the dest directory */ +static void install_fake_dll( WCHAR *dest, char *file, const char *ext ) +{ + int ret; + size_t size; + void *data; + DWORD written; + WCHAR *destname = dest + strlenW(dest); + char *name = strrchr( file, '/' ) + 1; + char *end = name + strlen(name); + + if (ext) strcpy( end, ext ); + if (!(ret = read_file( file, &data, &size ))) return; + + if (end > name + 2 && !strncmp( end - 2, "16", 2 )) end -= 2; /* remove "16" suffix */ + dll_name_AtoW( destname, name, end - name ); + if (!add_handled_dll( destname )) ret = -1; + + if (ret != -1) + { + HANDLE h = create_dest_file( dest ); + + if (h && h != INVALID_HANDLE_VALUE) + { + TRACE( "%s -> %s\n", debugstr_a(file), debugstr_w(dest) ); + + ret = (WriteFile( h, data, size, &written, NULL ) && written == size); + if (!ret) ERR( "failed to write to %s (error=%u)\n", debugstr_w(dest), GetLastError() ); + CloseHandle( h ); + if (!ret) DeleteFileW( dest ); + } + } + *destname = 0; /* restore it for next file */ +} + +/* find and install all fake dlls in a given lib directory */ +static void install_lib_dir( WCHAR *dest, char *file, const char *default_ext ) +{ + DIR *dir; + struct dirent *de; + char *name; + + if (!(dir = opendir( file ))) return; + name = file + strlen(file); + *name++ = '/'; + while ((de = readdir( dir ))) + { + if (strlen( de->d_name ) > max_dll_name_len) continue; + if (!strcmp( de->d_name, "." )) continue; + if (!strcmp( de->d_name, ".." )) continue; + strcpy( name, de->d_name ); + if (default_ext) /* inside build dir */ + { + strcat( name, "/" ); + strcat( name, de->d_name ); + if (!strchr( de->d_name, '.' )) strcat( name, default_ext ); + install_fake_dll( dest, file, ".fake" ); + } + else install_fake_dll( dest, file, NULL ); + } + closedir( dir ); +} + +/* create fake dlls in dirname for all the files we can find */ +static BOOL create_wildcard_dlls( const WCHAR *dirname ) +{ + const char *build_dir = wine_get_build_dir(); + const char *path; + unsigned int i, maxlen = 0; + char *file; + WCHAR *dest; + + if (build_dir) maxlen = strlen(build_dir) + sizeof("/programs/"); + for (i = 0; (path = wine_dll_enum_load_path(i)); i++) maxlen = max( maxlen, strlen(path) ); + maxlen += 2 * max_dll_name_len + 2 + sizeof(".dll.fake"); + if (!(file = HeapAlloc( GetProcessHeap(), 0, maxlen ))) return FALSE; + + if (!(dest = HeapAlloc( GetProcessHeap(), 0, (strlenW(dirname) + max_dll_name_len) * sizeof(WCHAR) ))) + { + HeapFree( GetProcessHeap(), 0, file ); + return FALSE; + } + strcpyW( dest, dirname ); + dest[strlenW(dest) - 1] = 0; /* remove wildcard */ + + if (build_dir) + { + strcpy( file, build_dir ); + strcat( file, "/dlls" ); + install_lib_dir( dest, file, ".dll" ); + strcpy( file, build_dir ); + strcat( file, "/programs" ); + install_lib_dir( dest, file, ".exe" ); + } + for (i = 0; (path = wine_dll_enum_load_path( i )); i++) + { + strcpy( file, path ); + strcat( file, "/fakedlls" ); + install_lib_dir( dest, file, NULL ); + } + HeapFree( GetProcessHeap(), 0, file ); + HeapFree( GetProcessHeap(), 0, dest ); + return TRUE; +} + /*********************************************************************** * create_fake_dll */ @@ -471,6 +590,8 @@ BOOL create_fake_dll( const WCHAR *name, const WCHAR *source ) create_directories( name ); return TRUE; } + if (filename[0] == '*' && !filename[1]) return create_wildcard_dlls( name ); + add_handled_dll( filename ); if (!(h = create_dest_file( name ))) return TRUE; /* not a fake dll */ diff --git a/tools/wine.inf.in b/tools/wine.inf.in index 6b6acf91616..9f0a2dee891 100644 --- a/tools/wine.inf.in +++ b/tools/wine.inf.in @@ -2446,93 +2446,19 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 10,,hh.exe 10,,notepad.exe 10,,regedit.exe +10,,twain.dll,twain.dll16 10,,twain_32.dll 10,,winhelp.exe,winhelp.exe16 10,,winhlp32.exe 10,command,start.exe -11,,actxprxy.dll -11,,advapi32.dll -11,,advpack.dll -11,,appwiz.cpl -11,,cabinet.dll -11,,cmd.exe -11,,comctl32.dll -11,,comdlg32.dll -11,,control.exe -11,,crypt32.dll -11,,d3d8.dll -11,,d3d9.dll -11,,dbghelp.dll -11,,ddeml.dll,ddeml.dll16 11,,ddhelp.exe -11,,ddraw.dll -11,,dinput8.dll 11,,dosx.exe -11,,dsound.dll 11,,dsound.vxd -11,,dxdiagn.dll -11,,gdi32.dll -11,,glu32.dll -11,,hal.dll -11,,hhctrl.ocx -11,,imaadp32.acm -11,,imagehlp.dll -11,,itircl.dll -11,,itss.dll -11,,kernel32.dll -11,,mapi32.dll -11,,msadp32.acm -11,,msg711.acm -11,,msgsm32.acm -11,,mshtml.dll -11,,msi.dll -11,,msiexec.exe -11,,msvcrt.dll -11,,msxml3.dll 11,,notepad.exe -11,,ntdll.dll -11,,ntoskrnl.exe -11,,ole32.dll -11,,oleaut32.dll -11,,oledlg.dll -11,,olepro32.dll -11,,opengl32.dll -11,,progman.exe -11,,psapi.dll -11,,pstorec.dll -11,,quartz.dll -11,,regsvr32.exe -11,,reg.exe -11,,riched20.dll -11,,riched32.dll -11,,rpcrt4.dll -11,,rsabase.dll -11,,rsaenh.dll -11,,rundll32.exe -11,,schannel.dll -11,,sensapi.dll -11,,setupapi.dll -11,,shdocvw.dll -11,,shell32.dll -11,,shfolder.dll -11,,shlwapi.dll -11,,stdole2.tlb -11,,urlmon.dll -11,,user32.dll -11,,version.dll -11,,windowscodecs.dll -11,,winebrowser.exe 11,,winhlp32.exe -11,,wininet.dll -11,,winmm.dll -11,,winspool.drv -11,,wintab32.dll -11,,winver.exe -11,,wordpad.exe -11,,ws2_32.dll -11,,wsock32.dll 12,,mountmgr.sys 16422,Internet Explorer,iexplore.exe +11,,* [SystemIni] system.ini, mci,,"MPEGVideo=mciqtz32.dll"