http://bugs.winehq.org/show_bug.cgi?id=31087
Bug #: 31087 Summary: WMI class property retrieval: some CIM data type to OLE variant (VT) mappings are incorrect (CIM_UINT32, CIM_UINT16 ...) Product: Wine Version: 1.5.7 Platform: x86 OS/Version: Linux Status: NEW Severity: normal Priority: P2 Component: wmi&wbemprox AssignedTo: wine-bugs@winehq.org ReportedBy: focht@gmx.net Classification: Unclassified
Hello,
another problem from app in bug 24875 which deserves an extra bug.
The app still fails with wine-1.5.7-252-g1f01355
The problems seems to be a WMI -> .NET type conversion problem of "ProcessId" property value.
"InvalidCastException" is thrown
--- snip --- 006ee1e8 7b83953f [HelperMethodFrame: 006ee1e8] 006ee258 040347f6 System.Management.PropertyData.MapWmiValueToValue(System.Object, System.Management.CimType, Boolean) 006ee2d0 04034204 System.Management.PropertyData.get_Value() 006ee2dc 04033aa6 System.Management.ManagementBaseObject.GetPropertyValue(System.String) 006ee2e8 04033a35 System.Management.ManagementBaseObject.get_Item(System.String) 006ee2ec 04034f70 SSCustomInstaller.SSInstaller.GetSongsmithSetupPathAndCopyMSI() 006ee31c 04034c0f SSCustomInstaller.SSInstaller.Install(System.Collections.IDictionary) 006ee350 649e3fc6 System.Configuration.Install.Installer.Install(System.Collections.IDictionary) 006ee398 649e5d38 System.Configuration.Install.AssemblyInstaller.Install(System.Collections.IDictionary) 006ee3d0 649e7f6e System.Configuration.Install.ManagedInstallerClass.InstallHelper(System.String[]) 006ee494 649e7734 System.Configuration.Install.ManagedInstallerClass.System.Configuration.Install.IManagedInstaller.ManagedInstall(System.String, Int32) --- snip ---
MapWmiValueToValue converts WMI values (wrapped in object) to native .NET value (wrapped in object) with type conversion if necessary.
MSDN claims "ProcessId" is CIM_UINT32/uint32.
The following link shows example "ProcessId" property dump with 'wbemdump' tool:
http://nukz.net/reference/wmi/hh/wmisdk/wbemdump_8wft.htm
--- snip --- wbemdump /Q /wy root\cimv2 WQL "SELECT ProcessId FROM Win32_process WHERE Name = 'Winmgmt.exe'"
This command produces the following output:
(WQL) SELECT ProcessId FROM Win32_Process WHERE Name = 'Winmgmt.exe'
ProcessId (CIM_UINT32/uint32) = 644 (0x284) --- snip ---
For CIM_UINT32 type there seems to be 'unboxing' taking place:
net_value = (uint)((int)(wmi_value))
I extracted a small C# snippet from the app .NET assembly which can be used for easy reproduction of the problem.
Save the following snippet to a text file (ex: "test.cs"):
--- snip test.cs --- using System; using System.Collections; using System.Management;
class TestProgram { [STAThread] static void Main(string[] args) { using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * from Win32_Process")) { new ManagementScope(@"root\CIMV2"); foreach (ManagementObject obj2 in searcher.Get()) { string str = obj2["ProcessId"].ToString(); } } } } --- snip test.cs ---
Compile it with C# compiler which is present if you installed .NET 2.0 Framework (winetricks).
--- snip --- $ wine "C:\windows\Microsoft.NET\Framework\v2.0.50727\csc.exe" /debug+ test.cs --- snip ---
Run and get the same backtrace as with installer.
The problem is CIMTYPE -> OLE Variant type conversion.
Source: http://source.winehq.org/git/wine.git/blob/d2661b802556e073760af5d70869fb55a...
--- snip --- 665 HRESULT get_propval( const struct view *view, UINT index, const WCHAR *name, VARIANT *ret, 666 CIMTYPE *type, LONG *flavor ) 667 { ... 681 switch (view->table->columns[column].type & COL_TYPE_MASK) 682 { 683 case CIM_STRING: 684 case CIM_DATETIME: 685 V_VT( ret ) = VT_BSTR; 686 V_BSTR( ret ) = SysAllocString( (const WCHAR *)(INT_PTR)val ); 687 break; 688 case CIM_SINT16: 689 V_VT( ret ) = VT_I2; 690 V_I2( ret ) = val; 691 break; 692 case CIM_UINT16: 693 V_VT( ret ) = VT_UI2; 694 V_UI2( ret ) = val; 695 break; 696 case CIM_SINT32: 697 V_VT( ret ) = VT_I4; 698 V_I4( ret ) = val; 699 break; 700 case CIM_UINT32: 701 V_VT( ret ) = VT_UI4; 702 V_UI4( ret ) = val; 703 break; 704 case CIM_SINT64: 705 V_VT( ret ) = VT_BSTR; 706 V_BSTR( ret ) = get_value_bstr( view->table, row, column ); 707 break; 708 case CIM_UINT64: 709 V_VT( ret ) = VT_BSTR; 710 V_BSTR( ret ) = get_value_bstr( view->table, row, column ); 711 break; ... --- snip ---
The unbox failure let me guess that CIM_UINT32 doesn't map to VT_UI4 but to VT_I4. Google "CIM_UINT32 VT_I4" and hit the first link -> book "Developing Wmi Solutions: A Guide to Windows Management ..." Bingo! There is a table which shows the type mapping (BTW good WMI resource to read...)
uint32 - VT_I4 - CIM_UINT32
While you're at it you might want to fix other type conversions (CIM_UINT16 ...) according to the table.
Regards