[Bug 48455] New: Native Instruments Native Access 1.9 installer hangs during installation of ISO Mounter driver (missing handling of architecture-specific SourceDisks{Names,Files} .inf sections)

WineHQ Bugzilla wine-bugs at winehq.org
Sun Jan 12 16:26:23 CST 2020


https://bugs.winehq.org/show_bug.cgi?id=48455

            Bug ID: 48455
           Summary: Native Instruments Native Access 1.9 installer hangs
                    during installation of ISO Mounter driver (missing
                    handling of architecture-specific
                    SourceDisks{Names,Files} .inf sections)
           Product: Wine
           Version: 5.0-rc5
          Hardware: x86-64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: setupapi
          Assignee: wine-bugs at winehq.org
          Reporter: focht at gmx.net
      Distribution: ---

Hello folks,

as it says. The driver sub-installer just hangs (churning cpu), blocking the
main installer forever.

Stable download link via Internet Archive:

https://web.archive.org/web/20190227215247/https://www.native-instruments.com/fileadmin/downloads/Native_Access_Installer.zip

--- snip ---
$ wine ./Native\ Access\ 1.9.1\ Setup\ PC.exe
...
--- snip ---

Reduced case by calling driver sub-installer directly, after killing main
installer:

--- snip ---
$ pwd
/home/focht/.wine/drive_c/Program Files (x86)/Native Instruments/IsoDriver/x64

$ WINEDEBUG=+seh,+relay,+loaddll,+process,+setupapi wine ./NI-drvinst.exe
instroot "root\NIWinCDEmu" "C:\Program Files (x86)\Native
Instruments\IsoDriver\NIWinCDEmu.inf" >>log.txt 2>&1
...
002d:trace:setupapi:SetupDiInstallDriverFiles devinfo 000000000011C1C0,
device_data 000000000022F6C0. 
...
002d:trace:setupapi:SetupOpenInfFileW L"C:\\Program Files (x86)\\Native
Instruments\\IsoDriver\\NIWinCDEmu.inf" -> 000000000011D990 
...
002d:trace:setupapi:SetupGetStringFieldW context
000000000011D990/000000000011D990/9/0 index 1 returning L"Drivers_Dir" 
...
002d:trace:setupapi:SetupQueueCopySectionW queue 000000000011DDD0, src_root
L"C:\\Program Files (x86)\\Native Instruments\\IsoDriver", hinf
000000000011D990, hlist 000000000011D990, section L"Drivers_Dir", style
0x10000. 
...
002d:trace:setupapi:SetupQueueCopyIndirectW root=L"C:\\Program Files
(x86)\\Native Instruments\\IsoDriver" path=(null) file=L"NIWinCDEmu.sys" ->
dir=L"C:\\windows\\system32\\drivers" file=L"NIWinCDEmu.sys"  descr=(null)
tag=(null)
...
002d:trace:setupapi:SetupDefaultQueueCallbackW start copy L"C:\\Program Files
(x86)\\Native Instruments\\IsoDriver\\NIWinCDEmu.sys" ->
L"C:\\windows\\system32\\drivers\\NIWinCDEmu.sys"
...
002d:trace:setupapi:queue_copy_file copying file L"C:\\Program Files
(x86)\\Native Instruments\\IsoDriver\\NIWinCDEmu.sys" ->
L"C:\\windows\\system32\\drivers\\NIWinCDEmu.sys" 
...
002d:trace:setupapi:do_file_copyW copy L"C:\\Program Files (x86)\\Native
Instruments\\IsoDriver\\NIWinCDEmu.sys" to
L"C:\\windows\\system32\\drivers\\NIWinCDEmu.sys" style 0x10000
002d:Call KERNEL32.GetFileAttributesW(006fd540
L"C:\\windows\\system32\\drivers\\NIWinCDEmu.sys") ret=00259e09
...
002d:Ret  KERNEL32.GetFileAttributesW() retval=ffffffff ret=00259e09
002d:Call KERNEL32.CopyFileW(006fd4a0 L"C:\\Program Files (x86)\\Native
Instruments\\IsoDriver\\NIWinCDEmu.sys",006fd540
L"C:\\windows\\system32\\drivers\\NIWinCDEmu.sys",00000000) ret=0025a064
....
002d:Call
ntdll.NtCreateFile(0022e100,80100080,0022e128,0022e118,00000000,00000000,00000007,00000001,00000060,00000000,00000000)
ret=7b0110a1
002d:Ret  ntdll.NtCreateFile() retval=c0000034 ret=7b0110a1
002d:Call ntdll.RtlNtStatusToDosError(c0000034) ret=7b011190
002d:Ret  ntdll.RtlNtStatusToDosError() retval=00000002 ret=7b011190
...
002d:Ret  KERNEL32.CopyFileW() retval=00000000 ret=0025a064
002d:warn:setupapi:do_file_copyW failed to copy, err 2 
...
<repeats endlessly>
...
002d:trace:setupapi:SetupDefaultQueueCallbackW need media L"C:\\Program Files
(x86)\\Native Instruments\\IsoDriver" L"NIWinCDEmu.sys"
...
002d:trace:setupapi:SetupDefaultQueueCallbackW start copy L"C:\\Program Files
(x86)\\Native Instruments\\IsoDriver\\NIWinCDEmu.sys" ->
L"C:\\windows\\system32\\drivers\\NIWinCDEmu.sys" 
...
--- snip ---

Content of 'NIWinCDEmu.inf':

--- snip ---
[Version]
Signature="$WINDOWS NT$"
Class=SCSIAdapter
ClassGuid={4d36e97b-e325-11ce-bfc1-08002be10318}
Provider=%NI_MFNAME%
DriverVer= 08/05/2011, 1.0.0.2
CatalogFile=NIWinCDEmu.cat

[DestinationDirs]
DefaultDestDir = 12

[SourceDisksNames.x86]
1 = %DiskId1%,,,

[SourceDisksNames.amd64]
1 = %DiskId1%,,,

[SourceDisksFiles.x86]
NIWinCDEmu.sys  = 1,\x86

[SourceDisksFiles.amd64]
NIWinCDEmu.sys  = 1,\x64

[Manufacturer]
%NI_MFNAME%=Standard, NTamd64

[Standard]
%NIWinCDEmu.DeviceDesc%=NIWinCDEmu_Device, root\NIWinCDEmu

[Standard.NTamd64]
%NIWinCDEmu.DeviceDesc%=NIWinCDEmu_Device, root\NIWinCDEmu

[NIWinCDEmu_Device.NT]
CopyFiles=Drivers_Dir

[Drivers_Dir]
NIWinCDEmu.sys,,,2

;-------------- Service installation
[NIWinCDEmu_Device.NT.Services]
AddService = NIWinCDEmu,%SPSVCINST_ASSOCSERVICE%, dev_Service_Inst

; -------------- busenum driver install sections
[dev_Service_Inst]
DisplayName    = %dev.SVCDESC%
ServiceType    = 1               ; SERVICE_KERNEL_DRIVER
StartType      = 3               ; SERVICE_DEMAND_START 
ErrorControl   = 1               ; SERVICE_ERROR_NORMAL
ServiceBinary  = %12%\NIWinCDEmu.sys
LoadOrderGroup = Extended Base


[Strings]
SPSVCINST_ASSOCSERVICE= 0x00000002
NI_MFNAME = "Native Instruments GmbH"
DiskId1 = "ISO Mounter Installation Disk #1"
NIWinCDEmu.DeviceDesc = "ISO Mounter"
dev.SVCDESC = "ISO Mounter driver" 
--- snip ---

The problem here is that Wine's 'get_source_info' doesn't take
architecture-specific 'SourceDisksNames' and 'SourceDisksFiles' .inf sections
into account.

Wine source:

https://source.winehq.org/git/wine.git/blob/b3abc343c373ee5fd0764a3ceedeef52589c0ab2:/dlls/setupapi/queue.c#l289

--- snip ---
 289 static void get_source_info( HINF hinf, const WCHAR *src_file,
SP_FILE_COPY_PARAMS_W *params,
 290                              WCHAR *src_root, WCHAR *src_path)
 291 {
 292     static const WCHAR SourceDisksNames[] =
 293        
{'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s',0};
 294     static const WCHAR SourceDisksFiles[] =
 295        
{'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};
 296 
 297     INFCONTEXT file_ctx, disk_ctx;
 298     INT id, diskid;
 299     DWORD len;
 300 
 301     /* find the SourceDisksFiles entry */
 302     if (!SetupFindFirstLineW( hinf, SourceDisksFiles, src_file, &file_ctx
)) return;
 303     if (!SetupGetIntField( &file_ctx, 1, &diskid )) return;
 304 
 305     /* now find the diskid in the SourceDisksNames section */
 306     if (!SetupFindFirstLineW( hinf, SourceDisksNames, NULL, &disk_ctx ))
return;
 307     for (;;)
 308     {
 309         if (SetupGetIntField( &disk_ctx, 0, &id ) && (id == diskid))
break;
 310         if (!SetupFindNextLine( &disk_ctx, &disk_ctx )) return;
 311     }
 312 
 313     if (SetupGetStringFieldW( &disk_ctx, 1, NULL, 0, &len ) && len >
sizeof(WCHAR)
 314             && (params->SourceDescription = heap_alloc( len *
sizeof(WCHAR) )))
 315         SetupGetStringFieldW( &disk_ctx, 1, (WCHAR
*)params->SourceDescription, len, NULL );
 316 
 317     if (SetupGetStringFieldW( &disk_ctx, 2, NULL, 0, &len ) && len >
sizeof(WCHAR)
 318             && (params->SourceTagfile = heap_alloc( len * sizeof(WCHAR)
)))
 319         SetupGetStringFieldW( &disk_ctx, 2, (WCHAR
*)params->SourceTagfile, len, NULL );
 320 
 321     if (SetupGetStringFieldW( &disk_ctx, 4, NULL, 0, &len ) && len >
sizeof(WCHAR)
 322             && len < MAX_PATH - lstrlenW( src_root ) - 1)
 323     {
 324         lstrcatW( src_root, backslashW );
 325         SetupGetStringFieldW( &disk_ctx, 4, src_root + lstrlenW( src_root
),
 326                               MAX_PATH - lstrlenW( src_root ), NULL );
 327     }
 328 
 329     if (SetupGetStringFieldW( &file_ctx, 2, NULL, 0, &len ) && len >
sizeof(WCHAR) && len < MAX_PATH)
 330     {
 331         SetupGetStringFieldW( &file_ctx, 2, src_path, MAX_PATH, NULL );
 332         params->SourcePath = src_path;
 333     }
 334 }
--- snip ---

Microsoft docs:

https://docs.microsoft.com/en-us/windows-hardware/drivers/install/inf-sourcedisksfiles-section

--- quote ----
...
To support distribution of driver files on multiple system architectures, you
can specify an architecture-specific SourceDisksFiles section by adding an
.x86, .ia64, .amd64, .arm, or .arm64 extension to SourceDisksFiles. Be aware
that, unlike other sections such as a DDInstall section, the platform
extensions for a SourceDisksFiles section are not .ntx86, .ntia64, or .ntamd64.

For example, to specify a source disk names section for an x86-based system,
use a SourceDisksFiles.x86 section, not a SourceDisksFiles.ntx86 section.
Similarly, use a SourceDisksFiles.ia64 section to specify an Itanium-based
system and a SourceDisksFiles.amd64 section to specify an x64-based system.

During installation, SetupAPI functions look for architecture-specific
SourceDisksFiles sections before using the generic section. For example, if,
during installation on an x86-based platform, Windows is copying a file that is
named driver.sys, it will look for the file's description in
[SourceDisksFiles.x86] before looking in [SourceDisksFiles].
--- quote ----

In contrast, 'get_source_id' does it properly:

https://source.winehq.org/git/wine.git/blob/f1b94dc16c35a5c477b6df8aa94c6d3537642c77:/dlls/setupapi/query.c#l372

--- snip ---
 372 static LPWSTR get_source_id( HINF hinf, PINFCONTEXT context, PCWSTR
filename )
 373 {
 374     DWORD size;
 375     LPWSTR source_id;
 376 
 377     if (!SetupFindFirstLineW( hinf, source_disks_files_platform, filename,
context ) &&
 378         !SetupFindFirstLineW( hinf, source_disks_files, filename, context
))
 379         return NULL;
 380 
 381     if (!SetupGetStringFieldW( context, 1, NULL, 0, &size ))
 382         return NULL;
 383 
 384     if (!(source_id = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR)
)))
 385         return NULL;
 386 
 387     if (!SetupGetStringFieldW( context, 1, source_id, size, NULL ))
 388     {
 389         HeapFree( GetProcessHeap(), 0, source_id );
 390         return NULL;
 391     }
 392 
 393     if (!SetupFindFirstLineW( hinf, source_disks_names_platform,
source_id, context ) &&
 394         !SetupFindFirstLineW( hinf, source_disks_names, source_id, context
))
 395     {
 396         HeapFree( GetProcessHeap(), 0, source_id );
 397         return NULL;
 398     }
 399     return source_id;
 400 }
--- snip ---

$ sha1sum Native*
374f62fb373ceb02527b8a179c7e305268bab25c  Native Access 1.9.1 Setup PC.exe
5a78d5850267d0ef6701bc5da7dc25e5b62b6031  Native_Access_Installer.zip

$ du -sh Native*
70M    Native Access 1.9.1 Setup PC.exe
69M    Native_Access_Installer.zip

$ wine --version
wine-5.0-rc5

Regards

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.


More information about the wine-bugs mailing list