https://bugs.winehq.org/show_bug.cgi?id=46968
Bug ID: 46968 Summary: Pre-compiled fake .sys drivers are not copied when creating/updating WINEPREFIX (SIMATIC WinCC V15.1 Runtime installer) Product: Wine Version: 4.5 Hardware: x86-64 OS: Linux Status: NEW Severity: normal Priority: P2 Component: setupapi Assignee: wine-bugs@winehq.org Reporter: focht@gmx.net Distribution: ---
Hello folks,
split out of bug 46898 (https://bugs.winehq.org/show_bug.cgi?id=46898#c3).
The installer still fails with the stub 'ksecdd.sys' present.
--- snip --- $ WINEDEBUG=+seh,+relay,+msi,+version wine ./Start.exe >>log.txt 2>&1 ... 0087:Call KERNEL32.GetFullPathNameW(0032edb4 L"C:\windows\Sysnative\drivers\ksecdd.sys",00000105,0032eba8,00000000) ret=0036a1c3 0087:Ret KERNEL32.GetFullPathNameW() retval=00000027 ret=0036a1c3 ... 0087:Call KERNEL32.GetFileAttributesExW(00d70204 L"C:\windows\Sysnative\drivers\ksecdd.sys",00000000,0032f0a4) ret=0036bb1c 0087:Ret KERNEL32.GetFileAttributesExW() retval=00000001 ret=0036bb1c ... 0087:Call version.GetFileVersionInfoSizeW(00d70198 L"C:\windows\Sysnative\drivers\ksecdd.sys",0032f0e4) ret=03c507c9 ... 0087:Call KERNEL32.GetVersion() ret=7efeb65c 0087:Ret KERNEL32.GetVersion() retval=1db10106 ret=7efeb65c 0087:Ret version.GetFileVersionInfoSizeW() retval=00000000 ret=03c507c9 ... --- snip ---
Installer log:
--- snip --- ... 23:36:13|.. |CheckTerms::CheckTerms() |(01) TERM: '{Condition=([OS_VERSION_String]>=6.1 AND [OS_VERSION_String]<6.2 AND [OS_PLATFORM]='x64')};{File};{[WINDOWSFOLDER]Sysnative\drivers\ksecdd.sys};{=>};{6.1.7601.18741};{TermMessage44}' 23:36:13|.. |CheckTerms::CheckTerms() |(01) Condition='([OS_VERSION_String]>=6.1 AND [OS_VERSION_String]<6.2 AND [OS_PLATFORM]='x64')' 23:36:13|.. |CheckTerms::CheckTerms() |(01) Condition is fulfilled. Checking term... 23:36:13|... |CheckTerms::CheckFileTerm() |(01) File-Term: Exists: True; Path: C:\windows\Sysnative\drivers\ksecdd.sys 23:36:13|... |CheckTerms::CheckFileTerm() |(01) File-Term: Required file version: 06.01.7601.18741_00.00.00.00 23:36:13|... |CheckTerms::CheckFileTerm() |(01) File-Term: Current file version: 00.00.00.00_00.00.00.00 23:36:13|ERROR |CheckTerms::CheckFileTerm() |(01) File-Term. The term value {Condition=([OS_VERSION_String]>=6.1 AND [OS_VERSION_String]<6.2 AND [OS_PLATFORM]='x64')};{File};{[WINDOWSFOLDER]Sysnative\drivers\ksecdd.sys};{=>};{6.1.7601.18741};{TermMessage44} is not satisfied. 23:36:13|INFO1 |CheckTerms::AddMessage() |(01) Adding message to the Terms-FAILURE Dialog: TermMessage44 23:36:13|.. |CheckTerms::CheckTerms() |(01) 23:36:13|.. |CheckTerms::CheckTerms() |(01) TERM: '{Condition=([OS_VERSION_String]>=6.1 AND [OS_VERSION_String]<6.2 AND [OS_PLATFORM]='x32')};{File};{[SystemFolder]drivers\ksecdd.sys};{=>};{6.1.7601.18741};{TermMessage44}' 23:36:13|.. |CheckTerms::CheckTerms() |(01) Condition='([OS_VERSION_String]>=6.1 AND [OS_VERSION_String]<6.2 AND [OS_PLATFORM]='x32')' 23:36:13|.. |CheckTerms::CheckTerms() |(01) TERM will be ignored. TERM's condition is not fulfilled. ... --- snip ---
Wine source:
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/setupapi/fakedll.c#l9...
--- snip --- 950 /*********************************************************************** 951 * create_fake_dll 952 */ 953 BOOL create_fake_dll( const WCHAR *name, const WCHAR *source ) 954 { 955 HANDLE h; 956 BOOL ret; 957 SIZE_T size; 958 const WCHAR *filename; 959 void *buffer; 960 961 if (!(filename = strrchrW( name, '\' ))) filename = name; 962 else filename++; 963 964 /* check for empty name which means to only create the directory */ 965 if (!filename[0]) 966 { 967 create_directories( name ); 968 return TRUE; 969 } 970 if (filename[0] == '*' && !filename[1]) return create_wildcard_dlls( name ); 971 972 add_handled_dll( filename ); 973 974 if (!(h = create_dest_file( name ))) return TRUE; /* not a fake dll */ 975 if (h == INVALID_HANDLE_VALUE) return FALSE; 976 977 if (source[0] == '-' && !source[1]) 978 { 979 /* '-' source means delete the file */ 980 TRACE( "deleting %s\n", debugstr_w(name) ); 981 ret = FALSE; 982 } 983 else if ((buffer = load_fake_dll( source, &size ))) 984 { 985 DWORD written; 986 987 ret = (WriteFile( h, buffer, size, &written, NULL ) && written == size); 988 if (ret) register_fake_dll( name, buffer, size ); 989 else ERR( "failed to write to %s (error=%u)\n", debugstr_w(name), GetLastError() ); 990 } 991 else 992 { 993 WARN( "fake dll %s not found for %s\n", debugstr_w(source), debugstr_w(name) ); 994 ret = build_fake_dll( h, name ); 995 } 996 997 CloseHandle( h ); 998 if (!ret) DeleteFileW( name ); 999 return ret; 1000 } --- snip ---
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/setupapi/fakedll.c#l3...
--- snip --- 393 /* try to load a pre-compiled fake dll */ 394 static void *load_fake_dll( const WCHAR *name, SIZE_T *size ) 395 { 396 const char *build_dir = wine_get_build_dir(); 397 const char *path; 398 char *file, *ptr; 399 void *data = NULL; 400 unsigned int i, pos, len, namelen, maxlen = 0; 401 WCHAR *p; 402 int res = 0; 403 404 if ((p = strrchrW( name, '\' ))) name = p + 1; 405 406 i = 0; 407 len = strlenW( name ); 408 if (build_dir) maxlen = strlen(build_dir) + sizeof("/programs/") + len; 409 while ((path = wine_dll_enum_load_path( i++ ))) maxlen = max( maxlen, strlen(path) ); 410 maxlen += sizeof("/fakedlls") + len + sizeof(".fake"); 411 412 if (!(file = HeapAlloc( GetProcessHeap(), 0, maxlen ))) return NULL; 413 414 pos = maxlen - len - sizeof(".fake"); 415 if (!dll_name_WtoA( file + pos, name, len )) goto done; 416 file[--pos] = '/'; 417 418 if (build_dir) 419 { 420 strcpy( file + pos + len + 1, ".fake" ); 421 422 /* try as a dll */ 423 ptr = file + pos; 424 namelen = len + 1; 425 if (namelen > 4 && !memcmp( ptr + namelen - 4, ".dll", 4 )) namelen -= 4; 426 ptr = prepend( ptr, ptr, namelen ); 427 ptr = prepend( ptr, "/dlls", sizeof("/dlls") - 1 ); 428 ptr = prepend( ptr, build_dir, strlen(build_dir) ); 429 if ((res = read_file( ptr, &data, size ))) goto done; 430 431 /* now as a program */ 432 ptr = file + pos; 433 namelen = len + 1; 434 if (namelen > 4 && !memcmp( ptr + namelen - 4, ".exe", 4 )) namelen -= 4; 435 ptr = prepend( ptr, ptr, namelen ); 436 ptr = prepend( ptr, "/programs", sizeof("/programs") - 1 ); 437 ptr = prepend( ptr, build_dir, strlen(build_dir) ); 438 if ((res = read_file( ptr, &data, size ))) goto done; 439 } 440 441 file[pos + len + 1] = 0; 442 for (i = 0; (path = wine_dll_enum_load_path( i )); i++) 443 { 444 ptr = prepend( file + pos, "/fakedlls", sizeof("/fakedlls") - 1 ); 445 ptr = prepend( ptr, path, strlen(path) ); 446 if ((res = read_file( ptr, &data, size ))) break; 447 } 448 449 done: 450 HeapFree( GetProcessHeap(), 0, file ); 451 if (res == 1) return data; 452 return NULL; 453 } --- snip ---
'load_fake_dll' -> instead of taking the pre-compiled fake .sys driver from Wine 's installation directory, a new one is created on the fly via 'build_fake_dll'. These fake dlls don't contain a version resource by design, leading to installer failure.
$ sha1sum SIMATIC_WinCC_Runtime_Advanced_V15_1.exe db1f97bb648b62fa1c5d974d7f2bcb6b4a9fd786 SIMATIC_WinCC_Runtime_Advanced_V15_1.exe
$ du -sh SIMATIC_WinCC_Runtime_Advanced_V15_1.exe 1.3G SIMATIC_WinCC_Runtime_Advanced_V15_1.exe
$ wine --version wine-4.5-222-g8ee1e3453e
Regards