[WBEMPROX] Sync with Wine Staging 4.18. CORE-16441
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 1 Dec 2019 18:45:00 +0000 (19:45 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 1 Dec 2019 18:45:00 +0000 (19:45 +0100)
18 files changed:
dll/win32/wbemprox/builtin.c
dll/win32/wbemprox/class.c
dll/win32/wbemprox/main.c
dll/win32/wbemprox/precomp.h
dll/win32/wbemprox/process.c
dll/win32/wbemprox/qualifier.c
dll/win32/wbemprox/query.c
dll/win32/wbemprox/reg.c
dll/win32/wbemprox/security.c
dll/win32/wbemprox/service.c
dll/win32/wbemprox/services.c
dll/win32/wbemprox/table.c
dll/win32/wbemprox/wbemlocator.c
dll/win32/wbemprox/wbemprox_private.h
dll/win32/wbemprox/wql.tab.c
dll/win32/wbemprox/wql.tab.h
dll/win32/wbemprox/wql.y
media/doc/README.WINE

index 5f68963..b92231c 100644 (file)
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
 
-#include "config.h"
 #include <stdarg.h>
-#include <fcntl.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
+#ifdef __REACTOS__
+#include <wchar.h>
 #endif
 
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
 #include "windef.h"
 #include "winbase.h"
-#ifdef __MINGW32__
-# include "winsock2.h"
-# include "ws2tcpip.h"
-# define WS_AF_INET AF_INET
-# define WS_AF_UNSPEC AF_UNSPEC
-# define WS_NI_MAXHOST NI_MAXHOST
-# define WS_NI_NAMEREQD NI_NAMEREQD
-#else
-# define USE_WS_PREFIX
-# include "winsock2.h"
-# include "ws2tcpip.h"
-#endif
+#include "winsock2.h"
+#include "ws2tcpip.h"
 #include "initguid.h"
 #include "wbemcli.h"
 #include "wbemprov.h"
 #include "winspool.h"
 #include "setupapi.h"
 
+#include "wine/asm.h"
 #include "wine/debug.h"
 #include "wbemprox_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
 
+static const WCHAR class_associatorsW[] =
+    {'_','_','A','S','S','O','C','I','A','T','O','R','S',0};
 static const WCHAR class_baseboardW[] =
     {'W','i','n','3','2','_','B','a','s','e','B','o','a','r','d',0};
 static const WCHAR class_biosW[] =
@@ -91,20 +79,27 @@ static const WCHAR class_directoryW[] =
     {'W','i','n','3','2','_','D','i','r','e','c','t','o','r','y',0};
 static const WCHAR class_diskdriveW[] =
     {'W','i','n','3','2','_','D','i','s','k','D','r','i','v','e',0};
+static const WCHAR class_diskdrivetodiskpartitionW[] =
+    {'W','i','n','3','2','_','D','i','s','k','D','r','i','v','e','T','o','D','i','s','k','P','a','r','t','i','t','i','o','n',0};
 static const WCHAR class_diskpartitionW[] =
     {'W','i','n','3','2','_','D','i','s','k','P','a','r','t','i','t','i','o','n',0};
+static const WCHAR class_displaycontrollerconfigW[] =
+    {'W','i','n','3','2','_','D','i','s','p','l','a','y','C','o','n','t','r','o','l','l','e','r',
+     'C','o','n','f','i','g','u','r','a','t','i','o','n',0};
 static const WCHAR class_ip4routetableW[] =
     {'W','i','n','3','2','_','I','P','4','R','o','u','t','e','T','a','b','l','e',0};
 static const WCHAR class_logicaldiskW[] =
     {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k',0};
 static const WCHAR class_logicaldisk2W[] =
     {'C','I','M','_','L','o','g','i','c','a','l','D','i','s','k',0};
+static const WCHAR class_logicaldisktopartitionW[] =
+    {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',0};
 static const WCHAR class_networkadapterW[] =
     {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',0};
 static const WCHAR class_networkadapterconfigW[] =
     {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',
      'C','o','n','f','i','g','u','r','a','t','i','o','n',0};
-static const WCHAR class_osW[] =
+static const WCHAR class_operatingsystemW[] =
     {'W','i','n','3','2','_','O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
 static const WCHAR class_paramsW[] =
     {'_','_','P','A','R','A','M','E','T','E','R','S',0};
@@ -125,6 +120,8 @@ static const WCHAR class_processor2W[] =
     {'C','I','M','_','P','r','o','c','e','s','s','o','r',0};
 static const WCHAR class_qualifiersW[] =
     {'_','_','Q','U','A','L','I','F','I','E','R','S',0};
+static const WCHAR class_quickfixengineeringW[] =
+    {'W','i','n','3','2','_','Q','u','i','c','k','F','i','x','E','n','g','i','n','e','e','r','i','n','g',0};
 static const WCHAR class_sidW[] =
     {'W','i','n','3','2','_','S','I','D',0};
 static const WCHAR class_sounddeviceW[] =
@@ -135,6 +132,8 @@ static const WCHAR class_systemenclosureW[] =
 static const WCHAR class_videocontrollerW[] =
     {'W','i','n','3','2','_','V','i','d','e','o','C','o','n','t','r','o','l','l','e','r',0};
 #endif
+static const WCHAR class_winsatW[] =
+    {'W','i','n','3','2','_','W','i','n','S','A','T',0};
 
 static const WCHAR prop_accountnameW[] =
     {'A','c','c','o','u','n','t','N','a','m','e',0};
@@ -152,10 +151,18 @@ static const WCHAR prop_adapterramW[] =
 #endif
 static const WCHAR prop_adaptertypeW[] =
     {'A','d','a','p','t','e','r','T','y','p','e',0};
+static const WCHAR prop_adaptertypeidW[] =
+    {'A','d','a','p','t','e','r','T','y','p','e','I','D',0};
 static const WCHAR prop_addresswidthW[] =
     {'A','d','d','r','e','s','s','W','i','d','t','h',0};
+static const WCHAR prop_antecedentW[] =
+    {'A','n','t','e','c','e','d','e','n','t',0};
 static const WCHAR prop_architectureW[] =
     {'A','r','c','h','i','t','e','c','t','u','r','e',0};
+static const WCHAR prop_assocclassW[] =
+    {'A','s','s','o','c','C','l','a','s','s',0};
+static const WCHAR prop_associatorW[] =
+    {'A','s','s','o','c','i','a','t','o','r',0};
 static const WCHAR prop_attributesW[] =
     {'A','t','t','r','i','b','u','t','e','s',0};
 #ifndef __REACTOS__
@@ -164,6 +171,10 @@ static const WCHAR prop_availabilityW[] =
 #endif
 static const WCHAR prop_binaryrepresentationW[] =
     {'B','i','n','a','r','y','R','e','p','r','e','s','e','n','t','a','t','i','o','n',0};
+static const WCHAR prop_bitsperpixelW[] =
+    {'B','i','t','s','P','e','r','P','i','x','e','l',0};
+static const WCHAR prop_boolvalueW[] =
+    {'B','o','o','l','V','a','l','u','e',0};
 static const WCHAR prop_bootableW[] =
     {'B','o','o','t','a','b','l','e',0};
 static const WCHAR prop_bootpartitionW[] =
@@ -184,44 +195,60 @@ static const WCHAR prop_commandlineW[] =
     {'C','o','m','m','a','n','d','L','i','n','e',0};
 static const WCHAR prop_configmanagererrorcodeW[] =
     {'C','o','n','f','i','g','M','a','n','a','g','e','r','E','r','r','o','r','C','o','d','e',0};
+static const WCHAR prop_configuredclockspeedW[] =
+    {'C','o','n','f','i','g','u','r','e','d','C','l','o','c','k','S','p','e','e','d',0};
 static const WCHAR prop_countrycodeW[] =
     {'C','o','u','n','t','r','y','C','o','d','e',0};
+static const WCHAR prop_cpuscoreW[] =
+    {'C','P','U','S','c','o','r','e',0};
 static const WCHAR prop_cpustatusW[] =
     {'C','p','u','S','t','a','t','u','s',0};
 static const WCHAR prop_csdversionW[] =
     {'C','S','D','V','e','r','s','i','o','n',0};
+static const WCHAR prop_csnameW[] =
+    {'C','S','N','a','m','e',0};
 #ifndef __REACTOS__
 static const WCHAR prop_currentbitsperpixelW[] =
     {'C','u','r','r','e','n','t','B','i','t','s','P','e','r','P','i','x','e','l',0};
 #endif
 static const WCHAR prop_currentclockspeedW[] =
     {'C','u','r','r','e','n','t','C','l','o','c','k','S','p','e','e','d',0};
-#ifndef __REACTOS__
 static const WCHAR prop_currenthorizontalresW[] =
     {'C','u','r','r','e','n','t','H','o','r','i','z','o','n','t','a','l','R','e','s','o','l','u','t','i','o','n',0};
+static const WCHAR prop_currentlanguageW[] =
+    {'C','u','r','r','e','n','t','L','a','n','g','u','a','g','e',0};
 static const WCHAR prop_currentrefreshrateW[] =
     {'C','u','r','r','e','n','t','R','e','f','r','e','s','h','R','a','t','e',0};
 static const WCHAR prop_currentscanmodeW[] =
     {'C','u','r','r','e','n','t','S','c','a','n','M','o','d','e',0};
+static const WCHAR prop_currenttimezoneW[] =
+    {'C','u','r','r','e','n','t','T','i','m','e','Z','o','n','e',0};
 static const WCHAR prop_currentverticalresW[] =
     {'C','u','r','r','e','n','t','V','e','r','t','i','c','a','l','R','e','s','o','l','u','t','i','o','n',0};
-#endif
+static const WCHAR prop_d3dscoreW[] =
+    {'D','3','D','S','c','o','r','e',0};
 static const WCHAR prop_datawidthW[] =
     {'D','a','t','a','W','i','d','t','h',0};
 static const WCHAR prop_defaultipgatewayW[] =
     {'D','e','f','a','u','l','t','I','P','G','a','t','e','w','a','y',0};
 static const WCHAR prop_defaultvalueW[] =
     {'D','e','f','a','u','l','t','V','a','l','u','e',0};
+static const WCHAR prop_dependentW[] =
+    {'D','e','p','e','n','d','e','n','t',0};
 static const WCHAR prop_descriptionW[] =
     {'D','e','s','c','r','i','p','t','i','o','n',0};
 static const WCHAR prop_destinationW[] =
     {'D','e','s','t','i','n','a','t','i','o','n',0};
 static const WCHAR prop_deviceidW[] =
     {'D','e','v','i','c','e','I','d',0};
+static const WCHAR prop_devicelocatorW[] =
+    {'D','e','v','i','c','e','L','o','c','a','t','o','r',0};
 static const WCHAR prop_dhcpenabledW[] =
     {'D','H','C','P','E','n','a','b','l','e','d',0};
 static const WCHAR prop_directionW[] =
     {'D','i','r','e','c','t','i','o','n',0};
+static const WCHAR prop_diskscoreW[] =
+    {'D','i','s','k','S','c','o','r','e',0};
 static const WCHAR prop_displaynameW[] =
     {'D','i','s','p','l','a','y','N','a','m','e',0};
 static const WCHAR prop_diskindexW[] =
@@ -258,8 +285,12 @@ static const WCHAR prop_freephysicalmemoryW[] =
     {'F','r','e','e','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
 static const WCHAR prop_handleW[] =
     {'H','a','n','d','l','e',0};
+static const WCHAR prop_graphicsscoreW[] =
+    {'G','r','a','p','h','i','c','s','S','c','o','r','e',0};
 static const WCHAR prop_horizontalresolutionW[] =
     {'H','o','r','i','z','o','n','t','a','l','R','e','s','o','l','u','t','i','o','n',0};
+static const WCHAR prop_hotfixidW[] =
+    {'H','o','t','F','i','x','I','D',0};
 static const WCHAR prop_idW[] =
     {'I','D',0};
 static const WCHAR prop_identificationcodeW[] =
@@ -310,6 +341,8 @@ static const WCHAR prop_mediatypeW[] =
     {'M','e','d','i','a','T','y','p','e',0};
 static const WCHAR prop_memberW[] =
     {'M','e','m','b','e','r',0};
+static const WCHAR prop_memoryscoreW[] =
+    {'M','e','m','o','r','y','S','c','o','r','e',0};
 static const WCHAR prop_memorytypeW[] =
     {'M','e','m','o','r','y','T','y','p','e',0};
 static const WCHAR prop_methodW[] =
@@ -328,6 +361,8 @@ static const WCHAR prop_numlogicalprocessorsW[] =
     {'N','u','m','b','e','r','O','f','L','o','g','i','c','a','l','P','r','o','c','e','s','s','o','r','s',0};
 static const WCHAR prop_numprocessorsW[] =
     {'N','u','m','b','e','r','O','f','P','r','o','c','e','s','s','o','r','s',0};
+static const WCHAR prop_operatingsystemskuW[] =
+    {'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m','S','K','U',0};
 static const WCHAR prop_osarchitectureW[] =
     {'O','S','A','r','c','h','i','t','e','c','t','u','r','e',0};
 static const WCHAR prop_oslanguageW[] =
@@ -338,6 +373,8 @@ static const WCHAR prop_ostypeW[] =
     {'O','S','T','y','p','e',0};
 static const WCHAR prop_parameterW[] =
     {'P','a','r','a','m','e','t','e','r',0};
+static const WCHAR prop_partnumberW[] =
+    {'P','a','r','t','N','u','m','b','e','r',0};
 static const WCHAR prop_physicaladapterW[] =
     {'P','h','y','s','i','c','a','l','A','d','a','p','t','e','r',0};
 static const WCHAR prop_pixelsperxlogicalinchW[] =
@@ -408,12 +445,16 @@ static const WCHAR prop_suitemaskW[] =
     {'S','u','i','t','e','M','a','s','k',0};
 static const WCHAR prop_systemdirectoryW[] =
     {'S','y','s','t','e','m','D','i','r','e','c','t','o','r','y',0};
+static const WCHAR prop_systemdriveW[] =
+    {'S','y','s','t','e','m','D','r','i','v','e',0};
 static const WCHAR prop_systemnameW[] =
     {'S','y','s','t','e','m','N','a','m','e',0};
 static const WCHAR prop_tagW[] =
     {'T','a','g',0};
 static const WCHAR prop_threadcountW[] =
     {'T','h','r','e','a','d','C','o','u','n','t',0};
+static const WCHAR prop_timetakenW[] =
+    {'T','i','m','e','T','a','k','e','n',0};
 static const WCHAR prop_totalphysicalmemoryW[] =
     {'T','o','t','a','l','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
 static const WCHAR prop_totalvirtualmemorysizeW[] =
@@ -428,12 +469,12 @@ static const WCHAR prop_usernameW[] =
     {'U','s','e','r','N','a','m','e',0};
 static const WCHAR prop_uuidW[] =
     {'U','U','I','D',0};
-static const WCHAR prop_varianttypeW[] =
-    {'V','a','r','i','a','n','t','T','y','p','e',0};
 static const WCHAR prop_vendorW[] =
     {'V','e','n','d','o','r',0};
 static const WCHAR prop_versionW[] =
     {'V','e','r','s','i','o','n',0};
+static const WCHAR prop_verticalresolutionW[] =
+    {'V','e','r','t','i','c','a','l','R','e','s','o','l','u','t','i','o','n',0};
 #ifndef __REACTOS__
 static const WCHAR prop_videoarchitectureW[] =
     {'V','i','d','e','o','A','r','c','h','i','t','e','c','t','u','r','e',0};
@@ -448,31 +489,42 @@ static const WCHAR prop_volumenameW[] =
     {'V','o','l','u','m','e','N','a','m','e',0};
 static const WCHAR prop_volumeserialnumberW[] =
     {'V','o','l','u','m','e','S','e','r','i','a','l','N','u','m','b','e','r',0};
+static const WCHAR prop_winsatassessmentstateW[] =
+    {'W','i','n','S','A','T','A','s','s','e','s','s','m','e','n','t','S','t','a','t','e',0};
+static const WCHAR prop_winsprlevelW[] =
+    {'W','i','n','S','P','R','L','e','v','e','l',0};
 static const WCHAR prop_workingsetsizeW[] =
     {'W','o','r','k','i','n','g','S','e','t','S','i','z','e',0};
 
 /* column definitions must be kept in sync with record structures below */
+static const struct column col_associator[] =
+{
+    { prop_assocclassW, CIM_STRING },
+    { prop_classW,      CIM_STRING },
+    { prop_associatorW, CIM_STRING }
+};
 static const struct column col_baseboard[] =
 {
-    { prop_manufacturerW,  CIM_STRING },
+    { prop_manufacturerW,  CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_modelW,         CIM_STRING },
     { prop_nameW,          CIM_STRING },
-    { prop_productW,       CIM_STRING },
-    { prop_serialnumberW,  CIM_STRING },
+    { prop_productW,       CIM_STRING|COL_FLAG_DYNAMIC },
+    { prop_serialnumberW,  CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_tagW,           CIM_STRING|COL_FLAG_KEY },
-    { prop_versionW,       CIM_STRING }
+    { prop_versionW,       CIM_STRING|COL_FLAG_DYNAMIC }
 };
 static const struct column col_bios[] =
 {
+    { prop_currentlanguageW,    CIM_STRING },
     { prop_descriptionW,        CIM_STRING },
     { prop_identificationcodeW, CIM_STRING },
-    { prop_manufacturerW,       CIM_STRING },
+    { prop_manufacturerW,       CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_nameW,               CIM_STRING },
-    { prop_releasedateW,        CIM_DATETIME },
+    { prop_releasedateW,        CIM_DATETIME|COL_FLAG_DYNAMIC },
     { prop_serialnumberW,       CIM_STRING },
-    { prop_smbiosbiosversionW,  CIM_STRING },
-    { prop_smbiosmajorversionW, CIM_UINT16, VT_I4 },
-    { prop_smbiosminorversionW, CIM_UINT16, VT_I4 },
+    { prop_smbiosbiosversionW,  CIM_STRING|COL_FLAG_DYNAMIC },
+    { prop_smbiosmajorversionW, CIM_UINT16 },
+    { prop_smbiosminorversionW, CIM_UINT16 },
     { prop_versionW,            CIM_STRING|COL_FLAG_KEY }
 };
 static const struct column col_cdromdrive[] =
@@ -487,23 +539,23 @@ static const struct column col_compsys[] =
 {
     { prop_descriptionW,          CIM_STRING },
     { prop_domainW,               CIM_STRING },
-    { prop_domainroleW,           CIM_UINT16, VT_I4 },
+    { prop_domainroleW,           CIM_UINT16 },
     { prop_manufacturerW,         CIM_STRING },
     { prop_modelW,                CIM_STRING },
     { prop_nameW,                 CIM_STRING|COL_FLAG_DYNAMIC },
-    { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 },
-    { prop_numprocessorsW,        CIM_UINT32, VT_I4 },
+    { prop_numlogicalprocessorsW, CIM_UINT32 },
+    { prop_numprocessorsW,        CIM_UINT32 },
     { prop_totalphysicalmemoryW,  CIM_UINT64 },
     { prop_usernameW,             CIM_STRING|COL_FLAG_DYNAMIC }
 };
 static const struct column col_compsysproduct[] =
 {
-    { prop_identifyingnumberW,  CIM_STRING|COL_FLAG_KEY },
-    { prop_nameW,               CIM_STRING|COL_FLAG_KEY },
+    { prop_identifyingnumberW,  CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
+    { prop_nameW,               CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
     { prop_skunumberW,          CIM_STRING },
     { prop_uuidW,               CIM_STRING|COL_FLAG_DYNAMIC },
-    { prop_vendorW,             CIM_STRING },
-    { prop_versionW,            CIM_STRING|COL_FLAG_KEY }
+    { prop_vendorW,             CIM_STRING|COL_FLAG_DYNAMIC },
+    { prop_versionW,            CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }
 };
 static const struct column col_datafile[] =
 {
@@ -522,7 +574,7 @@ static const struct column col_directory[] =
 static const struct column col_diskdrive[] =
 {
     { prop_deviceidW,      CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
-    { prop_indexW,         CIM_UINT32, VT_I4 },
+    { prop_indexW,         CIM_UINT32 },
     { prop_interfacetypeW, CIM_STRING },
     { prop_manufacturerW,  CIM_STRING },
     { prop_mediatypeW,     CIM_STRING },
@@ -531,18 +583,31 @@ static const struct column col_diskdrive[] =
     { prop_serialnumberW,  CIM_STRING },
     { prop_sizeW,          CIM_UINT64 }
 };
+static const struct column col_diskdrivetodiskpartition[] =
+{
+    { prop_antecedentW, CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
+    { prop_dependentW,  CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY }
+};
 static const struct column col_diskpartition[] =
 {
     { prop_bootableW,       CIM_BOOLEAN },
     { prop_bootpartitionW,  CIM_BOOLEAN },
     { prop_deviceidW,       CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
-    { prop_diskindexW,      CIM_UINT32, VT_I4 },
-    { prop_indexW,          CIM_UINT32, VT_I4 },
+    { prop_diskindexW,      CIM_UINT32 },
+    { prop_indexW,          CIM_UINT32 },
     { prop_pnpdeviceidW,    CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_sizeW,           CIM_UINT64 },
     { prop_startingoffsetW, CIM_UINT64 },
     { prop_typeW,           CIM_STRING|COL_FLAG_DYNAMIC }
 };
+static const struct column col_displaycontrollerconfig[] =
+{
+    { prop_bitsperpixelW,         CIM_UINT32 },
+    { prop_captionW,              CIM_STRING },
+    { prop_horizontalresolutionW, CIM_UINT32 },
+    { prop_nameW,                 CIM_STRING|COL_FLAG_KEY },
+    { prop_verticalresolutionW,   CIM_UINT32 }
+};
 static const struct column col_ip4routetable[] =
 {
     { prop_destinationW,    CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
@@ -552,7 +617,7 @@ static const struct column col_ip4routetable[] =
 static const struct column col_logicaldisk[] =
 {
     { prop_deviceidW,           CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
-    { prop_drivetypeW,          CIM_UINT32, VT_I4 },
+    { prop_drivetypeW,          CIM_UINT32 },
     { prop_filesystemW,         CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_freespaceW,          CIM_UINT64 },
     { prop_nameW,               CIM_STRING|COL_FLAG_DYNAMIC },
@@ -560,16 +625,23 @@ static const struct column col_logicaldisk[] =
     { prop_volumenameW,         CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_volumeserialnumberW, CIM_STRING|COL_FLAG_DYNAMIC }
 };
+static const struct column col_logicaldisktopartition[] =
+{
+    { prop_antecedentW, CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
+    { prop_dependentW,  CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY }
+};
 static const struct column col_networkadapter[] =
 {
     { prop_adaptertypeW,         CIM_STRING },
+    { prop_adaptertypeidW,       CIM_UINT16 },
+    { prop_descriptionW,         CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_deviceidW,            CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
-    { prop_indexW,               CIM_UINT32, VT_I4 },
-    { prop_interfaceindexW,      CIM_UINT32, VT_I4 },
+    { prop_indexW,               CIM_UINT32 },
+    { prop_interfaceindexW,      CIM_UINT32 },
     { prop_macaddressW,          CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_manufacturerW,        CIM_STRING },
     { prop_nameW,                CIM_STRING|COL_FLAG_DYNAMIC },
-    { prop_netconnectionstatusW, CIM_UINT16, VT_I4 },
+    { prop_netconnectionstatusW, CIM_UINT16 },
     { prop_physicaladapterW,     CIM_BOOLEAN },
     { prop_pnpdeviceidW,         CIM_STRING },
     { prop_speedW,               CIM_UINT64 }
@@ -581,37 +653,42 @@ static const struct column col_networkadapterconfig[] =
     { prop_dhcpenabledW,          CIM_BOOLEAN },
     { prop_dnshostnameW,          CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_dnsserversearchorderW, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
-    { prop_indexW,                CIM_UINT32|COL_FLAG_KEY, VT_I4 },
+    { prop_indexW,                CIM_UINT32|COL_FLAG_KEY },
     { prop_ipaddressW,            CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
-    { prop_ipconnectionmetricW,   CIM_UINT32, VT_I4 },
+    { prop_ipconnectionmetricW,   CIM_UINT32 },
     { prop_ipenabledW,            CIM_BOOLEAN },
     { prop_ipsubnet,              CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
     { prop_macaddressW,           CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_settingidW,            CIM_STRING|COL_FLAG_DYNAMIC }
 };
-static const struct column col_os[] =
+static const struct column col_operatingsystem[] =
 {
     { prop_buildnumberW,            CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_captionW,                CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_codesetW,                CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_countrycodeW,            CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_csdversionW,             CIM_STRING|COL_FLAG_DYNAMIC },
+    { prop_csnameW,                 CIM_STRING|COL_FLAG_DYNAMIC },
+    { prop_currenttimezoneW,        CIM_SINT16 },
     { prop_freephysicalmemoryW,     CIM_UINT64 },
     { prop_installdateW,            CIM_DATETIME },
     { prop_lastbootuptimeW,         CIM_DATETIME|COL_FLAG_DYNAMIC },
     { prop_localdatetimeW,          CIM_DATETIME|COL_FLAG_DYNAMIC },
     { prop_localeW,                 CIM_STRING|COL_FLAG_DYNAMIC },
+    { prop_manufacturerW,           CIM_STRING },
     { prop_nameW,                   CIM_STRING|COL_FLAG_DYNAMIC },
+    { prop_operatingsystemskuW,     CIM_UINT32 },
     { prop_osarchitectureW,         CIM_STRING },
-    { prop_oslanguageW,             CIM_UINT32, VT_I4 },
-    { prop_osproductsuiteW,         CIM_UINT32, VT_I4 },
-    { prop_ostypeW,                 CIM_UINT16, VT_I4 },
+    { prop_oslanguageW,             CIM_UINT32 },
+    { prop_osproductsuiteW,         CIM_UINT32 },
+    { prop_ostypeW,                 CIM_UINT16 },
     { prop_primaryW,                CIM_BOOLEAN },
     { prop_serialnumberW,           CIM_STRING },
-    { prop_servicepackmajorW,       CIM_UINT16, VT_I4 },
-    { prop_servicepackminorW,       CIM_UINT16, VT_I4 },
-    { prop_suitemaskW,              CIM_UINT32, VT_I4 },
+    { prop_servicepackmajorW,       CIM_UINT16 },
+    { prop_servicepackminorW,       CIM_UINT16 },
+    { prop_suitemaskW,              CIM_UINT32 },
     { prop_systemdirectoryW,        CIM_STRING|COL_FLAG_DYNAMIC },
+    { prop_systemdriveW,            CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_totalvirtualmemorysizeW, CIM_UINT64 },
     { prop_totalvisiblememorysizeW, CIM_UINT64 },
     { prop_versionW,                CIM_STRING|COL_FLAG_DYNAMIC }
@@ -623,7 +700,6 @@ static const struct column col_param[] =
     { prop_directionW,    CIM_SINT32 },
     { prop_parameterW,    CIM_STRING },
     { prop_typeW,         CIM_UINT32 },
-    { prop_varianttypeW,  CIM_UINT32 },
     { prop_defaultvalueW, CIM_UINT32 }
 };
 static const struct column col_physicalmedia[] =
@@ -633,8 +709,11 @@ static const struct column col_physicalmedia[] =
 };
 static const struct column col_physicalmemory[] =
 {
-    { prop_capacityW,   CIM_UINT64 },
-    { prop_memorytypeW, CIM_UINT16, VT_I4 }
+    { prop_capacityW,             CIM_UINT64 },
+    { prop_configuredclockspeedW, CIM_UINT32 },
+    { prop_devicelocatorW,        CIM_STRING },
+    { prop_memorytypeW,           CIM_UINT16 },
+    { prop_partnumberW,           CIM_STRING }
 };
 static const struct column col_pnpentity[] =
 {
@@ -659,45 +738,51 @@ static const struct column col_process[] =
     { prop_descriptionW,    CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_handleW,         CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
     { prop_nameW,           CIM_STRING|COL_FLAG_DYNAMIC },
-    { prop_pprocessidW,     CIM_UINT32, VT_I4 },
-    { prop_processidW,      CIM_UINT32, VT_I4 },
-    { prop_threadcountW,    CIM_UINT32, VT_I4 },
+    { prop_pprocessidW,     CIM_UINT32 },
+    { prop_processidW,      CIM_UINT32 },
+    { prop_threadcountW,    CIM_UINT32 },
     { prop_workingsetsizeW, CIM_UINT64 },
     /* methods */
     { method_getownerW,     CIM_FLAG_ARRAY|COL_FLAG_METHOD }
 };
 static const struct column col_processor[] =
 {
-    { prop_addresswidthW,         CIM_UINT16, VT_I4 },
-    { prop_architectureW,         CIM_UINT16, VT_I4 },
+    { prop_addresswidthW,         CIM_UINT16 },
+    { prop_architectureW,         CIM_UINT16 },
     { prop_captionW,              CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_cpustatusW,            CIM_UINT16 },
-    { prop_currentclockspeedW,    CIM_UINT32, VT_I4 },
-    { prop_datawidthW,            CIM_UINT16, VT_I4 },
+    { prop_currentclockspeedW,    CIM_UINT32 },
+    { prop_datawidthW,            CIM_UINT16 },
     { prop_descriptionW,          CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_deviceidW,             CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
-    { prop_familyW,               CIM_UINT16, VT_I4 },
-    { prop_levelW,                CIM_UINT16, VT_I4 },
+    { prop_familyW,               CIM_UINT16 },
+    { prop_levelW,                CIM_UINT16 },
     { prop_manufacturerW,         CIM_STRING|COL_FLAG_DYNAMIC },
-    { prop_maxclockspeedW,        CIM_UINT32, VT_I4 },
+    { prop_maxclockspeedW,        CIM_UINT32 },
     { prop_nameW,                 CIM_STRING|COL_FLAG_DYNAMIC },
-    { prop_numcoresW,             CIM_UINT32, VT_I4 },
-    { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 },
+    { prop_numcoresW,             CIM_UINT32 },
+    { prop_numlogicalprocessorsW, CIM_UINT32 },
     { prop_processoridW,          CIM_STRING|COL_FLAG_DYNAMIC },
-    { prop_processortypeW,        CIM_UINT16, VT_I4 },
-    { prop_revisionW,             CIM_UINT16, VT_I4 },
+    { prop_processortypeW,        CIM_UINT16 },
+    { prop_revisionW,             CIM_UINT16 },
     { prop_uniqueidW,             CIM_STRING },
     { prop_versionW,              CIM_STRING|COL_FLAG_DYNAMIC }
 };
 static const struct column col_qualifier[] =
 {
-    { prop_classW,    CIM_STRING },
-    { prop_memberW,   CIM_STRING },
-    { prop_typeW,     CIM_UINT32 },
-    { prop_flavorW,   CIM_SINT32 },
-    { prop_nameW,     CIM_STRING },
-    { prop_intvalueW, CIM_SINT32 },
-    { prop_strvalueW, CIM_STRING }
+    { prop_classW,     CIM_STRING },
+    { prop_memberW,    CIM_STRING },
+    { prop_typeW,      CIM_UINT32 },
+    { prop_flavorW,    CIM_SINT32 },
+    { prop_nameW,      CIM_STRING },
+    { prop_intvalueW,  CIM_SINT32 },
+    { prop_strvalueW,  CIM_STRING },
+    { prop_boolvalueW, CIM_BOOLEAN }
+};
+static const struct column col_quickfixengineering[] =
+{
+    { prop_captionW,  CIM_STRING },
+    { prop_hotfixidW, CIM_STRING|COL_FLAG_KEY }
 };
 static const struct column col_service[] =
 {
@@ -728,7 +813,7 @@ static const struct column col_sounddevice[] =
 {
     { prop_nameW,        CIM_STRING },
     { prop_productnameW, CIM_STRING },
-    { prop_statusinfoW,  CIM_UINT16, VT_I4 }
+    { prop_statusinfoW,  CIM_UINT16 }
 };
 static const struct column col_stdregprov[] =
 {
@@ -740,10 +825,10 @@ static const struct column col_stdregprov[] =
 static const struct column col_systemenclosure[] =
 {
     { prop_captionW,      CIM_STRING },
-    { prop_chassistypesW, CIM_UINT16|CIM_FLAG_ARRAY, VT_I4|VT_ARRAY },
+    { prop_chassistypesW, CIM_UINT16|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
     { prop_descriptionW,  CIM_STRING },
     { prop_lockpresentW,  CIM_BOOLEAN },
-    { prop_manufacturerW, CIM_STRING },
+    { prop_manufacturerW, CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_nameW,         CIM_STRING },
     { prop_tagW,          CIM_STRING },
 };
@@ -757,15 +842,15 @@ static const struct column col_systemsecurity[] =
 static const struct column col_videocontroller[] =
 {
     { prop_adapterdactypeW,         CIM_STRING },
-    { prop_adapterramW,             CIM_UINT32, VT_I4 },
+    { prop_adapterramW,             CIM_UINT32 },
     { prop_availabilityW,           CIM_UINT16 },
     { prop_captionW,                CIM_STRING|COL_FLAG_DYNAMIC },
-    { prop_configmanagererrorcodeW, CIM_UINT32, VT_I4 },
-    { prop_currentbitsperpixelW,    CIM_UINT32, VT_I4 },
-    { prop_currenthorizontalresW,   CIM_UINT32, VT_I4 },
-    { prop_currentrefreshrateW,     CIM_UINT32, VT_I4 },
-    { prop_currentscanmodeW,        CIM_UINT16, VT_I4 },
-    { prop_currentverticalresW,     CIM_UINT32, VT_I4 },
+    { prop_configmanagererrorcodeW, CIM_UINT32 },
+    { prop_currentbitsperpixelW,    CIM_UINT32 },
+    { prop_currenthorizontalresW,   CIM_UINT32 },
+    { prop_currentrefreshrateW,     CIM_UINT32 },
+    { prop_currentscanmodeW,        CIM_UINT16 },
+    { prop_currentverticalresW,     CIM_UINT32 },
     { prop_descriptionW,            CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_deviceidW,               CIM_STRING|COL_FLAG_KEY },
     { prop_driverdateW,             CIM_DATETIME },
@@ -774,13 +859,26 @@ static const struct column col_videocontroller[] =
     { prop_nameW,                   CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_pnpdeviceidW,            CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_statusW,                 CIM_STRING },
-    { prop_videoarchitectureW,      CIM_UINT16, VT_I4 },
-    { prop_videomemorytypeW,        CIM_UINT16, VT_I4 },
+    { prop_videoarchitectureW,      CIM_UINT16 },
+    { prop_videomemorytypeW,        CIM_UINT16 },
     { prop_videomodedescriptionW,   CIM_STRING|COL_FLAG_DYNAMIC },
     { prop_videoprocessorW,         CIM_STRING|COL_FLAG_DYNAMIC },
 };
 #endif
 
+static const struct column col_winsat[] =
+{
+    { prop_cpuscoreW,              CIM_REAL32 },
+    { prop_d3dscoreW,              CIM_REAL32 },
+    { prop_diskscoreW,             CIM_REAL32 },
+    { prop_graphicsscoreW,         CIM_REAL32 },
+    { prop_memoryscoreW,           CIM_REAL32 },
+    { prop_timetakenW,             CIM_STRING|COL_FLAG_KEY },
+    { prop_winsatassessmentstateW, CIM_UINT32 },
+    { prop_winsprlevelW,           CIM_REAL32 },
+};
+
+
 static const WCHAR baseboard_manufacturerW[] =
     {'I','n','t','e','l',' ','C','o','r','p','o','r','a','t','i','o','n',0};
 static const WCHAR baseboard_serialnumberW[] =
@@ -793,8 +891,6 @@ static const WCHAR bios_descriptionW[] =
     {'D','e','f','a','u','l','t',' ','S','y','s','t','e','m',' ','B','I','O','S',0};
 static const WCHAR bios_manufacturerW[] =
     {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
-static const WCHAR bios_nameW[] =
-    {'W','I','N','E',' ','B','I','O','S',0};
 static const WCHAR bios_releasedateW[] =
     {'2','0','1','2','0','6','0','8','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0};
 static const WCHAR bios_serialnumberW[] =
@@ -859,6 +955,10 @@ static const WCHAR os_serialnumberW[] =
     {'1','2','3','4','5','-','O','E','M','-','1','2','3','4','5','6','7','-','1','2','3','4','5',0};
 static const WCHAR physicalmedia_tagW[] =
     {'\\','\\','.','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0',0};
+static const WCHAR quickfixengineering_captionW[] =
+    {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
+static const WCHAR quickfixengineering_hotfixidW[] =
+    {'K','B','1','2','3','4','5','6','7',0};
 static const WCHAR sounddevice_productnameW[] =
     {'W','i','n','e',' ','A','u','d','i','o',' ','D','e','v','i','c','e',0};
 static const WCHAR systemenclosure_systemenclosureW[] =
@@ -867,7 +967,6 @@ static const WCHAR systemenclosure_tagW[] =
     {'S','y','s','t','e','m',' ','E','n','c','l','o','s','u','r','e',' ','0',0};
 static const WCHAR systemenclosure_manufacturerW[] =
     {'W','i','n','e',0};
-#ifndef __REACTOS__
 static const WCHAR videocontroller_dactypeW[] =
     {'I','n','t','e','g','r','a','t','e','d',' ','R','A','M','D','A','C',0};
 static const WCHAR videocontroller_deviceidW[] =
@@ -878,9 +977,16 @@ static const WCHAR videocontroller_driverversionW[] =
     {'1','.','0',0};
 static const WCHAR videocontroller_statusW[] =
     {'O','K',0};
-#endif
+static const WCHAR winsat_timetakenW[] =
+    {'M','o','s','t','R','e','c','e','n','t','A','s','s','e','s','s','m','e','n','t',0};
 
 #include "pshpack1.h"
+struct record_associator
+{
+    const WCHAR *assocclass;
+    const WCHAR *class;
+    const WCHAR *associator;
+};
 struct record_baseboard
 {
     const WCHAR *manufacturer;
@@ -893,6 +999,7 @@ struct record_baseboard
 };
 struct record_bios
 {
+    const WCHAR *currentlanguage;
     const WCHAR *description;
     const WCHAR *identificationcode;
     const WCHAR *manufacturer;
@@ -960,6 +1067,11 @@ struct record_diskdrive
     const WCHAR *serialnumber;
     UINT64       size;
 };
+struct record_diskdrivetodiskpartition
+{
+    const WCHAR *antecedent;
+    const WCHAR *dependent;
+};
 struct record_diskpartition
 {
     int          bootable;
@@ -972,6 +1084,14 @@ struct record_diskpartition
     UINT64       startingoffset;
     const WCHAR *type;
 };
+struct record_displaycontrollerconfig
+{
+    UINT32       bitsperpixel;
+    const WCHAR *caption;
+    UINT32       horizontalresolution;
+    const WCHAR *name;
+    UINT32       verticalresolution;
+};
 struct record_ip4routetable
 {
     const WCHAR *destination;
@@ -989,9 +1109,16 @@ struct record_logicaldisk
     const WCHAR *volumename;
     const WCHAR *volumeserialnumber;
 };
+struct record_logicaldisktopartition
+{
+    const WCHAR *antecedent;
+    const WCHAR *dependent;
+};
 struct record_networkadapter
 {
     const WCHAR *adaptertype;
+    UINT16       adaptertypeid;
+    const WCHAR *description;
     const WCHAR *device_id;
     UINT32       index;
     UINT32       interface_index;
@@ -1025,12 +1152,16 @@ struct record_operatingsystem
     const WCHAR *codeset;
     const WCHAR *countrycode;
     const WCHAR *csdversion;
+    const WCHAR *csname;
+    INT16        currenttimezone;
     UINT64       freephysicalmemory;
     const WCHAR *installdate;
     const WCHAR *lastbootuptime;
     const WCHAR *localdatetime;
     const WCHAR *locale;
+    const WCHAR *manufacturer;
     const WCHAR *name;
+    UINT32       operatingsystemsku;
     const WCHAR *osarchitecture;
     UINT32       oslanguage;
     UINT32       osproductsuite;
@@ -1041,6 +1172,7 @@ struct record_operatingsystem
     UINT16       servicepackminor;
     UINT32       suitemask;
     const WCHAR *systemdirectory;
+    const WCHAR *systemdrive;
     UINT64       totalvirtualmemorysize;
     UINT64       totalvisiblememorysize;
     const WCHAR *version;
@@ -1052,7 +1184,6 @@ struct record_param
     INT32        direction;
     const WCHAR *parameter;
     UINT32       type;
-    UINT32       varianttype;
     UINT32       defaultvalue;
 };
 struct record_physicalmedia
@@ -1062,8 +1193,11 @@ struct record_physicalmedia
 };
 struct record_physicalmemory
 {
-    UINT64 capacity;
-    UINT16 memorytype;
+    UINT64       capacity;
+    UINT32       configuredclockspeed;
+    const WCHAR *devicelocator;
+    UINT16       memorytype;
+    const WCHAR *partnumber;
 };
 struct record_pnpentity
 {
@@ -1127,6 +1261,12 @@ struct record_qualifier
     const WCHAR *name;
     INT32        intvalue;
     const WCHAR *strvalue;
+    int          boolvalue;
+};
+struct record_quickfixengineering
+{
+    const WCHAR *caption;
+    const WCHAR *hotfixid;
 };
 struct record_service
 {
@@ -1173,13 +1313,13 @@ struct record_systemsecurity
 };
 struct record_systemenclosure
 {
-    const WCHAR *caption;
+    const WCHAR        *caption;
     const struct array *chassistypes;
-    const WCHAR *description;
-    int         lockpresent;
-    const WCHAR *manufacturer;
-    const WCHAR *name;
-    const WCHAR *tag;
+    const WCHAR        *description;
+    int                 lockpresent;
+    const WCHAR        *manufacturer;
+    const WCHAR        *name;
+    const WCHAR        *tag;
 };
 struct record_videocontroller
 {
@@ -1206,47 +1346,54 @@ struct record_videocontroller
     const WCHAR *videomodedescription;
     const WCHAR *videoprocessor;
 };
+struct record_winsat
+{
+    FLOAT        cpuscore;
+    FLOAT        d3dscore;
+    FLOAT        diskscrore;
+    FLOAT        graphicsscore;
+    FLOAT        memoryscore;
+    const WCHAR *timetaken;
+    UINT32       winsatassessmentstate;
+    FLOAT        winsprlevel;
+};
 #include "poppack.h"
 
-static const struct record_baseboard data_baseboard[] =
-{
-    { baseboard_manufacturerW, baseboard_tagW, baseboard_tagW, baseboard_tagW, baseboard_serialnumberW, baseboard_versionW }
-};
-static const struct record_bios data_bios[] =
+static const struct record_associator data_associator[] =
 {
-    { bios_descriptionW, NULL, bios_manufacturerW, bios_nameW, bios_releasedateW, bios_serialnumberW,
-      bios_smbiosbiosversionW, 1, 0, bios_versionW }
+    { class_diskdrivetodiskpartitionW, class_diskpartitionW, class_diskdriveW },
+    { class_logicaldisktopartitionW, class_logicaldiskW, class_diskpartitionW },
 };
 static const struct record_param data_param[] =
 {
-    { class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
+    { class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32 },
     { class_processW, method_getownerW, -1, param_userW, CIM_STRING },
     { class_processW, method_getownerW, -1, param_domainW, CIM_STRING },
-    { class_serviceW, method_pauseserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
-    { class_serviceW, method_resumeserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
-    { class_serviceW, method_startserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
-    { class_serviceW, method_stopserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
-    { class_stdregprovW, method_createkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
+    { class_serviceW, method_pauseserviceW, -1, param_returnvalueW, CIM_UINT32 },
+    { class_serviceW, method_resumeserviceW, -1, param_returnvalueW, CIM_UINT32 },
+    { class_serviceW, method_startserviceW, -1, param_returnvalueW, CIM_UINT32 },
+    { class_serviceW, method_stopserviceW, -1, param_returnvalueW, CIM_UINT32 },
+    { class_stdregprovW, method_createkeyW, 1, param_defkeyW, CIM_SINT32, 0x80000002 },
     { class_stdregprovW, method_createkeyW, 1, param_subkeynameW, CIM_STRING },
-    { class_stdregprovW, method_createkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
-    { class_stdregprovW, method_enumkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
+    { class_stdregprovW, method_createkeyW, -1, param_returnvalueW, CIM_UINT32 },
+    { class_stdregprovW, method_enumkeyW, 1, param_defkeyW, CIM_SINT32, 0x80000002 },
     { class_stdregprovW, method_enumkeyW, 1, param_subkeynameW, CIM_STRING },
-    { class_stdregprovW, method_enumkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
+    { class_stdregprovW, method_enumkeyW, -1, param_returnvalueW, CIM_UINT32 },
     { class_stdregprovW, method_enumkeyW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY },
-    { class_stdregprovW, method_enumvaluesW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
+    { class_stdregprovW, method_enumvaluesW, 1, param_defkeyW, CIM_SINT32, 0x80000002 },
     { class_stdregprovW, method_enumvaluesW, 1, param_subkeynameW, CIM_STRING },
-    { class_stdregprovW, method_enumvaluesW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
+    { class_stdregprovW, method_enumvaluesW, -1, param_returnvalueW, CIM_UINT32 },
     { class_stdregprovW, method_enumvaluesW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY },
     { class_stdregprovW, method_enumvaluesW, -1, param_typesW, CIM_SINT32|CIM_FLAG_ARRAY },
-    { class_stdregprovW, method_getstringvalueW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
+    { class_stdregprovW, method_getstringvalueW, 1, param_defkeyW, CIM_SINT32, 0x80000002 },
     { class_stdregprovW, method_getstringvalueW, 1, param_subkeynameW, CIM_STRING },
     { class_stdregprovW, method_getstringvalueW, 1, param_valuenameW, CIM_STRING },
-    { class_stdregprovW, method_getstringvalueW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
+    { class_stdregprovW, method_getstringvalueW, -1, param_returnvalueW, CIM_UINT32 },
     { class_stdregprovW, method_getstringvalueW, -1, param_valueW, CIM_STRING },
-    { class_systemsecurityW, method_getsdW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
+    { class_systemsecurityW, method_getsdW, -1, param_returnvalueW, CIM_UINT32 },
     { class_systemsecurityW, method_getsdW, -1, param_sdW, CIM_UINT8|CIM_FLAG_ARRAY },
     { class_systemsecurityW, method_setsdW, 1, param_sdW, CIM_UINT8|CIM_FLAG_ARRAY },
-    { class_systemsecurityW, method_setsdW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
+    { class_systemsecurityW, method_setsdW, -1, param_returnvalueW, CIM_UINT32 },
 };
 
 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\
@@ -1261,6 +1408,10 @@ static const struct record_qualifier data_qualifier[] =
     { class_process_getowner_outW, param_userW, CIM_SINT32, FLAVOR_ID, prop_idW, 0 },
     { class_process_getowner_outW, param_domainW, CIM_SINT32, FLAVOR_ID, prop_idW, 1 }
 };
+static const struct record_quickfixengineering data_quickfixengineering[] =
+{
+    { quickfixengineering_captionW, quickfixengineering_hotfixidW },
+};
 static const struct record_sounddevice data_sounddevice[] =
 {
     { sounddevice_productnameW, sounddevice_productnameW, 3 /* enabled */ }
@@ -1275,25 +1426,18 @@ static UINT16 systemenclosure_chassistypes[] =
 };
 static const struct array systemenclosure_chassistypes_array =
 {
+    sizeof(*systemenclosure_chassistypes),
     ARRAY_SIZE(systemenclosure_chassistypes),
     &systemenclosure_chassistypes
 };
-static const struct record_systemenclosure data_systemenclosure[] =
-{
-    {
-        systemenclosure_systemenclosureW,
-        &systemenclosure_chassistypes_array,
-        systemenclosure_systemenclosureW,
-        FALSE,
-        systemenclosure_manufacturerW,
-        systemenclosure_systemenclosureW,
-        systemenclosure_tagW,
-    }
-};
 static const struct record_systemsecurity data_systemsecurity[] =
 {
     { security_get_sd, security_set_sd }
 };
+static const struct record_winsat data_winsat[] =
+{
+    { 8.0f, 8.0f, 8.0f, 8.0f, 8.0f, winsat_timetakenW, 1 /* Valid */, 8.0f },
+};
 
 /* check if row matches condition and update status */
 static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status )
@@ -1334,6 +1478,318 @@ static BOOL resize_table( struct table *table, UINT row_count, UINT row_size )
     return TRUE;
 }
 
+#include "pshpack1.h"
+struct smbios_prologue
+{
+    BYTE  calling_method;
+    BYTE  major_version;
+    BYTE  minor_version;
+    BYTE  revision;
+    DWORD length;
+};
+
+enum smbios_type
+{
+    SMBIOS_TYPE_BIOS,
+    SMBIOS_TYPE_SYSTEM,
+    SMBIOS_TYPE_BASEBOARD,
+    SMBIOS_TYPE_CHASSIS,
+};
+
+struct smbios_header
+{
+    BYTE type;
+    BYTE length;
+    WORD handle;
+};
+
+struct smbios_baseboard
+{
+    struct smbios_header hdr;
+    BYTE                 vendor;
+    BYTE                 product;
+    BYTE                 version;
+    BYTE                 serial;
+};
+
+struct smbios_bios
+{
+    struct smbios_header hdr;
+    BYTE                 vendor;
+    BYTE                 version;
+    WORD                 start;
+    BYTE                 date;
+    BYTE                 size;
+    UINT64               characteristics;
+};
+
+struct smbios_chassis
+{
+    struct smbios_header hdr;
+    BYTE                 vendor;
+    BYTE                 type;
+    BYTE                 version;
+    BYTE                 serial;
+    BYTE                 asset_tag;
+};
+
+struct smbios_system
+{
+    struct smbios_header hdr;
+    BYTE                 vendor;
+    BYTE                 product;
+    BYTE                 version;
+    BYTE                 serial;
+    BYTE                 uuid[16];
+};
+#include "poppack.h"
+
+#define RSMB (('R' << 24) | ('S' << 16) | ('M' << 8) | 'B')
+
+static const struct smbios_header *find_smbios_entry( enum smbios_type type, const char *buf, UINT len )
+{
+    const char *ptr, *start;
+    const struct smbios_prologue *prologue;
+    const struct smbios_header *hdr;
+
+    if (len < sizeof(struct smbios_prologue)) return NULL;
+    prologue = (const struct smbios_prologue *)buf;
+    if (prologue->length > len - sizeof(*prologue) || prologue->length < sizeof(*hdr)) return NULL;
+
+    start = (const char *)(prologue + 1);
+    hdr = (const struct smbios_header *)start;
+
+    for (;;)
+    {
+        if ((const char *)hdr - start >= prologue->length - sizeof(*hdr)) return NULL;
+
+        if (!hdr->length)
+        {
+            WARN( "invalid entry\n" );
+            return NULL;
+        }
+
+        if (hdr->type == type)
+        {
+            if ((const char *)hdr - start + hdr->length > prologue->length) return NULL;
+            break;
+        }
+        else /* skip other entries and their strings */
+        {
+            for (ptr = (const char *)hdr + hdr->length; ptr - buf < len && *ptr; ptr++)
+            {
+                for (; ptr - buf < len; ptr++) if (!*ptr) break;
+            }
+            if (ptr == (const char *)hdr + hdr->length) ptr++;
+            hdr = (const struct smbios_header *)(ptr + 1);
+        }
+    }
+
+    return hdr;
+}
+
+static WCHAR *get_smbios_string( BYTE id, const char *buf, UINT offset, UINT buflen )
+{
+    const char *ptr = buf + offset;
+    UINT i = 0;
+
+    if (!id || offset >= buflen) return NULL;
+    for (ptr = buf + offset; ptr - buf < buflen && *ptr; ptr++)
+    {
+        if (++i == id) return heap_strdupAW( ptr );
+        for (; ptr - buf < buflen; ptr++) if (!*ptr) break;
+    }
+    return NULL;
+}
+
+static WCHAR *get_baseboard_string( BYTE id, const char *buf, UINT len )
+{
+    const struct smbios_header *hdr;
+    const struct smbios_baseboard *baseboard;
+    UINT offset;
+
+    if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BASEBOARD, buf, len ))) return NULL;
+
+    baseboard = (const struct smbios_baseboard *)hdr;
+    offset = (const char *)baseboard - buf + baseboard->hdr.length;
+    return get_smbios_string( id, buf, offset, len );
+}
+
+static WCHAR *get_baseboard_manufacturer( const char *buf, UINT len )
+{
+    WCHAR *ret = get_baseboard_string( 1, buf, len );
+    if (!ret) return heap_strdupW( baseboard_manufacturerW );
+    return ret;
+}
+
+static WCHAR *get_baseboard_product( const char *buf, UINT len )
+{
+    WCHAR *ret = get_baseboard_string( 2, buf, len );
+    if (!ret) return heap_strdupW( baseboard_tagW );
+    return ret;
+}
+
+static WCHAR *get_baseboard_serialnumber( const char *buf, UINT len )
+{
+    WCHAR *ret = get_baseboard_string( 4, buf, len );
+    if (!ret) return heap_strdupW( baseboard_serialnumberW );
+    return ret;
+}
+
+static WCHAR *get_baseboard_version( const char *buf, UINT len )
+{
+    WCHAR *ret = get_baseboard_string( 3, buf, len );
+    if (!ret) return heap_strdupW( baseboard_versionW );
+    return ret;
+}
+
+static enum fill_status fill_baseboard( struct table *table, const struct expr *cond )
+{
+    struct record_baseboard *rec;
+    enum fill_status status = FILL_STATUS_UNFILTERED;
+    UINT row = 0, len;
+    char *buf;
+
+    if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
+
+    len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
+    if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
+    GetSystemFirmwareTable( RSMB, 0, buf, len );
+
+    rec = (struct record_baseboard *)table->data;
+    rec->manufacturer = get_baseboard_manufacturer( buf, len );
+    rec->model        = baseboard_tagW;
+    rec->name         = baseboard_tagW;
+    rec->product      = get_baseboard_product( buf, len );
+    rec->serialnumber = get_baseboard_serialnumber( buf, len );
+    rec->tag          = baseboard_tagW;
+    rec->version      = get_baseboard_version( buf, len );
+    if (!match_row( table, row, cond, &status )) free_row_values( table, row );
+    else row++;
+
+    heap_free( buf );
+
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
+    return status;
+}
+
+static UINT16 get_bios_smbiosmajorversion( const char *buf, UINT len )
+{
+    const struct smbios_prologue *prologue = (const struct smbios_prologue *)buf;
+    if (len < sizeof(*prologue)) return 2;
+    return prologue->major_version;
+}
+
+static UINT16 get_bios_smbiosminorversion( const char *buf, UINT len )
+{
+    const struct smbios_prologue *prologue = (const struct smbios_prologue *)buf;
+    if (len < sizeof(*prologue)) return 0;
+    return prologue->minor_version;
+}
+
+static WCHAR *get_bios_string( BYTE id, const char *buf, UINT len )
+{
+    const struct smbios_header *hdr;
+    const struct smbios_bios *bios;
+    UINT offset;
+
+    if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return NULL;
+
+    bios = (const struct smbios_bios *)hdr;
+    offset = (const char *)bios - buf + bios->hdr.length;
+    return get_smbios_string( id, buf, offset, len );
+}
+
+static WCHAR *get_bios_manufacturer( const char *buf, UINT len )
+{
+    WCHAR *ret = get_bios_string( 1, buf, len );
+    if (!ret) return heap_strdupW( bios_manufacturerW );
+    return ret;
+}
+
+static WCHAR *convert_bios_date( const WCHAR *str )
+{
+    static const WCHAR fmtW[] =
+        {'%','0','4','u','%','0','2','u','%','0','2','u','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0};
+    UINT year, month, day, len = lstrlenW( str );
+    const WCHAR *p = str, *q;
+    WCHAR *ret;
+
+    while (len && iswspace( *p )) { p++; len--; }
+    while (len && iswspace( p[len - 1] )) { len--; }
+
+    q = p;
+    while (len && iswdigit( *q )) { q++; len--; };
+    if (q - p != 2 || !len || *q != '/') return NULL;
+    month = (p[0] - '0') * 10 + p[1] - '0';
+
+    p = ++q; len--;
+    while (len && iswdigit( *q )) { q++; len--; };
+    if (q - p != 2 || !len || *q != '/') return NULL;
+    day = (p[0] - '0') * 10 + p[1] - '0';
+
+    p = ++q; len--;
+    while (len && iswdigit( *q )) { q++; len--; };
+    if (q - p == 4) year = (p[0] - '0') * 1000 + (p[1] - '0') * 100 + (p[2] - '0') * 10 + p[3] - '0';
+    else if (q - p == 2) year = 1900 + (p[0] - '0') * 10 + p[1] - '0';
+    else return NULL;
+
+    if (!(ret = heap_alloc( sizeof(fmtW) ))) return NULL;
+    swprintf( ret, fmtW, year, month, day );
+    return ret;
+}
+
+static WCHAR *get_bios_releasedate( const char *buf, UINT len )
+{
+    WCHAR *ret, *date = get_bios_string( 3, buf, len );
+    if (!date || !(ret = convert_bios_date( date ))) ret = heap_strdupW( bios_releasedateW );
+    heap_free( date );
+    return ret;
+}
+
+static WCHAR *get_bios_smbiosbiosversion( const char *buf, UINT len )
+{
+    WCHAR *ret = get_bios_string( 2, buf, len );
+    if (!ret) return heap_strdupW( bios_smbiosbiosversionW );
+    return ret;
+}
+
+static enum fill_status fill_bios( struct table *table, const struct expr *cond )
+{
+    struct record_bios *rec;
+    enum fill_status status = FILL_STATUS_UNFILTERED;
+    UINT row = 0, len;
+    char *buf;
+
+    if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
+
+    len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
+    if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
+    GetSystemFirmwareTable( RSMB, 0, buf, len );
+
+    rec = (struct record_bios *)table->data;
+    rec->currentlanguage    = NULL;
+    rec->description        = bios_descriptionW;
+    rec->identificationcode = NULL;
+    rec->manufacturer       = get_bios_manufacturer( buf, len );
+    rec->name               = bios_descriptionW;
+    rec->releasedate        = get_bios_releasedate( buf, len );
+    rec->serialnumber       = bios_serialnumberW;
+    rec->smbiosbiosversion  = get_bios_smbiosbiosversion( buf, len );
+    rec->smbiosmajorversion = get_bios_smbiosmajorversion( buf, len );
+    rec->smbiosminorversion = get_bios_smbiosminorversion( buf, len );
+    rec->version            = bios_versionW;
+    if (!match_row( table, row, cond, &status )) free_row_values( table, row );
+    else row++;
+
+    heap_free( buf );
+
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
+    return status;
+}
+
 static enum fill_status fill_cdromdrive( struct table *table, const struct expr *cond )
 {
     static const WCHAR fmtW[] = {'%','c',':',0};
@@ -1357,7 +1813,7 @@ static enum fill_status fill_cdromdrive( struct table *table, const struct expr
 
             rec = (struct record_cdromdrive *)(table->data + offset);
             rec->device_id    = cdromdrive_pnpdeviceidW;
-            sprintfW( drive, fmtW, 'A' + i );
+            swprintf( drive, fmtW, 'A' + i );
             rec->drive        = heap_strdupW( drive );
             rec->mediatype    = cdromdrive_mediatypeW;
             rec->name         = cdromdrive_nameW;
@@ -1384,6 +1840,7 @@ static UINT get_processor_count(void)
     return info.NumberOfProcessors;
 }
 
+#ifdef __REACTOS__
 static UINT get_logical_processor_count( UINT *num_cores )
 {
     SYSTEM_LOGICAL_PROCESSOR_INFORMATION *info;
@@ -1417,6 +1874,50 @@ static UINT get_logical_processor_count( UINT *num_cores )
     heap_free( info );
     return count;
 }
+#else
+static UINT get_logical_processor_count( UINT *num_physical, UINT *num_packages )
+{
+    SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buf, *entry;
+    UINT core_relation_count = 0, package_relation_count = 0;
+    NTSTATUS status;
+    ULONG len, offset = 0;
+    BOOL smt_enabled = FALSE;
+    DWORD all = RelationAll;
+
+    if (num_packages) *num_packages = 1;
+    status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), NULL, 0, &len );
+    if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count();
+
+    if (!(buf = heap_alloc( len ))) return get_processor_count();
+    status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), buf, len, NULL );
+    if (status != STATUS_SUCCESS)
+    {
+        heap_free( buf );
+        return get_processor_count();
+    }
+
+    while (offset < len)
+    {
+        entry = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)buf + offset);
+
+        if (entry->Relationship == RelationProcessorCore)
+        {
+            core_relation_count++;
+            if (entry->u.Processor.Flags & LTP_PC_SMT) smt_enabled = TRUE;
+        }
+        else if (entry->Relationship == RelationProcessorPackage)
+        {
+            package_relation_count++;
+        }
+        offset += entry->Size;
+    }
+
+    heap_free( buf );
+    if (num_physical) *num_physical = core_relation_count;
+    if (num_packages) *num_packages = package_relation_count;
+    return smt_enabled ? core_relation_count * 2 : core_relation_count;
+}
+#endif
 
 static UINT64 get_total_physical_memory(void)
 {
@@ -1479,8 +1980,12 @@ static enum fill_status fill_compsys( struct table *table, const struct expr *co
     rec->manufacturer           = compsys_manufacturerW;
     rec->model                  = compsys_modelW;
     rec->name                   = get_computername();
+#ifdef __REACTOS__
     rec->num_logical_processors = get_logical_processor_count( NULL );
     rec->num_processors         = get_processor_count();
+#else
+    rec->num_logical_processors = get_logical_processor_count( NULL, &rec->num_processors );
+#endif
     rec->total_physical_memory  = get_total_physical_memory();
     rec->username               = get_username();
     if (!match_row( table, row, cond, &status )) free_row_values( table, row );
@@ -1491,72 +1996,97 @@ static enum fill_status fill_compsys( struct table *table, const struct expr *co
     return status;
 }
 
-static WCHAR *get_compsysproduct_uuid(void)
+static WCHAR *get_compsysproduct_string( BYTE id, const char *buf, UINT len )
 {
-#ifdef __APPLE__
-    unsigned char uuid[16];
-    const struct timespec timeout = {1, 0};
-    if (!gethostuuid( uuid, &timeout ))
-    {
-        static const WCHAR fmtW[] =
-            {'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-',
-             '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X',
-             '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',0};
-        WCHAR *ret = heap_alloc( 37 * sizeof(WCHAR) );
-        if (!ret) return NULL;
-        sprintfW( ret, fmtW, uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
-                  uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] );
-        return ret;
-    }
-#endif
-#ifdef __linux__
-    int file;
-    if ((file = open( "/var/lib/dbus/machine-id", O_RDONLY )) != -1)
-    {
-        unsigned char buf[32];
-        if (read( file, buf, sizeof(buf) ) == sizeof(buf))
-        {
-            unsigned int i, j;
-            WCHAR *ret, *p;
-
-            close( file );
-            if (!(p = ret = heap_alloc( 37 * sizeof(WCHAR) ))) return NULL;
-            for (i = 0, j = 0; i < 8; i++) p[i] = toupperW( buf[j++] );
-            p[8] = '-';
-            for (i = 9; i < 13; i++) p[i] = toupperW( buf[j++] );
-            p[13] = '-';
-            for (i = 14; i < 18; i++) p[i] = toupperW( buf[j++] );
-            p[18] = '-';
-            for (i = 19; i < 23; i++) p[i] = toupperW( buf[j++] );
-            p[23] = '-';
-            for (i = 24; i < 36; i++) p[i] = toupperW( buf[j++] );
-            ret[i] = 0;
-            return ret;
-        }
-        close( file );
-    }
-#endif
-    return heap_strdupW( compsysproduct_uuidW );
+    const struct smbios_header *hdr;
+    const struct smbios_system *system;
+    UINT offset;
+
+    if (!(hdr = find_smbios_entry( SMBIOS_TYPE_SYSTEM, buf, len ))) return NULL;
+
+    system = (const struct smbios_system *)hdr;
+    offset = (const char *)system - buf + system->hdr.length;
+    return get_smbios_string( id, buf, offset, len );
+}
+
+static WCHAR *get_compsysproduct_identifyingnumber( const char *buf, UINT len )
+{
+    WCHAR *ret = get_compsysproduct_string( 4, buf, len );
+    if (!ret) return heap_strdupW( compsysproduct_identifyingnumberW );
+    return ret;
+}
+
+static WCHAR *get_compsysproduct_name( const char *buf, UINT len )
+{
+    WCHAR *ret = get_compsysproduct_string( 2, buf, len );
+    if (!ret) return heap_strdupW( compsysproduct_nameW );
+    return ret;
+}
+
+static WCHAR *get_compsysproduct_uuid( const char *buf, UINT len )
+{
+    static const WCHAR fmtW[] =
+        {'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-',
+         '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X',
+         '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',0};
+    static const BYTE none[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
+    const struct smbios_header *hdr;
+    const struct smbios_system *system;
+    const BYTE *ptr;
+    WCHAR *ret = NULL;
+
+    if (!(hdr = find_smbios_entry( SMBIOS_TYPE_SYSTEM, buf, len )) || hdr->length < sizeof(*system)) goto done;
+    system = (const struct smbios_system *)hdr;
+    if (!memcmp( system->uuid, none, sizeof(none) ) || !(ret = heap_alloc( 37 * sizeof(WCHAR) ))) goto done;
+
+    ptr = system->uuid;
+    swprintf( ret, fmtW, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9],
+              ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15] );
+
+done:
+    if (!ret) ret = heap_strdupW( compsysproduct_uuidW );
+    return ret;
+}
+
+static WCHAR *get_compsysproduct_vendor( const char *buf, UINT len )
+{
+    WCHAR *ret = get_compsysproduct_string( 1, buf, len );
+    if (!ret) return heap_strdupW( compsysproduct_vendorW );
+    return ret;
+}
+
+static WCHAR *get_compsysproduct_version( const char *buf, UINT len )
+{
+    WCHAR *ret = get_compsysproduct_string( 3, buf, len );
+    if (!ret) return heap_strdupW( compsysproduct_versionW );
+    return ret;
 }
 
 static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond )
 {
     struct record_computersystemproduct *rec;
     enum fill_status status = FILL_STATUS_UNFILTERED;
-    UINT row = 0;
+    UINT row = 0, len;
+    char *buf;
 
     if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
 
+    len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
+    if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
+    GetSystemFirmwareTable( RSMB, 0, buf, len );
+
     rec = (struct record_computersystemproduct *)table->data;
-    rec->identifyingnumber = compsysproduct_identifyingnumberW;
-    rec->name              = compsysproduct_nameW;
+    rec->identifyingnumber = get_compsysproduct_identifyingnumber( buf, len );
+    rec->name              = get_compsysproduct_name( buf, len );
     rec->skunumber         = NULL;
-    rec->uuid              = get_compsysproduct_uuid();
-    rec->vendor            = compsysproduct_vendorW;
-    rec->version           = compsysproduct_versionW;
+    rec->uuid              = get_compsysproduct_uuid( buf, len );
+    rec->vendor            = get_compsysproduct_vendor( buf, len );
+    rec->version           = get_compsysproduct_version( buf, len );
     if (!match_row( table, row, cond, &status )) free_row_values( table, row );
     else row++;
 
+    heap_free( buf );
+
     TRACE("created %u rows\n", row);
     table->num_rows = row;
     return status;
@@ -1703,9 +2233,9 @@ static WCHAR *build_dirname( const WCHAR *path, UINT *ret_len )
     UINT len, i;
     WCHAR *ret;
 
-    if (!isalphaW( p[0] ) || p[1] != ':' || p[2] != '\\' || p[3] != '\\' || !p[4]) return NULL;
+    if (!iswalpha( p[0] ) || p[1] != ':' || p[2] != '\\' || p[3] != '\\' || !p[4]) return NULL;
     start = path + 4;
-    len = strlenW( start );
+    len = lstrlenW( start );
     p = start + len - 1;
     if (*p == '\\') return NULL;
 
@@ -1730,7 +2260,7 @@ static WCHAR *build_dirname( const WCHAR *path, UINT *ret_len )
 static BOOL seen_dir( struct dirstack *dirstack, const WCHAR *path )
 {
     UINT i;
-    for (i = 0; i < dirstack->num_dirs; i++) if (!strcmpW( dirstack->dirs[i], path )) return TRUE;
+    for (i = 0; i < dirstack->num_dirs; i++) if (!wcscmp( dirstack->dirs[i], path )) return TRUE;
     return FALSE;
 }
 
@@ -1750,14 +2280,14 @@ static UINT seed_dirs( struct dirstack *dirstack, const struct expr *cond, WCHAR
         const WCHAR *str = NULL;
 
         if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL &&
-            !strcmpW( left->u.propval->name, prop_nameW ) &&
-            toupperW( right->u.sval[0] ) == toupperW( root ))
+            !wcscmp( left->u.propval->name, prop_nameW ) &&
+            towupper( right->u.sval[0] ) == towupper( root ))
         {
             str = right->u.sval;
         }
         else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL &&
-                 !strcmpW( right->u.propval->name, prop_nameW ) &&
-                 toupperW( left->u.sval[0] ) == toupperW( root ))
+                 !wcscmp( right->u.propval->name, prop_nameW ) &&
+                 towupper( left->u.sval[0] ) == towupper( root ))
         {
             str = left->u.sval;
         }
@@ -1786,11 +2316,11 @@ static UINT seed_dirs( struct dirstack *dirstack, const struct expr *cond, WCHAR
 
 static WCHAR *append_path( const WCHAR *path, const WCHAR *segment, UINT *len )
 {
-    UINT len_path = 0, len_segment = strlenW( segment );
+    UINT len_path = 0, len_segment = lstrlenW( segment );
     WCHAR *ret;
 
     *len = 0;
-    if (path) len_path = strlenW( path );
+    if (path) len_path = lstrlenW( path );
     if (!(ret = heap_alloc( (len_path + len_segment + 2) * sizeof(WCHAR) ))) return NULL;
     if (path && len_path)
     {
@@ -1808,11 +2338,11 @@ static WCHAR *get_file_version( const WCHAR *filename )
 {
     static const WCHAR slashW[] = {'\\',0}, fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
     VS_FIXEDFILEINFO *info;
-    DWORD size;
+    DWORD size, len = 4 * 5 + ARRAY_SIZE( fmtW );
     void *block;
     WCHAR *ret;
 
-    if (!(ret = heap_alloc( (4 * 5 + ARRAY_SIZE( fmtW )) * sizeof(WCHAR) ))) return NULL;
+    if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
     if (!(size = GetFileVersionInfoSizeW( filename, NULL )) || !(block = heap_alloc( size )))
     {
         heap_free( ret );
@@ -1825,8 +2355,8 @@ static WCHAR *get_file_version( const WCHAR *filename )
         heap_free( ret );
         return NULL;
     }
-    sprintfW( ret, fmtW, info->dwFileVersionMS >> 16, info->dwFileVersionMS & 0xffff,
-                         info->dwFileVersionLS >> 16, info->dwFileVersionLS & 0xffff );
+    swprintf( ret, fmtW, info->dwFileVersionMS >> 16, info->dwFileVersionMS & 0xffff,
+                              info->dwFileVersionLS >> 16, info->dwFileVersionLS & 0xffff );
     heap_free( block );
     return ret;
 }
@@ -1877,7 +2407,7 @@ static enum fill_status fill_datafile( struct table *table, const struct expr *c
                         FindClose( handle );
                         goto done;
                     }
-                    if (!strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW )) continue;
+                    if (!wcscmp( data.cFileName, dotW ) || !wcscmp( data.cFileName, dotdotW )) continue;
                     new_path = append_path( path, data.cFileName, &len );
 
                     if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
@@ -1999,7 +2529,7 @@ static enum fill_status fill_directory( struct table *table, const struct expr *
                         goto done;
                     }
                     if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
-                        !strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW ))
+                        !wcscmp( data.cFileName, dotW ) || !wcscmp( data.cFileName, dotdotW ))
                         continue;
 
                     new_path = append_path( path, data.cFileName, &len );
@@ -2092,15 +2622,12 @@ static enum fill_status fill_diskdrive( struct table *table, const struct expr *
             if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
 
             rec = (struct record_diskdrive *)(table->data + offset);
-            sprintfW( device_id, fmtW, index );
+            swprintf( device_id, fmtW, index );
             rec->device_id     = heap_strdupW( device_id );
-            rec->index         = index;
+            rec->index         = index++;
             rec->interfacetype = diskdrive_interfacetypeW;
             rec->manufacturer  = diskdrive_manufacturerW;
-            if (type == DRIVE_FIXED)
-                rec->mediatype = diskdrive_mediatype_fixedW;
-            else
-                rec->mediatype = diskdrive_mediatype_removableW;
+            rec->mediatype     = (type == DRIVE_FIXED) ? diskdrive_mediatype_fixedW : diskdrive_mediatype_removableW;
             rec->model         = diskdrive_modelW;
             rec->pnpdevice_id  = diskdrive_pnpdeviceidW;
             rec->serialnumber  = diskdrive_serialW;
@@ -2112,7 +2639,6 @@ static enum fill_status fill_diskdrive( struct table *table, const struct expr *
                 continue;
             }
             offset += sizeof(*rec);
-            index++;
             row++;
         }
     }
@@ -2121,6 +2647,110 @@ static enum fill_status fill_diskdrive( struct table *table, const struct expr *
     return status;
 }
 
+struct association
+{
+    WCHAR *ref;
+    WCHAR *ref2;
+};
+
+static void free_assocations( struct association *assoc, UINT count )
+{
+    UINT i;
+    if (!assoc) return;
+    for (i = 0; i < count; i++)
+    {
+        heap_free( assoc[i].ref );
+        heap_free( assoc[i].ref2 );
+    }
+    heap_free( assoc );
+}
+
+static struct association *get_diskdrivetodiskpartition_pairs( UINT *count )
+{
+    static const WCHAR pathW[] =
+        {'_','_','P','A','T','H',0};
+    static const WCHAR selectW[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
+         'D','i','s','k','D','r','i','v','e',0};
+    static const WCHAR select2W[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
+         'D','i','s','k','P','a','r','t','i','t','i','o','n',0};
+    struct association *ret = NULL;
+    struct query *query, *query2 = NULL;
+    VARIANT val;
+    HRESULT hr;
+    UINT i;
+
+    if (!(query = create_query())) return NULL;
+    if ((hr = parse_query( selectW, &query->view, &query->mem )) != S_OK) goto done;
+    if ((hr = execute_view( query->view )) != S_OK) goto done;
+
+    if (!(query2 = create_query())) return FALSE;
+    if ((hr = parse_query( select2W, &query2->view, &query2->mem )) != S_OK) goto done;
+    if ((hr = execute_view( query2->view )) != S_OK) goto done;
+
+    if (!(ret = heap_alloc_zero( query->view->result_count * sizeof(*ret) ))) goto done;
+
+    for (i = 0; i < query->view->result_count; i++)
+    {
+        if ((hr = get_propval( query->view, i, pathW, &val, NULL, NULL )) != S_OK) goto done;
+        if (!(ret[i].ref = heap_strdupW( V_BSTR(&val) ))) goto done;
+        VariantClear( &val );
+
+        if ((hr = get_propval( query2->view, i, pathW, &val, NULL, NULL )) != S_OK) goto done;
+        if (!(ret[i].ref2 = heap_strdupW( V_BSTR(&val) ))) goto done;
+        VariantClear( &val );
+    }
+
+    *count = query->view->result_count;
+
+done:
+    if (!ret) free_assocations( ret, query->view->result_count );
+    free_query( query );
+    free_query( query2 );
+    return ret;
+}
+
+static enum fill_status fill_diskdrivetodiskpartition( struct table *table, const struct expr *cond )
+{
+    struct record_diskdrivetodiskpartition *rec;
+    UINT i, row = 0, offset = 0, count = 0;
+    enum fill_status status = FILL_STATUS_UNFILTERED;
+    struct association *assoc;
+
+    if (!(assoc = get_diskdrivetodiskpartition_pairs( &count ))) return FILL_STATUS_FAILED;
+    if (!count)
+    {
+        free_assocations( assoc, count );
+        return FILL_STATUS_UNFILTERED;
+    }
+    if (!resize_table( table, count, sizeof(*rec) ))
+    {
+        free_assocations( assoc, count );
+        return FILL_STATUS_FAILED;
+    }
+
+    for (i = 0; i < count; i++)
+    {
+        rec = (struct record_diskdrivetodiskpartition *)(table->data + offset);
+        rec->antecedent = assoc[i].ref;
+        rec->dependent  = assoc[i].ref2;
+        if (!match_row( table, row, cond, &status ))
+        {
+            free_row_values( table, row );
+            continue;
+        }
+        offset += sizeof(*rec);
+        row++;
+    }
+
+    heap_free( assoc );
+
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
+    return status;
+}
+
 static WCHAR *get_filesystem( const WCHAR *root )
 {
     static const WCHAR ntfsW[] = {'N','T','F','S',0};
@@ -2158,9 +2788,9 @@ static enum fill_status fill_diskpartition( struct table *table, const struct ex
             rec = (struct record_diskpartition *)(table->data + offset);
             rec->bootable       = (i == 2) ? -1 : 0;
             rec->bootpartition  = (i == 2) ? -1 : 0;
-            sprintfW( device_id, fmtW, index );
+            swprintf( device_id, fmtW, index );
             rec->device_id      = heap_strdupW( device_id );
-            rec->diskindex      = index;
+            rec->diskindex      = index++;
             rec->index          = 0;
             rec->pnpdevice_id   = heap_strdupW( device_id );
             get_freespace( root, &size );
@@ -2174,7 +2804,6 @@ static enum fill_status fill_diskpartition( struct table *table, const struct ex
             }
             offset += sizeof(*rec);
             row++;
-            index++;
         }
     }
     TRACE("created %u rows\n", row);
@@ -2182,13 +2811,49 @@ static enum fill_status fill_diskpartition( struct table *table, const struct ex
     return status;
 }
 
+static UINT32 get_bitsperpixel( UINT *hres, UINT *vres )
+{
+    HDC hdc = GetDC( NULL );
+    UINT32 ret;
+
+    if (!hdc) return 32;
+    ret = GetDeviceCaps( hdc, BITSPIXEL );
+    *hres = GetDeviceCaps( hdc, HORZRES );
+    *vres = GetDeviceCaps( hdc, VERTRES );
+    ReleaseDC( NULL, hdc );
+    return ret;
+}
+
+static enum fill_status fill_displaycontrollerconfig( struct table *table, const struct expr *cond )
+{
+    struct record_displaycontrollerconfig *rec;
+    UINT row = 0, hres = 1024, vres = 768;
+    enum fill_status status = FILL_STATUS_UNFILTERED;
+
+    if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
+
+    rec = (struct record_displaycontrollerconfig *)table->data;
+    rec->bitsperpixel         = get_bitsperpixel( &hres, &vres );
+    rec->caption              = videocontroller_deviceidW;
+    rec->horizontalresolution = hres;
+    rec->name                 = videocontroller_deviceidW;
+    rec->verticalresolution   = vres;
+    if (!match_row( table, row, cond, &status )) free_row_values( table, row );
+    else row++;
+
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
+    return status;
+}
+
 static WCHAR *get_ip4_string( DWORD addr )
 {
     static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
+    DWORD len = sizeof("ddd.ddd.ddd.ddd");
     WCHAR *ret;
 
-    if (!(ret = heap_alloc( sizeof("ddd.ddd.ddd.ddd") * sizeof(WCHAR) ))) return NULL;
-    sprintfW( ret, fmtW, (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff );
+    if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
+    swprintf( ret, fmtW, (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff );
     return ret;
 }
 
@@ -2248,7 +2913,7 @@ static WCHAR *get_volumeserialnumber( const WCHAR *root )
     WCHAR buffer[9];
 
     GetVolumeInformationW( root, NULL, 0, &serial, NULL, NULL, NULL, 0 );
-    sprintfW( buffer, fmtW, serial );
+    swprintf( buffer, fmtW, serial );
     return heap_strdupW( buffer );
 }
 
@@ -2276,7 +2941,7 @@ static enum fill_status fill_logicaldisk( struct table *table, const struct expr
             if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
 
             rec = (struct record_logicaldisk *)(table->data + offset);
-            sprintfW( device_id, fmtW, 'A' + i );
+            swprintf( device_id, fmtW, 'A' + i );
             rec->device_id          = heap_strdupW( device_id );
             rec->drivetype          = type;
             rec->filesystem         = get_filesystem( root );
@@ -2299,6 +2964,94 @@ static enum fill_status fill_logicaldisk( struct table *table, const struct expr
     return status;
 }
 
+static struct association *get_logicaldisktopartition_pairs( UINT *count )
+{
+    static const WCHAR pathW[] =
+        {'_','_','P','A','T','H',0};
+    static const WCHAR selectW[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
+         'D','i','s','k','P','a','r','t','i','t','i','o','n',0};
+    static const WCHAR select2W[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
+         'L','o','g','i','c','a','l','D','i','s','k',' ','W','H','E','R','E',' ',
+         'D','r','i','v','e','T','y','p','e','=','2',' ','O','R',' ','D','r','i','v','e','T','y','p','e','=','3',0};
+    struct association *ret = NULL;
+    struct query *query, *query2 = NULL;
+    VARIANT val;
+    HRESULT hr;
+    UINT i;
+
+    if (!(query = create_query())) return NULL;
+    if ((hr = parse_query( selectW, &query->view, &query->mem )) != S_OK) goto done;
+    if ((hr = execute_view( query->view )) != S_OK) goto done;
+
+    if (!(query2 = create_query())) return FALSE;
+    if ((hr = parse_query( select2W, &query2->view, &query2->mem )) != S_OK) goto done;
+    if ((hr = execute_view( query2->view )) != S_OK) goto done;
+
+    if (!(ret = heap_alloc_zero( query->view->result_count * sizeof(*ret) ))) goto done;
+
+    /* assume fixed and removable disks are enumerated in the same order as partitions */
+    for (i = 0; i < query->view->result_count; i++)
+    {
+        if ((hr = get_propval( query->view, i, pathW, &val, NULL, NULL )) != S_OK) goto done;
+        if (!(ret[i].ref = heap_strdupW( V_BSTR(&val) ))) goto done;
+        VariantClear( &val );
+
+        if ((hr = get_propval( query2->view, i, pathW, &val, NULL, NULL )) != S_OK) goto done;
+        if (!(ret[i].ref2 = heap_strdupW( V_BSTR(&val) ))) goto done;
+        VariantClear( &val );
+    }
+
+    *count = query->view->result_count;
+
+done:
+    if (!ret) free_assocations( ret, query->view->result_count );
+    free_query( query );
+    free_query( query2 );
+    return ret;
+}
+
+static enum fill_status fill_logicaldisktopartition( struct table *table, const struct expr *cond )
+{
+    struct record_logicaldisktopartition *rec;
+    UINT i, row = 0, offset = 0, count = 0;
+    enum fill_status status = FILL_STATUS_UNFILTERED;
+    struct association *assoc;
+
+    if (!(assoc = get_logicaldisktopartition_pairs( &count ))) return FILL_STATUS_FAILED;
+    if (!count)
+    {
+        free_assocations( assoc, count );
+        return FILL_STATUS_UNFILTERED;
+    }
+    if (!resize_table( table, count, sizeof(*rec) ))
+    {
+        free_assocations( assoc, count );
+        return FILL_STATUS_FAILED;
+    }
+
+    for (i = 0; i < count; i++)
+    {
+        rec = (struct record_logicaldisktopartition *)(table->data + offset);
+        rec->antecedent = assoc[i].ref;
+        rec->dependent  = assoc[i].ref2;
+        if (!match_row( table, row, cond, &status ))
+        {
+            free_row_values( table, row );
+            continue;
+        }
+        offset += sizeof(*rec);
+        row++;
+    }
+
+    heap_free( assoc );
+
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
+    return status;
+}
+
 static UINT16 get_connection_status( IF_OPER_STATUS status )
 {
     switch (status)
@@ -2321,10 +3074,10 @@ static WCHAR *get_mac_address( const BYTE *addr, DWORD len )
     WCHAR *ret;
 
     if (len != 6 || !(ret = heap_alloc( 18 * sizeof(WCHAR) ))) return NULL;
-    sprintfW( ret, fmtW, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] );
+    swprintf( ret, fmtW, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] );
     return ret;
 }
-static const WCHAR *get_adaptertype( DWORD type, int *physical )
+static const WCHAR *get_adaptertype( DWORD type, int *id, int *physical )
 {
     static const WCHAR ethernetW[] = {'E','t','h','e','r','n','e','t',' ','8','0','2','.','3',0};
     static const WCHAR wirelessW[] = {'W','i','r','e','l','e','s','s',0};
@@ -2333,11 +3086,26 @@ static const WCHAR *get_adaptertype( DWORD type, int *physical )
 
     switch (type)
     {
-    case IF_TYPE_ETHERNET_CSMACD: *physical = -1; return ethernetW;
-    case IF_TYPE_IEEE80211:       *physical = -1; return wirelessW;
-    case IF_TYPE_IEEE1394:        *physical = -1; return firewireW;
-    case IF_TYPE_TUNNEL:          *physical = 0; return tunnelW;
-    default:                      *physical = 0; return NULL;
+    case IF_TYPE_ETHERNET_CSMACD:
+        *id = 0;
+        *physical = -1;
+        return ethernetW;
+    case IF_TYPE_IEEE80211:
+        *id = 9;
+        *physical = -1;
+        return wirelessW;
+    case IF_TYPE_IEEE1394:
+        *id = 13;
+        *physical = -1;
+        return firewireW;
+    case IF_TYPE_TUNNEL:
+        *id = 15;
+        *physical = 0;
+        return tunnelW;
+    default:
+        *id = -1;
+        *physical = 0;
+        return NULL;
     }
 }
 
@@ -2349,7 +3117,7 @@ static enum fill_status fill_networkadapter( struct table *table, const struct e
     IP_ADAPTER_ADDRESSES *aa, *buffer;
     UINT row = 0, offset = 0, count = 0;
     DWORD size = 0, ret;
-    int physical;
+    int adaptertypeid, physical;
     enum fill_status status = FILL_STATUS_UNFILTERED;
 
     ret = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size );
@@ -2375,8 +3143,10 @@ static enum fill_status fill_networkadapter( struct table *table, const struct e
         if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
 
         rec = (struct record_networkadapter *)(table->data + offset);
-        sprintfW( device_id, fmtW, aa->u.s.IfIndex );
-        rec->adaptertype          = get_adaptertype( aa->IfType, &physical );
+        swprintf( device_id, fmtW, aa->u.s.IfIndex );
+        rec->adaptertype          = get_adaptertype( aa->IfType, &adaptertypeid, &physical );
+        rec->adaptertypeid        = adaptertypeid;
+        rec->description          = heap_strdupW( aa->Description );
         rec->device_id            = heap_strdupW( device_id );
         rec->index                = aa->u.s.IfIndex;
         rec->interface_index      = aa->u.s.IfIndex;
@@ -2440,8 +3210,9 @@ static struct array *get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS *list )
             return NULL;
         }
     }
-    ret->count = count;
-    ret->ptr   = ptr;
+    ret->elem_size = sizeof(*ptr);
+    ret->count     = count;
+    ret->ptr       = ptr;
     return ret;
 }
 static struct array *get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS *list )
@@ -2471,10 +3242,11 @@ static struct array *get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS *li
             heap_free( ret );
             return NULL;
         }
-        if ((p = strrchrW( ptr[i - 1], ':' ))) *p = 0;
+        if ((p = wcsrchr( ptr[i - 1], ':' ))) *p = 0;
     }
-    ret->count = count;
-    ret->ptr   = ptr;
+    ret->elem_size = sizeof(*ptr);
+    ret->count     = count;
+    ret->ptr       = ptr;
     return ret;
 }
 
@@ -2508,8 +3280,9 @@ static struct array *get_ipaddress( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
             return NULL;
         }
     }
-    ret->count = count;
-    ret->ptr   = ptr;
+    ret->elem_size = sizeof(*ptr);
+    ret->count     = count;
+    ret->ptr       = ptr;
     return ret;
 }
 static struct array *get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
@@ -2530,14 +3303,14 @@ static struct array *get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
     }
     for (address = list; address; address = address->Next)
     {
-        if (address->Address.lpSockaddr->sa_family == WS_AF_INET)
+        if (address->Address.lpSockaddr->sa_family == AF_INET)
         {
             WCHAR buf[INET_ADDRSTRLEN];
             SOCKADDR_IN addr;
             ULONG buflen = ARRAY_SIZE( buf );
 
             memset( &addr, 0, sizeof(addr) );
-            addr.sin_family = WS_AF_INET;
+            addr.sin_family = AF_INET;
             if (ConvertLengthToIpv4Mask( address->OnLinkPrefixLength, &addr.sin_addr.S_un.S_addr ) != NO_ERROR
                     || WSAAddressToStringW( (SOCKADDR*)&addr, sizeof(addr), NULL, buf, &buflen))
                 ptr[i] = NULL;
@@ -2549,7 +3322,7 @@ static struct array *get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
             static const WCHAR fmtW[] = {'%','u',0};
             WCHAR buf[11];
 
-            sprintfW(buf, fmtW, address->OnLinkPrefixLength);
+            swprintf( buf, fmtW, address->OnLinkPrefixLength );
             ptr[i] = heap_strdupW( buf );
         }
         if (!ptr[i++])
@@ -2560,8 +3333,9 @@ static struct array *get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
             return NULL;
         }
     }
-    ret->count = count;
-    ret->ptr   = ptr;
+    ret->elem_size = sizeof(*ptr);
+    ret->count     = count;
+    ret->ptr       = ptr;
     return ret;
 }
 
@@ -2643,6 +3417,7 @@ static enum fill_status fill_networkadapterconfig( struct table *table, const st
 
 static enum fill_status fill_physicalmemory( struct table *table, const struct expr *cond )
 {
+    static const WCHAR dimm0W[] = {'D','I','M','M',' ','0',0};
     struct record_physicalmemory *rec;
     enum fill_status status = FILL_STATUS_UNFILTERED;
     UINT row = 0;
@@ -2650,8 +3425,11 @@ static enum fill_status fill_physicalmemory( struct table *table, const struct e
     if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
 
     rec = (struct record_physicalmemory *)table->data;
-    rec->capacity   = get_total_physical_memory();
-    rec->memorytype = 9; /* RAM */
+    rec->capacity             = get_total_physical_memory();
+    rec->configuredclockspeed = 0;
+    rec->devicelocator        = dimm0W;
+    rec->memorytype           = 9; /* RAM */
+    rec->partnumber           = NULL;
     if (!match_row( table, row, cond, &status )) free_row_values( table, row );
     else row++;
 
@@ -2717,7 +3495,7 @@ static enum fill_status fill_printer( struct table *table, const struct expr *co
     WCHAR id[20];
 
     EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &size, &count );
-    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FILL_STATUS_FAILED;
+    if (!count) return FILL_STATUS_UNFILTERED;
 
     if (!(info = heap_alloc( size ))) return FILL_STATUS_FAILED;
     if (!EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, (BYTE *)info, size, &size, &count ))
@@ -2735,7 +3513,7 @@ static enum fill_status fill_printer( struct table *table, const struct expr *co
     {
         rec = (struct record_printer *)(table->data + offset);
         rec->attributes           = info[i].Attributes;
-        sprintfW( id, fmtW, i );
+        swprintf( id, fmtW, i );
         rec->device_id            = heap_strdupW( id );
         rec->drivername           = heap_strdupW( info[i].pDriverName );
         rec->horizontalresolution = info[i].pDevMode->u1.s1.dmPrintQuality;
@@ -2784,13 +3562,17 @@ static enum fill_status fill_process( struct table *table, const struct expr *co
 
     do
     {
-        if (!resize_table( table, row + 1, sizeof(*rec) )) goto done;
+        if (!resize_table( table, row + 1, sizeof(*rec) ))
+        {
+            status = FILL_STATUS_FAILED;
+            goto done;
+        }
 
         rec = (struct record_process *)(table->data + offset);
         rec->caption        = heap_strdupW( entry.szExeFile );
         rec->commandline    = get_cmdline( entry.th32ProcessID );
         rec->description    = heap_strdupW( entry.szExeFile );
-        sprintfW( handle, fmtW, entry.th32ProcessID );
+        swprintf( handle, fmtW, entry.th32ProcessID );
         rec->handle         = heap_strdupW( handle );
         rec->name           = heap_strdupW( entry.szExeFile );
         rec->process_id     = entry.th32ProcessID;
@@ -2809,27 +3591,85 @@ static enum fill_status fill_process( struct table *table, const struct expr *co
 
     TRACE("created %u rows\n", row);
     table->num_rows = row;
-    status = FILL_STATUS_UNFILTERED;
 
 done:
     CloseHandle( snap );
     return status;
 }
 
-static inline void do_cpuid( unsigned int ax, unsigned int *p )
+extern void do_cpuid( unsigned int ax, unsigned int *p );
+#if defined(_MSC_VER)
+void do_cpuid( unsigned int ax, unsigned int *p )
 {
-#ifdef __i386__
-#ifdef _MSC_VER
-    __cpuid(p, ax);
+    __cpuid( p, ax );
+}
+#elif defined(__i386__)
+__ASM_GLOBAL_FUNC( do_cpuid,
+                   "pushl %esi\n\t"
+                   "pushl %ebx\n\t"
+                   "movl 12(%esp),%eax\n\t"
+                   "movl 16(%esp),%esi\n\t"
+                   "cpuid\n\t"
+                   "movl %eax,(%esi)\n\t"
+                   "movl %ebx,4(%esi)\n\t"
+                   "movl %ecx,8(%esi)\n\t"
+                   "movl %edx,12(%esi)\n\t"
+                   "popl %ebx\n\t"
+                   "popl %esi\n\t"
+                   "ret" )
+#elif defined(__x86_64__)
+__ASM_GLOBAL_FUNC( do_cpuid,
+                   "pushq %rsi\n\t"
+                   "pushq %rbx\n\t"
+                   "movq %rcx,%rax\n\t"
+                   "movq %rdx,%rsi\n\t"
+                   "cpuid\n\t"
+                   "movl %eax,(%rsi)\n\t"
+                   "movl %ebx,4(%rsi)\n\t"
+                   "movl %ecx,8(%rsi)\n\t"
+                   "movl %edx,12(%rsi)\n\t"
+                   "popq %rbx\n\t"
+                   "popq %rsi\n\t"
+                   "ret" )
 #else
-    __asm__("pushl %%ebx\n\t"
-                "cpuid\n\t"
-                "movl %%ebx, %%esi\n\t"
-                "popl %%ebx"
-                : "=a" (p[0]), "=S" (p[1]), "=c" (p[2]), "=d" (p[3])
-                :  "0" (ax));
-#endif
+void do_cpuid( unsigned int ax, unsigned int *p )
+{
+    FIXME("\n");
+}
 #endif
+
+static unsigned int get_processor_model( unsigned int reg0, unsigned int *stepping, unsigned int *family )
+{
+    unsigned int model, family_id = (reg0 & (0x0f << 8)) >> 8;
+
+    model = (reg0 & (0x0f << 4)) >> 4;
+    if (family_id == 6 || family_id == 15) model |= (reg0 & (0x0f << 16)) >> 12;
+    if (family)
+    {
+        *family = family_id;
+        if (family_id == 15) *family += (reg0 & (0xff << 20)) >> 20;
+    }
+    *stepping = reg0 & 0x0f;
+    return model;
+}
+static void regs_to_str( unsigned int *regs, unsigned int len, WCHAR *buffer )
+{
+    unsigned int i;
+    unsigned char *p = (unsigned char *)regs;
+
+    for (i = 0; i < len; i++) { buffer[i] = *p++; }
+    buffer[i] = 0;
+}
+static void get_processor_manufacturer( WCHAR *manufacturer, UINT len )
+{
+    unsigned int tmp, regs[4] = {0, 0, 0, 0};
+
+    do_cpuid( 0, regs );
+    tmp = regs[2];      /* swap edx and ecx */
+    regs[2] = regs[3];
+    regs[3] = tmp;
+
+    regs_to_str( regs + 1, min( 12, len ), manufacturer );
 }
 static const WCHAR *get_osarchitecture(void)
 {
@@ -2838,27 +3678,39 @@ static const WCHAR *get_osarchitecture(void)
     if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) return os_64bitW;
     return os_32bitW;
 }
-static void get_processor_caption( WCHAR *caption )
+static void get_processor_caption( WCHAR *caption, UINT len )
 {
     static const WCHAR fmtW[] =
         {'%','s',' ','F','a','m','i','l','y',' ','%','u',' ',
          'M','o','d','e','l',' ','%','u',' ','S','t','e','p','p','i','n','g',' ','%','u',0};
     static const WCHAR x86W[] = {'x','8','6',0};
     static const WCHAR intel64W[] = {'I','n','t','e','l','6','4',0};
-    const WCHAR *arch = (get_osarchitecture() == os_32bitW) ? x86W : intel64W;
-    unsigned int regs[4] = {0, 0, 0, 0};
+    static const WCHAR amd64W[] = {'A','M','D','6','4',0};
+    static const WCHAR authenticamdW[] = {'A','u','t','h','e','n','t','i','c','A','M','D',0};
+    const WCHAR *arch;
+    WCHAR manufacturer[13];
+    unsigned int regs[4] = {0, 0, 0, 0}, family, model, stepping;
+
+    get_processor_manufacturer( manufacturer, ARRAY_SIZE( manufacturer ) );
+    if (get_osarchitecture() == os_32bitW) arch = x86W;
+    else if (!wcscmp( manufacturer, authenticamdW )) arch = amd64W;
+    else arch = intel64W;
 
     do_cpuid( 1, regs );
-    sprintfW( caption, fmtW, arch, (regs[0] & (15 << 8)) >> 8, (regs[0] & (15 << 4)) >> 4, regs[0] & 15 );
+
+    model = get_processor_model( regs[0], &stepping, &family );
+    swprintf( caption, fmtW, arch, family, model, stepping );
 }
-static void get_processor_version( WCHAR *version )
+static void get_processor_version( WCHAR *version, UINT len )
 {
     static const WCHAR fmtW[] =
         {'M','o','d','e','l',' ','%','u',',',' ','S','t','e','p','p','i','n','g',' ','%','u',0};
-    unsigned int regs[4] = {0, 0, 0, 0};
+    unsigned int regs[4] = {0, 0, 0, 0}, model, stepping;
 
     do_cpuid( 1, regs );
-    sprintfW( version, fmtW, (regs[0] & (15 << 4)) >> 4, regs[0] & 15 );
+
+    model = get_processor_model( regs[0], &stepping, NULL );
+    swprintf( version, fmtW, model, stepping );
 }
 static UINT16 get_processor_revision(void)
 {
@@ -2866,36 +3718,18 @@ static UINT16 get_processor_revision(void)
     do_cpuid( 1, regs );
     return regs[0];
 }
-static void get_processor_id( WCHAR *processor_id )
+static void get_processor_id( WCHAR *processor_id, UINT len )
 {
     static const WCHAR fmtW[] = {'%','0','8','X','%','0','8','X',0};
     unsigned int regs[4] = {0, 0, 0, 0};
 
     do_cpuid( 1, regs );
-    sprintfW( processor_id, fmtW, regs[3], regs[0] );
-}
-static void regs_to_str( unsigned int *regs, unsigned int len, WCHAR *buffer )
-{
-    unsigned int i;
-    unsigned char *p = (unsigned char *)regs;
-
-    for (i = 0; i < len; i++) { buffer[i] = *p++; }
-    buffer[i] = 0;
-}
-static void get_processor_manufacturer( WCHAR *manufacturer )
-{
-    unsigned int tmp, regs[4] = {0, 0, 0, 0};
-
-    do_cpuid( 0, regs );
-    tmp = regs[2];      /* swap edx and ecx */
-    regs[2] = regs[3];
-    regs[3] = tmp;
-
-    regs_to_str( regs + 1, 12, manufacturer );
+    swprintf( processor_id, fmtW, regs[3], regs[0] );
 }
 static void get_processor_name( WCHAR *name )
 {
     unsigned int regs[4] = {0, 0, 0, 0};
+    int i;
 
     do_cpuid( 0x80000000, regs );
     if (regs[0] >= 0x80000004)
@@ -2907,6 +3741,7 @@ static void get_processor_name( WCHAR *name )
         do_cpuid( 0x80000004, regs );
         regs_to_str( regs, 16, name + 32 );
     }
+    for (i = lstrlenW(name) - 1; i >= 0 && name[i] == ' '; i--) name[i] = 0;
 }
 static UINT get_processor_currentclockspeed( UINT index )
 {
@@ -2942,21 +3777,35 @@ static enum fill_status fill_processor( struct table *table, const struct expr *
     static const WCHAR fmtW[] = {'C','P','U','%','u',0};
     WCHAR caption[100], device_id[14], processor_id[17], manufacturer[13], name[49] = {0}, version[50];
     struct record_processor *rec;
+#ifdef __REACTOS__
     UINT i, offset = 0, num_rows = 0, num_cores, num_logical_processors, count = get_processor_count();
+#else
+    UINT i, offset = 0, num_rows = 0, num_logical, num_physical, num_packages;
+#endif
     enum fill_status status = FILL_STATUS_UNFILTERED;
 
+#ifdef __REACTOS__
     if (!resize_table( table, count, sizeof(*rec) )) return FILL_STATUS_FAILED;
+#else
+    num_logical = get_logical_processor_count( &num_physical, &num_packages );
+
+    if (!resize_table( table, num_packages, sizeof(*rec) )) return FILL_STATUS_FAILED;
+#endif
 
-    get_processor_caption( caption );
-    get_processor_id( processor_id );
-    get_processor_manufacturer( manufacturer );
+    get_processor_caption( caption, ARRAY_SIZE( caption ) );
+    get_processor_id( processor_id, ARRAY_SIZE( processor_id ) );
+    get_processor_manufacturer( manufacturer, ARRAY_SIZE( manufacturer ) );
     get_processor_name( name );
-    get_processor_version( version );
+    get_processor_version( version, ARRAY_SIZE( version ) );
 
+#ifdef __REACTOS__
     num_logical_processors = get_logical_processor_count( &num_cores ) / count;
     num_cores /= count;
 
     for (i = 0; i < count; i++)
+#else
+    for (i = 0; i < num_packages; i++)
+#endif
     {
         rec = (struct record_processor *)(table->data + offset);
         rec->addresswidth           = get_osarchitecture() == os_32bitW ? 32 : 64;
@@ -2966,15 +3815,20 @@ static enum fill_status fill_processor( struct table *table, const struct expr *
         rec->currentclockspeed      = get_processor_currentclockspeed( i );
         rec->datawidth              = get_osarchitecture() == os_32bitW ? 32 : 64;
         rec->description            = heap_strdupW( caption );
-        sprintfW( device_id, fmtW, i );
+        swprintf( device_id, fmtW, i );
         rec->device_id              = heap_strdupW( device_id );
         rec->family                 = 2; /* Unknown */
         rec->level                  = 15;
         rec->manufacturer           = heap_strdupW( manufacturer );
         rec->maxclockspeed          = get_processor_maxclockspeed( i );
         rec->name                   = heap_strdupW( name );
+#ifdef __REACTOS__
         rec->num_cores              = num_cores;
         rec->num_logical_processors = num_logical_processors;
+#else
+        rec->num_cores              = num_physical / num_packages;
+        rec->num_logical_processors = num_logical / num_packages;
+#endif
         rec->processor_id           = heap_strdupW( processor_id );
         rec->processortype          = 3; /* central processor */
         rec->revision               = get_processor_revision();
@@ -3007,7 +3861,7 @@ static WCHAR *get_lastbootuptime(void)
 
     NtQuerySystemInformation( SystemTimeOfDayInformation, &ti, sizeof(ti), NULL );
     RtlTimeToTimeFields( &ti.liKeBootTime, &tf );
-    sprintfW( ret, fmtW, tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute, tf.Second, tf.Milliseconds * 1000 );
+    swprintf( ret, fmtW, tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute, tf.Second, tf.Milliseconds * 1000 );
     return ret;
 }
 static WCHAR *get_localdatetime(void)
@@ -3032,7 +3886,7 @@ static WCHAR *get_localdatetime(void)
     if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL;
 
     GetLocalTime(&st);
-    sprintfW( ret, fmtW, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds * 1000, -Bias);
+    swprintf( ret, fmtW, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds * 1000, -Bias );
     return ret;
 }
 static WCHAR *get_systemdirectory(void)
@@ -3046,11 +3900,18 @@ static WCHAR *get_systemdirectory(void)
     Wow64RevertWow64FsRedirection( redir );
     return ret;
 }
+static WCHAR *get_systemdrive(void)
+{
+    WCHAR *ret = heap_alloc( 3 * sizeof(WCHAR) ); /* "c:" */
+    if (ret && GetEnvironmentVariableW( prop_systemdriveW, ret, 3 )) return ret;
+    heap_free( ret );
+    return NULL;
+}
 static WCHAR *get_codeset(void)
 {
     static const WCHAR fmtW[] = {'%','u',0};
     WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) );
-    if (ret) sprintfW( ret, fmtW, GetACP() );
+    if (ret) swprintf( ret, fmtW, GetACP() );
     return ret;
 }
 static WCHAR *get_countrycode(void)
@@ -3069,7 +3930,7 @@ static WCHAR *get_osbuildnumber( OSVERSIONINFOEXW *ver )
 {
     static const WCHAR fmtW[] = {'%','u',0};
     WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) );
-    if (ret) sprintfW( ret, fmtW, ver->dwBuildNumber );
+    if (ret) swprintf( ret, fmtW, ver->dwBuildNumber );
     return ret;
 }
 static WCHAR *get_oscaption( OSVERSIONINFOEXW *ver )
@@ -3130,7 +3991,7 @@ static WCHAR *get_osname( const WCHAR *caption )
     static const WCHAR partitionW[] =
         {'|','C',':','\\','W','I','N','D','O','W','S','|','\\','D','e','v','i','c','e','\\',
          'H','a','r','d','d','i','s','k','0','\\','P','a','r','t','i','t','i','o','n','1',0};
-    int len = strlenW( caption );
+    int len = lstrlenW( caption );
     WCHAR *ret;
 
     if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(partitionW) ))) return NULL;
@@ -3142,12 +4003,29 @@ static WCHAR *get_osversion( OSVERSIONINFOEXW *ver )
 {
     static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u',0};
     WCHAR *ret = heap_alloc( 33 * sizeof(WCHAR) );
-    if (ret) sprintfW( ret, fmtW, ver->dwMajorVersion, ver->dwMinorVersion, ver->dwBuildNumber );
+    if (ret) swprintf( ret, fmtW, ver->dwMajorVersion, ver->dwMinorVersion, ver->dwBuildNumber );
+    return ret;
+}
+#ifndef __REACTOS__
+static DWORD get_operatingsystemsku(void)
+{
+    DWORD ret = PRODUCT_UNDEFINED;
+    GetProductInfo( 6, 0, 0, 0, &ret );
     return ret;
 }
+#endif
+static INT16 get_currenttimezone(void)
+{
+    TIME_ZONE_INFORMATION info;
+    DWORD status = GetTimeZoneInformation( &info );
+    if (status == TIME_ZONE_ID_INVALID) return 0;
+    if (status == TIME_ZONE_ID_DAYLIGHT) return -(info.Bias + info.DaylightBias);
+    return -(info.Bias + info.StandardBias);
+}
 
-static enum fill_status fill_os( struct table *table, const struct expr *cond )
+static enum fill_status fill_operatingsystem( struct table *table, const struct expr *cond )
 {
+    static const WCHAR wineprojectW[] = {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
     struct record_operatingsystem *rec;
     enum fill_status status = FILL_STATUS_UNFILTERED;
     OSVERSIONINFOEXW ver;
@@ -3164,12 +4042,18 @@ static enum fill_status fill_os( struct table *table, const struct expr *cond )
     rec->codeset                = get_codeset();
     rec->countrycode            = get_countrycode();
     rec->csdversion             = ver.szCSDVersion[0] ? heap_strdupW( ver.szCSDVersion ) : NULL;
+    rec->csname                 = get_computername();
+    rec->currenttimezone        = get_currenttimezone();
     rec->freephysicalmemory     = get_available_physical_memory() / 1024;
     rec->installdate            = os_installdateW;
     rec->lastbootuptime         = get_lastbootuptime();
     rec->localdatetime          = get_localdatetime();
     rec->locale                 = get_locale();
+    rec->manufacturer           = wineprojectW;
     rec->name                   = get_osname( rec->caption );
+#ifndef __REACTOS__
+    rec->operatingsystemsku     = get_operatingsystemsku();
+#endif
     rec->osarchitecture         = get_osarchitecture();
     rec->oslanguage             = GetSystemDefaultLangID();
     rec->osproductsuite         = 2461140; /* Windows XP Professional  */
@@ -3180,6 +4064,7 @@ static enum fill_status fill_os( struct table *table, const struct expr *cond )
     rec->servicepackminor       = ver.wServicePackMinor;
     rec->suitemask              = 272;     /* Single User + Terminal */
     rec->systemdirectory        = get_systemdirectory();
+    rec->systemdrive            = get_systemdrive();
     rec->totalvirtualmemorysize = get_total_physical_memory() / 1024;
     rec->totalvisiblememorysize = rec->totalvirtualmemorysize;
     rec->version                = get_osversion( &ver );
@@ -3354,20 +4239,20 @@ static WCHAR *get_accountname( LSA_TRANSLATED_NAME *name )
 }
 static struct array *get_binaryrepresentation( PSID sid, UINT len )
 {
-    struct array *array = heap_alloc( sizeof(struct array) );
-    if (array)
+    struct array *ret;
+    UINT8 *ptr;
+
+    if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
+    if (!(ptr = heap_alloc( len )))
     {
-        UINT8 *ret = heap_alloc( len );
-        if (ret)
-        {
-            memcpy( ret, sid, len );
-            array->count = len;
-            array->ptr = ret;
-            return array;
-        }
-        heap_free( array );
+        heap_free( ret );
+        return NULL;
     }
-    return NULL;
+    memcpy( ptr, sid, len );
+    ret->elem_size = sizeof(*ptr);
+    ret->count     = len;
+    ret->ptr       = ptr;
+    return ret;
 }
 static WCHAR *get_referenceddomainname( LSA_REFERENCED_DOMAIN_LIST *domain )
 {
@@ -3383,11 +4268,11 @@ static const WCHAR *find_sid_str( const struct expr *cond )
 
     left = cond->u.expr.left;
     right = cond->u.expr.right;
-    if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL && !strcmpiW( left->u.propval->name, prop_sidW ))
+    if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL && !wcsicmp( left->u.propval->name, prop_sidW ))
     {
         ret = right->u.sval;
     }
-    else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL && !strcmpiW( right->u.propval->name, prop_sidW ))
+    else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL && !wcsicmp( right->u.propval->name, prop_sidW ))
     {
         ret = left->u.sval;
     }
@@ -3442,38 +4327,133 @@ static enum fill_status fill_sid( struct table *table, const struct expr *cond )
     return FILL_STATUS_FILTERED;
 }
 
-#ifndef __REACTOS__
+static WCHAR *get_systemenclosure_string( BYTE id, const char *buf, UINT len )
+{
+    const struct smbios_header *hdr;
+    const struct smbios_chassis *chassis;
+    UINT offset;
 
-static UINT32 get_bits_per_pixel( UINT *hres, UINT *vres )
+    if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len ))) return NULL;
+
+    chassis = (const struct smbios_chassis *)hdr;
+    offset = (const char *)chassis - buf + chassis->hdr.length;
+    return get_smbios_string( id, buf, offset, len );
+}
+
+static WCHAR *get_systemenclosure_manufacturer( const char *buf, UINT len )
 {
-    HDC hdc = GetDC( NULL );
-    UINT32 ret;
+    WCHAR *ret = get_systemenclosure_string( 1, buf, len );
+    if (!ret) return heap_strdupW( systemenclosure_manufacturerW );
+    return ret;
+}
 
-    if (!hdc) return 32;
-    ret = GetDeviceCaps( hdc, BITSPIXEL );
-    *hres = GetDeviceCaps( hdc, HORZRES );
-    *vres = GetDeviceCaps( hdc, VERTRES );
-    ReleaseDC( NULL, hdc );
+static int get_systemenclosure_lockpresent( const char *buf, UINT len )
+{
+    const struct smbios_header *hdr;
+    const struct smbios_chassis *chassis;
+
+    if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len )) || hdr->length < sizeof(*chassis)) return 0;
+
+    chassis = (const struct smbios_chassis *)hdr;
+    return (chassis->type & 0x80) ? -1 : 0;
+}
+
+static struct array *dup_array( const struct array *src )
+{
+    struct array *dst;
+    if (!(dst = heap_alloc( sizeof(*dst) ))) return NULL;
+    if (!(dst->ptr = heap_alloc( src->count * src->elem_size )))
+    {
+        heap_free( dst );
+        return NULL;
+    }
+    memcpy( dst->ptr, src->ptr, src->count * src->elem_size );
+    dst->elem_size = src->elem_size;
+    dst->count     = src->count;
+    return dst;
+}
+
+static struct array *get_systemenclosure_chassistypes( const char *buf, UINT len )
+{
+    const struct smbios_header *hdr;
+    const struct smbios_chassis *chassis;
+    struct array *ret = NULL;
+    UINT16 *types;
+
+    if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len )) || hdr->length < sizeof(*chassis)) goto done;
+    chassis = (const struct smbios_chassis *)hdr;
+
+    if (!(ret = heap_alloc( sizeof(*ret) ))) goto done;
+    if (!(types = heap_alloc( sizeof(*types) )))
+    {
+        heap_free( ret );
+        return NULL;
+    }
+    types[0] = chassis->type & ~0x80;
+
+    ret->elem_size = sizeof(*types);
+    ret->count     = 1;
+    ret->ptr       = types;
+
+done:
+    if (!ret) ret = dup_array( &systemenclosure_chassistypes_array );
     return ret;
 }
+
+static enum fill_status fill_systemenclosure( struct table *table, const struct expr *cond )
+{
+    struct record_systemenclosure *rec;
+    enum fill_status status = FILL_STATUS_UNFILTERED;
+    UINT row = 0, len;
+    char *buf;
+
+    if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
+
+    len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
+    if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
+    GetSystemFirmwareTable( RSMB, 0, buf, len );
+
+    rec = (struct record_systemenclosure *)table->data;
+    rec->caption      = systemenclosure_systemenclosureW;
+    rec->chassistypes = get_systemenclosure_chassistypes( buf, len );
+    rec->description  = systemenclosure_systemenclosureW;
+    rec->lockpresent  = get_systemenclosure_lockpresent( buf, len );
+    rec->manufacturer = get_systemenclosure_manufacturer( buf, len );
+    rec->name         = systemenclosure_systemenclosureW;
+    rec->tag          = systemenclosure_tagW;
+    if (!match_row( table, row, cond, &status )) free_row_values( table, row );
+    else row++;
+
+    heap_free( buf );
+
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
+    return status;
+}
+
+#ifndef __REACTOS__
 static WCHAR *get_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
 {
     static const WCHAR fmtW[] =
         {'P','C','I','\\','V','E','N','_','%','0','4','X','&','D','E','V','_','%','0','4','X',
          '&','S','U','B','S','Y','S','_','%','0','8','X','&','R','E','V','_','%','0','2','X','\\',
          '0','&','D','E','A','D','B','E','E','F','&','0','&','D','E','A','D',0};
+    UINT len = sizeof(fmtW) + 2;
     WCHAR *ret;
 
-    if (!(ret = heap_alloc( sizeof(fmtW) + 2 * sizeof(WCHAR) ))) return NULL;
-    sprintfW( ret, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision );
+    if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
+    swprintf( ret, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision );
     return ret;
 }
+#endif
 
 #define HW_VENDOR_AMD    0x1002
 #define HW_VENDOR_NVIDIA 0x10de
 #define HW_VENDOR_VMWARE 0x15ad
 #define HW_VENDOR_INTEL  0x8086
 
+#ifndef __REACTOS__
+
 static const WCHAR *get_installeddriver( UINT vendorid )
 {
     static const WCHAR driver_amdW[] = {'a','t','i','c','f','x','3','2','.','d','l','l',0};
@@ -3528,7 +4508,7 @@ done:
     rec->availability          = 3; /* Running or Full Power */
     rec->config_errorcode      = 0; /* no error */
     rec->caption               = heap_strdupW( name );
-    rec->current_bitsperpixel  = get_bits_per_pixel( &hres, &vres );
+    rec->current_bitsperpixel  = get_bitsperpixel( &hres, &vres );
     rec->current_horizontalres = hres;
     rec->current_refreshrate   = 0; /* default refresh rate */
     rec->current_scanmode      = 2; /* Unknown */
@@ -3543,7 +4523,7 @@ done:
     rec->status                = videocontroller_statusW;
     rec->videoarchitecture     = 2; /* Unknown */
     rec->videomemorytype       = 2; /* Unknown */
-    wsprintfW( mode, fmtW, hres, vres, (UINT64)1 << rec->current_bitsperpixel );
+    swprintf( mode, fmtW, hres, vres, (UINT64)1 << rec->current_bitsperpixel );
     rec->videomodedescription  = heap_strdupW( mode );
     rec->videoprocessor        = heap_strdupW( name );
     if (!match_row( table, row, cond, &status )) free_row_values( table, row );
@@ -3559,44 +4539,54 @@ done:
 
 #endif /* !__REACTOS__ */
 
+#define C(c) sizeof(c)/sizeof(c[0]), c
+#define D(d) sizeof(d)/sizeof(d[0]), 0, (BYTE *)d
 static struct table builtin_classes[] =
 {
-    { class_baseboardW, ARRAY_SIZE(col_baseboard), col_baseboard, ARRAY_SIZE(data_baseboard), 0, (BYTE *)data_baseboard },
-    { class_biosW, ARRAY_SIZE(col_bios), col_bios, ARRAY_SIZE(data_bios), 0, (BYTE *)data_bios },
-    { class_cdromdriveW, ARRAY_SIZE(col_cdromdrive), col_cdromdrive, 0, 0, NULL, fill_cdromdrive },
-    { class_compsysW, ARRAY_SIZE(col_compsys), col_compsys, 0, 0, NULL, fill_compsys },
-    { class_compsysproductW, ARRAY_SIZE(col_compsysproduct), col_compsysproduct, 0, 0, NULL, fill_compsysproduct },
-    { class_datafileW, ARRAY_SIZE(col_datafile), col_datafile, 0, 0, NULL, fill_datafile },
-    { class_desktopmonitorW, ARRAY_SIZE(col_desktopmonitor), col_desktopmonitor, 0, 0, NULL, fill_desktopmonitor },
-    { class_directoryW, ARRAY_SIZE(col_directory), col_directory, 0, 0, NULL, fill_directory },
-    { class_diskdriveW, ARRAY_SIZE(col_diskdrive), col_diskdrive, 0, 0, NULL, fill_diskdrive },
-    { class_diskpartitionW, ARRAY_SIZE(col_diskpartition), col_diskpartition, 0, 0, NULL, fill_diskpartition },
-    { class_ip4routetableW, ARRAY_SIZE(col_ip4routetable), col_ip4routetable, 0, 0, NULL, fill_ip4routetable },
-    { class_logicaldiskW, ARRAY_SIZE(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk },
-    { class_logicaldisk2W, ARRAY_SIZE(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk },
-    { class_networkadapterW, ARRAY_SIZE(col_networkadapter), col_networkadapter, 0, 0, NULL, fill_networkadapter },
-    { class_networkadapterconfigW, ARRAY_SIZE(col_networkadapterconfig), col_networkadapterconfig, 0, 0, NULL, fill_networkadapterconfig },
-    { class_osW, ARRAY_SIZE(col_os), col_os, 0, 0, NULL, fill_os },
-    { class_paramsW, ARRAY_SIZE(col_param), col_param, ARRAY_SIZE(data_param), 0, (BYTE *)data_param },
-    { class_physicalmediaW, ARRAY_SIZE(col_physicalmedia), col_physicalmedia, ARRAY_SIZE(data_physicalmedia), 0, (BYTE *)data_physicalmedia },
-    { class_physicalmemoryW, ARRAY_SIZE(col_physicalmemory), col_physicalmemory, 0, 0, NULL, fill_physicalmemory },
-    { class_pnpentityW, ARRAY_SIZE(col_pnpentity), col_pnpentity, 0, 0, NULL, fill_pnpentity },
-    { class_printerW, ARRAY_SIZE(col_printer), col_printer, 0, 0, NULL, fill_printer },
-    { class_processW, ARRAY_SIZE(col_process), col_process, 0, 0, NULL, fill_process },
-    { class_processorW, ARRAY_SIZE(col_processor), col_processor, 0, 0, NULL, fill_processor },
-    { class_processor2W, ARRAY_SIZE(col_processor), col_processor, 0, 0, NULL, fill_processor },
-    { class_qualifiersW, ARRAY_SIZE(col_qualifier), col_qualifier, ARRAY_SIZE(data_qualifier), 0, (BYTE *)data_qualifier },
-    { class_serviceW, ARRAY_SIZE(col_service), col_service, 0, 0, NULL, fill_service },
-    { class_sidW, ARRAY_SIZE(col_sid), col_sid, 0, 0, NULL, fill_sid },
-    { class_sounddeviceW, ARRAY_SIZE(col_sounddevice), col_sounddevice, ARRAY_SIZE(data_sounddevice), 0, (BYTE *)data_sounddevice },
-    { class_stdregprovW, ARRAY_SIZE(col_stdregprov), col_stdregprov, ARRAY_SIZE(data_stdregprov), 0, (BYTE *)data_stdregprov },
-    { class_systemsecurityW, ARRAY_SIZE(col_systemsecurity), col_systemsecurity, ARRAY_SIZE(data_systemsecurity), 0, (BYTE *)data_systemsecurity },
-    { class_systemenclosureW, ARRAY_SIZE(col_systemenclosure), col_systemenclosure, ARRAY_SIZE(data_systemenclosure), 0, (BYTE *)data_systemenclosure },
+    { class_associatorsW, C(col_associator), D(data_associator) },
+    { class_baseboardW, C(col_baseboard), 0, 0, NULL, fill_baseboard },
+    { class_biosW, C(col_bios), 0, 0, NULL, fill_bios },
+    { class_cdromdriveW, C(col_cdromdrive), 0, 0, NULL, fill_cdromdrive },
+    { class_compsysW, C(col_compsys), 0, 0, NULL, fill_compsys },
+    { class_compsysproductW, C(col_compsysproduct), 0, 0, NULL, fill_compsysproduct },
+    { class_datafileW, C(col_datafile), 0, 0, NULL, fill_datafile },
+    { class_desktopmonitorW, C(col_desktopmonitor), 0, 0, NULL, fill_desktopmonitor },
+    { class_directoryW, C(col_directory), 0, 0, NULL, fill_directory },
+    { class_diskdriveW, C(col_diskdrive), 0, 0, NULL, fill_diskdrive },
+    { class_diskdrivetodiskpartitionW, C(col_diskdrivetodiskpartition), 0, 0, NULL, fill_diskdrivetodiskpartition },
+    { class_diskpartitionW, C(col_diskpartition), 0, 0, NULL, fill_diskpartition },
+    { class_displaycontrollerconfigW, C(col_displaycontrollerconfig), 0, 0, NULL, fill_displaycontrollerconfig },
+    { class_ip4routetableW, C(col_ip4routetable), 0, 0, NULL, fill_ip4routetable },
+    { class_logicaldiskW, C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk },
+    { class_logicaldisk2W, C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk },
+    { class_logicaldisktopartitionW, C(col_logicaldisktopartition), 0, 0, NULL, fill_logicaldisktopartition },
+    { class_networkadapterW, C(col_networkadapter), 0, 0, NULL, fill_networkadapter },
+    { class_networkadapterconfigW, C(col_networkadapterconfig), 0, 0, NULL, fill_networkadapterconfig },
+    { class_operatingsystemW, C(col_operatingsystem), 0, 0, NULL, fill_operatingsystem },
+    { class_paramsW, C(col_param), D(data_param) },
+    { class_physicalmediaW, C(col_physicalmedia), D(data_physicalmedia) },
+    { class_physicalmemoryW, C(col_physicalmemory), 0, 0, NULL, fill_physicalmemory },
+    { class_pnpentityW, C(col_pnpentity), 0, 0, NULL, fill_pnpentity },
+    { class_printerW, C(col_printer), 0, 0, NULL, fill_printer },
+    { class_processW, C(col_process), 0, 0, NULL, fill_process },
+    { class_processorW, C(col_processor), 0, 0, NULL, fill_processor },
+    { class_processor2W, C(col_processor), 0, 0, NULL, fill_processor },
+    { class_qualifiersW, C(col_qualifier), D(data_qualifier) },
+    { class_quickfixengineeringW, C(col_quickfixengineering), D(data_quickfixengineering) },
+    { class_serviceW, C(col_service), 0, 0, NULL, fill_service },
+    { class_sidW, C(col_sid), 0, 0, NULL, fill_sid },
+    { class_sounddeviceW, C(col_sounddevice), D(data_sounddevice) },
+    { class_stdregprovW, C(col_stdregprov), D(data_stdregprov) },
+    { class_systemsecurityW, C(col_systemsecurity), D(data_systemsecurity) },
+    { class_systemenclosureW, C(col_systemenclosure), 0, 0, NULL, fill_systemenclosure },
 #ifndef __REACTOS__
     /* Requires dxgi.dll */
-    { class_videocontrollerW, ARRAY_SIZE(col_videocontroller), col_videocontroller, 0, 0, NULL, fill_videocontroller }
+    { class_videocontrollerW, C(col_videocontroller), 0, 0, NULL, fill_videocontroller },
 #endif
+    { class_winsatW, C(col_winsat), D(data_winsat) },
 };
+#undef C
+#undef D
 
 void init_table_list( void )
 {
index a005204..8000774 100644 (file)
 
 #define COBJMACROS
 
-#include "config.h"
 #include <stdarg.h>
+#ifdef __REACTOS__
+#include <wchar.h>
+#endif
 
 #include "windef.h"
 #include "winbase.h"
@@ -114,6 +116,7 @@ static HRESULT WINAPI enum_class_object_Next(
 {
     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
     struct view *view = ec->query->view;
+    struct table *table;
     static int once = 0;
     HRESULT hr;
 
@@ -124,14 +127,15 @@ static HRESULT WINAPI enum_class_object_Next(
     if (lTimeout != WBEM_INFINITE && !once++) FIXME("timeout not supported\n");
 
     *puReturned = 0;
-    if (ec->index >= view->count) return WBEM_S_FALSE;
+    if (ec->index >= view->result_count) return WBEM_S_FALSE;
 
-    hr = create_class_object( view->table->name, iface, ec->index, NULL, apObjects );
+    table = get_view_table( view, ec->index );
+    hr = create_class_object( table->name, iface, ec->index, NULL, apObjects );
     if (hr != S_OK) return hr;
 
     ec->index++;
     *puReturned = 1;
-    if (ec->index == view->count && uCount > 1) return WBEM_S_FALSE;
+    if (ec->index == view->result_count && uCount > 1) return WBEM_S_FALSE;
     if (uCount > 1) return WBEM_S_TIMEDOUT;
     return WBEM_S_NO_ERROR;
 }
@@ -169,11 +173,11 @@ static HRESULT WINAPI enum_class_object_Skip(
 
     if (lTimeout != WBEM_INFINITE && !once++) FIXME("timeout not supported\n");
 
-    if (!view->count) return WBEM_S_FALSE;
+    if (!view->result_count) return WBEM_S_FALSE;
 
-    if (nCount > view->count - ec->index)
+    if (nCount > view->result_count - ec->index)
     {
-        ec->index = view->count - 1;
+        ec->index = view->result_count - 1;
         return WBEM_S_FALSE;
     }
     ec->index += nCount;
@@ -226,7 +230,6 @@ static struct record *create_record( struct table *table )
     for (i = 0; i < table->num_cols; i++)
     {
         record->fields[i].type    = table->columns[i].type;
-        record->fields[i].vartype = table->columns[i].vartype;
         record->fields[i].u.ival  = 0;
     }
     record->count = table->num_cols;
@@ -236,13 +239,11 @@ static struct record *create_record( struct table *table )
 
 void destroy_array( struct array *array, CIMTYPE type )
 {
-    UINT i, size;
-
+    UINT i;
     if (!array) return;
-    if (type == CIM_STRING || type == CIM_DATETIME)
+    if (type == CIM_STRING || type == CIM_DATETIME || type == CIM_REFERENCE)
     {
-        size = get_type_size( type );
-        for (i = 0; i < array->count; i++) heap_free( *(WCHAR **)((char *)array->ptr + i * size) );
+        for (i = 0; i < array->count; i++) heap_free( *(WCHAR **)((char *)array->ptr + i * array->elem_size) );
     }
     heap_free( array->ptr );
     heap_free( array );
@@ -256,8 +257,9 @@ static void destroy_record( struct record *record )
     release_table( record->table );
     for (i = 0; i < record->count; i++)
     {
-        if (record->fields[i].type == CIM_STRING || record->fields[i].type == CIM_DATETIME)
-            heap_free( record->fields[i].u.sval );
+        if (record->fields[i].type == CIM_STRING ||
+            record->fields[i].type == CIM_DATETIME ||
+            record->fields[i].type == CIM_REFERENCE) heap_free( record->fields[i].u.sval );
         else if (record->fields[i].type & CIM_FLAG_ARRAY)
             destroy_array( record->fields[i].u.aval, record->fields[i].type & CIM_TYPE_MASK );
     }
@@ -338,19 +340,22 @@ static HRESULT WINAPI class_object_GetQualifierSet(
     IWbemClassObject *iface,
     IWbemQualifierSet **ppQualSet )
 {
-    FIXME("%p, %p\n", iface, ppQualSet);
-    return E_NOTIMPL;
+    struct class_object *co = impl_from_IWbemClassObject( iface );
+
+    TRACE("%p, %p\n", iface, ppQualSet);
+
+    return WbemQualifierSet_create( co->name, NULL, (void **)ppQualSet );
 }
 
 static HRESULT record_get_value( const struct record *record, UINT index, VARIANT *var, CIMTYPE *type )
 {
-    VARTYPE vartype = record->fields[index].vartype;
+    VARTYPE vartype = to_vartype( record->fields[index].type & CIM_TYPE_MASK );
 
     if (type) *type = record->fields[index].type;
 
     if (record->fields[index].type & CIM_FLAG_ARRAY)
     {
-        V_VT( var ) = vartype ? vartype : to_vartype( record->fields[index].type & CIM_TYPE_MASK ) | VT_ARRAY;
+        V_VT( var ) = vartype | VT_ARRAY;
         V_ARRAY( var ) = to_safearray( record->fields[index].u.aval, record->fields[index].type & CIM_TYPE_MASK );
         return S_OK;
     }
@@ -358,15 +363,13 @@ static HRESULT record_get_value( const struct record *record, UINT index, VARIAN
     {
     case CIM_STRING:
     case CIM_DATETIME:
-        if (!vartype) vartype = VT_BSTR;
+    case CIM_REFERENCE:
         V_BSTR( var ) = SysAllocString( record->fields[index].u.sval );
         break;
     case CIM_SINT32:
-        if (!vartype) vartype = VT_I4;
         V_I4( var ) = record->fields[index].u.ival;
         break;
     case CIM_UINT32:
-        if (!vartype) vartype = VT_UI4;
         V_UI4( var ) = record->fields[index].u.ival;
         break;
     default:
@@ -419,6 +422,7 @@ static HRESULT record_set_value( struct record *record, UINT index, VARIANT *var
     {
     case CIM_STRING:
     case CIM_DATETIME:
+    case CIM_REFERENCE:
         record->fields[index].u.sval = (WCHAR *)(INT_PTR)val;
         return S_OK;
     case CIM_SINT16:
@@ -488,7 +492,7 @@ static HRESULT WINAPI class_object_GetNames(
     if (wszQualifierName || pQualifierVal)
         FIXME("qualifier not supported\n");
 
-    return get_properties( ec->query->view, lFlags, pNames );
+    return get_properties( ec->query->view, co->index, lFlags, pNames );
 }
 
 static HRESULT WINAPI class_object_BeginEnumeration(
@@ -516,17 +520,18 @@ static HRESULT WINAPI class_object_Next(
     struct class_object *obj = impl_from_IWbemClassObject( iface );
     struct enum_class_object *iter = impl_from_IEnumWbemClassObject( obj->iter );
     struct view *view = iter->query->view;
+    struct table *table = get_view_table( view, obj->index );
     BSTR prop;
     HRESULT hr;
     UINT i;
 
     TRACE("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor);
 
-    for (i = obj->index_property; i < view->table->num_cols; i++)
+    for (i = obj->index_property; i < table->num_cols; i++)
     {
-        if (is_method( view->table, i )) continue;
-        if (!is_selected_prop( view, view->table->columns[i].name )) continue;
-        if (!(prop = SysAllocString( view->table->columns[i].name ))) return E_OUTOFMEMORY;
+        if (is_method( table, i )) continue;
+        if (!is_result_prop( view, table->columns[i].name )) continue;
+        if (!(prop = SysAllocString( table->columns[i].name ))) return E_OUTOFMEMORY;
         if ((hr = get_propval( view, obj->index, prop, pVal, pType, plFlavor )) != S_OK)
         {
             SysFreeString( prop );
@@ -586,7 +591,7 @@ static BSTR get_body_text( const struct table *table, UINT row, UINT *len )
         if ((value = get_value_bstr( table, row, i )))
         {
             *len += ARRAY_SIZE( fmtW );
-            *len += strlenW( table->columns[i].name );
+            *len += lstrlenW( table->columns[i].name );
             *len += SysStringLen( value );
             SysFreeString( value );
         }
@@ -597,7 +602,7 @@ static BSTR get_body_text( const struct table *table, UINT row, UINT *len )
     {
         if ((value = get_value_bstr( table, row, i )))
         {
-            p += sprintfW( p, fmtW, table->columns[i].name, value );
+            p += swprintf( p, fmtW, table->columns[i].name, value );
             SysFreeString( value );
         }
     }
@@ -609,15 +614,16 @@ static BSTR get_object_text( const struct view *view, UINT index )
     static const WCHAR fmtW[] =
         {'\n','i','n','s','t','a','n','c','e',' ','o','f',' ','%','s','\n','{','%','s','\n','}',';',0};
     UINT len, len_body, row = view->result[index];
+    struct table *table = get_view_table( view, index );
     BSTR ret, body;
 
     len = ARRAY_SIZE( fmtW );
-    len += strlenW( view->table->name );
-    if (!(body = get_body_text( view->table, row, &len_body ))) return NULL;
+    len += lstrlenW( table->name );
+    if (!(body = get_body_text( table, row, &len_body ))) return NULL;
     len += len_body;
 
     if (!(ret = SysAllocStringLen( NULL, len ))) return NULL;
-    sprintfW( ret, fmtW, view->table->name, body );
+    swprintf( ret, fmtW, table->name, body );
     SysFreeString( body );
     return ret;
 }
@@ -657,12 +663,12 @@ static HRESULT WINAPI class_object_SpawnInstance(
 {
     struct class_object *co = impl_from_IWbemClassObject( iface );
     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
-    struct view *view = ec->query->view;
+    struct table *table = get_view_table( ec->query->view, co->index );
     struct record *record;
 
     TRACE("%p, %08x, %p\n", iface, lFlags, ppNewInstance);
 
-    if (!(record = create_record( view->table ))) return E_OUTOFMEMORY;
+    if (!(record = create_record( table ))) return E_OUTOFMEMORY;
 
     return create_class_object( co->name, NULL, 0, record, ppNewInstance );
 }
@@ -728,7 +734,6 @@ static HRESULT create_signature_columns_and_data( IEnumWbemClassObject *iter, UI
 {
     static const WCHAR parameterW[] = {'P','a','r','a','m','e','t','e','r',0};
     static const WCHAR typeW[] = {'T','y','p','e',0};
-    static const WCHAR varianttypeW[] = {'V','a','r','i','a','n','t','T','y','p','e',0};
     static const WCHAR defaultvalueW[] = {'D','e','f','a','u','l','t','V','a','l','u','e',0};
     struct column *columns;
     BYTE *row;
@@ -757,10 +762,6 @@ static HRESULT create_signature_columns_and_data( IEnumWbemClassObject *iter, UI
         if (hr != S_OK) goto error;
         columns[i].type = V_UI4( &val );
 
-        hr = IWbemClassObject_Get( param, varianttypeW, 0, &val, NULL, NULL );
-        if (hr != S_OK) goto error;
-        columns[i].vartype = V_UI4( &val );
-
         hr = IWbemClassObject_Get( param, defaultvalueW, 0, &val, NULL, NULL );
         if (hr != S_OK) goto error;
         if (V_UI4( &val )) set_default_value( columns[i].type, V_UI4( &val ), row + offset );
@@ -807,12 +808,12 @@ static WCHAR *build_signature_table_name( const WCHAR *class, const WCHAR *metho
     static const WCHAR fmtW[] = {'_','_','%','s','_','%','s','_','%','s',0};
     static const WCHAR outW[] = {'O','U','T',0};
     static const WCHAR inW[] = {'I','N',0};
-    UINT len = ARRAY_SIZE(fmtW) + ARRAY_SIZE(outW) + strlenW( class ) + strlenW( method );
+    UINT len = ARRAY_SIZE(fmtW) + ARRAY_SIZE(outW) + lstrlenW( class ) + lstrlenW( method );
     WCHAR *ret;
 
     if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
-    sprintfW( ret, fmtW, class, method, dir == PARAM_IN ? inW : outW );
-    return struprW( ret );
+    swprintf( ret, fmtW, class, method, dir == PARAM_IN ? inW : outW );
+    return _wcsupr( ret );
 }
 
 HRESULT create_signature( const WCHAR *class, const WCHAR *method, enum param_direction dir,
@@ -831,9 +832,9 @@ HRESULT create_signature( const WCHAR *class, const WCHAR *method, enum param_di
     WCHAR *query, *name;
     HRESULT hr;
 
-    len += strlenW( class ) + strlenW( method );
+    len += lstrlenW( class ) + lstrlenW( method );
     if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
-    sprintfW( query, selectW, class, method, dir >= 0 ? geW : leW );
+    swprintf( query, selectW, class, method, dir >= 0 ? geW : leW );
 
     hr = exec_query( query, &iter );
     heap_free( query );
index e6ccd5c..d90f4f8 100644 (file)
@@ -17,8 +17,6 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "config.h"
-
 #include <stdarg.h>
 
 #define COBJMACROS
index 54f2817..91403f2 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef _WBEMPROX_PRECOMP_H_
 #define _WBEMPROX_PRECOMP_H_
 
-#include <wine/config.h>
-
 #include <stdarg.h>
 
 #define _INC_WINDOWS
index 6bc3f37..de9b03f 100644 (file)
@@ -20,7 +20,6 @@
 
 #define COBJMACROS
 
-#include "config.h"
 #include <stdarg.h>
 
 #include "windef.h"
index 06dcc59..7243a2d 100644 (file)
 
 #define COBJMACROS
 
-#include "config.h"
 #include <stdarg.h>
+#ifdef __REACTOS__
+#include <wchar.h>
+#endif
 
 #include "windef.h"
 #include "winbase.h"
@@ -102,19 +104,32 @@ static HRESULT create_qualifier_enum( const WCHAR *class, const WCHAR *member, c
         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','_','_','Q','U','A','L',
          'I','F','I','E','R','S',' ','W','H','E','R','E',' ','C','l','a','s','s','=',
          '\'','%','s','\'',' ','A','N','D',' ','M','e','m','b','e','r','=','\'','%','s','\'',0};
-    static const WCHAR noneW[] = {'_','_','N','O','N','E',0};
+    static const WCHAR fmt3W[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','_','_','Q','U','A','L',
+         'I','F','I','E','R','S',' ','W','H','E','R','E',' ','C','l','a','s','s','=',
+         '\'','%','s','\'',0};
     WCHAR *query;
     HRESULT hr;
     int len;
 
-    if (!member) member = noneW;
-    len = strlenW( class ) + strlenW( member );
-    if (name) len += strlenW( name ) + ARRAY_SIZE(fmtW);
-    else len += ARRAY_SIZE(fmt2W);
-
-    if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
-    if (name) sprintfW( query, fmtW, class, member, name );
-    else sprintfW( query, fmt2W, class, member );
+    if (member && name)
+    {
+        len = lstrlenW( class ) + lstrlenW( member ) + lstrlenW( name ) + ARRAY_SIZE(fmtW);
+        if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
+        swprintf( query, fmtW, class, member, name );
+    }
+    else if (member)
+    {
+        len = lstrlenW( class ) + lstrlenW( member ) + ARRAY_SIZE(fmt2W);
+        if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
+        swprintf( query, fmt2W, class, member );
+    }
+    else
+    {
+        len = lstrlenW( class ) + ARRAY_SIZE(fmt3W);
+        if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
+        swprintf( query, fmt3W, class );
+    }
 
     hr = exec_query( query, iter );
     heap_free( query );
@@ -124,9 +139,9 @@ static HRESULT create_qualifier_enum( const WCHAR *class, const WCHAR *member, c
 static HRESULT get_qualifier_value( const WCHAR *class, const WCHAR *member, const WCHAR *name,
                                     VARIANT *val, LONG *flavor )
 {
-    static const WCHAR qualifiersW[] = {'_','_','Q','U','A','L','I','F','I','E','R','S',0};
     static const WCHAR intvalueW[] = {'I','n','t','e','g','e','r','V','a','l','u','e',0};
     static const WCHAR strvalueW[] = {'S','t','r','i','n','g','V','a','l','u','e',0};
+    static const WCHAR boolvalueW[] = {'B','o','o','l','V','a','l','u','e',0};
     static const WCHAR flavorW[] = {'F','l','a','v','o','r',0};
     static const WCHAR typeW[] = {'T','y','p','e',0};
     IEnumWbemClassObject *iter;
@@ -137,7 +152,7 @@ static HRESULT get_qualifier_value( const WCHAR *class, const WCHAR *member, con
     hr = create_qualifier_enum( class, member, name, &iter );
     if (FAILED( hr )) return hr;
 
-    hr = create_class_object( qualifiersW, iter, 0, NULL, &obj );
+    hr = create_class_object( NULL, iter, 0, NULL, &obj );
     IEnumWbemClassObject_Release( iter );
     if (FAILED( hr )) return hr;
 
@@ -157,6 +172,9 @@ static HRESULT get_qualifier_value( const WCHAR *class, const WCHAR *member, con
     case CIM_SINT32:
         hr = IWbemClassObject_Get( obj, intvalueW, 0, val, NULL, NULL );
         break;
+    case CIM_BOOLEAN:
+        hr = IWbemClassObject_Get( obj, boolvalueW, 0, val, NULL, NULL );
+        break;
     default:
         ERR("unhandled type %u\n", V_UI4( &var ));
         break;
@@ -176,7 +194,12 @@ static HRESULT WINAPI qualifier_set_Get(
 {
     struct qualifier_set *set = impl_from_IWbemQualifierSet( iface );
 
-    FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, plFlavor);
+    TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, plFlavor);
+    if (lFlags)
+    {
+        FIXME("flags %08x not supported\n", lFlags);
+        return E_NOTIMPL;
+    }
     return get_qualifier_value( set->class, set->member, wszName, pVal, plFlavor );
 }
 
@@ -203,8 +226,28 @@ static HRESULT WINAPI qualifier_set_GetNames(
     LONG lFlags,
     SAFEARRAY **pNames )
 {
-    FIXME("%p, %08x, %p\n", iface, lFlags, pNames);
-    return E_NOTIMPL;
+    struct qualifier_set *set = impl_from_IWbemQualifierSet( iface );
+    IEnumWbemClassObject *iter;
+    IWbemClassObject *obj;
+    HRESULT hr;
+
+    TRACE("%p, %08x, %p\n", iface, lFlags, pNames);
+    if (lFlags)
+    {
+        FIXME("flags %08x not supported\n", lFlags);
+        return E_NOTIMPL;
+    }
+
+    hr = create_qualifier_enum( set->class, set->member, NULL, &iter );
+    if (FAILED( hr )) return hr;
+
+    hr = create_class_object( NULL, iter, 0, NULL, &obj );
+    IEnumWbemClassObject_Release( iter );
+    if (FAILED( hr )) return hr;
+
+    hr = IWbemClassObject_GetNames( obj, NULL, 0, NULL, pNames );
+    IWbemClassObject_Release( obj );
+    return hr;
 }
 
 static HRESULT WINAPI qualifier_set_BeginEnumeration(
index d193574..85c9379 100644 (file)
 
 #define COBJMACROS
 
-#include "config.h"
 #include <stdarg.h>
+#ifdef __REACTOS__
+#include <wchar.h>
+#endif
 
 #include "windef.h"
 #include "winbase.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
 
-HRESULT create_view( const struct property *proplist, const WCHAR *class,
-                     const struct expr *cond, struct view **ret )
+static HRESULT append_table( struct view *view, struct table *table )
 {
-    struct view *view = heap_alloc( sizeof(struct view) );
+    struct table **tmp;
+    if (!(tmp = heap_realloc( view->table, (view->table_count + 1) * sizeof(*tmp) ))) return E_OUTOFMEMORY;
+    view->table = tmp;
+    view->table[view->table_count++] = table;
+    return S_OK;
+}
+
+HRESULT create_view( enum view_type type, const WCHAR *path, const struct keyword *keywordlist, const WCHAR *class,
+                     const struct property *proplist, const struct expr *cond, struct view **ret )
+{
+    struct view *view = heap_alloc_zero( sizeof(*view) );
 
     if (!view) return E_OUTOFMEMORY;
-    view->proplist = proplist;
-    view->table    = grab_table( class );
-    view->cond     = cond;
-    view->result   = NULL;
-    view->count    = 0;
+
+    switch (type)
+    {
+    case VIEW_TYPE_ASSOCIATORS:
+        view->path        = path;
+        view->keywordlist = keywordlist;
+        break;
+
+    case VIEW_TYPE_SELECT:
+    {
+        struct table *table = grab_table( class );
+        HRESULT hr;
+
+        if (table && (hr = append_table( view, table )) != S_OK)
+        {
+            heap_free( view );
+            return hr;
+        }
+        view->proplist = proplist;
+        view->cond     = cond;
+        break;
+    }
+    default:
+        ERR( "unhandled type %u\n", type );
+        heap_free( view );
+        return E_INVALIDARG;
+    }
+
+    view->type = type;
     *ret = view;
     return S_OK;
 }
 
 void destroy_view( struct view *view )
 {
+    ULONG i;
     if (!view) return;
-    if (view->table) release_table( view->table );
+    for (i = 0; i < view->table_count; i++) release_table( view->table[i] );
+    heap_free( view->table );
     heap_free( view->result );
     heap_free( view );
 }
@@ -63,10 +100,10 @@ static BOOL eval_like( const WCHAR *lstr, const WCHAR *rstr )
         {
             while (*q == '%') q++;
             if (!*q) return TRUE;
-            while (*p && *q && toupperW( *p ) == toupperW( *q )) { p++; q++; };
+            while (*p && *q && towupper( *p ) == towupper( *q )) { p++; q++; };
             if (!*p && !*q) return TRUE;
         }
-        if (*q != '%' && toupperW( *p++ ) != toupperW( *q++ )) return FALSE;
+        if (*q != '%' && towupper( *p++ ) != towupper( *q++ )) return FALSE;
     }
     return TRUE;
 }
@@ -81,22 +118,22 @@ static HRESULT eval_strcmp( UINT op, const WCHAR *lstr, const WCHAR *rstr, LONGL
     switch (op)
     {
     case OP_EQ:
-        *val = !strcmpW( lstr, rstr );
+        *val = !wcscmp( lstr, rstr );
         break;
     case OP_GT:
-        *val = strcmpW( lstr, rstr ) > 0;
+        *val = wcscmp( lstr, rstr ) > 0;
         break;
     case OP_LT:
-        *val = strcmpW( lstr, rstr ) < 0;
+        *val = wcscmp( lstr, rstr ) < 0;
         break;
     case OP_LE:
-        *val = strcmpW( lstr, rstr ) <= 0;
+        *val = wcscmp( lstr, rstr ) <= 0;
         break;
     case OP_GE:
-        *val = strcmpW( lstr, rstr ) >= 0;
+        *val = wcscmp( lstr, rstr ) >= 0;
         break;
     case OP_NE:
-        *val = strcmpW( lstr, rstr );
+        *val = wcscmp( lstr, rstr );
         break;
     case OP_LIKE:
         *val = eval_like( lstr, rstr );
@@ -148,8 +185,8 @@ static HRESULT eval_boolcmp( UINT op, LONGLONG lval, LONGLONG rval, UINT ltype,
 {
     static const WCHAR trueW[] = {'T','r','u','e',0};
 
-    if (ltype == CIM_STRING) lval = !strcmpiW( (const WCHAR *)(INT_PTR)lval, trueW ) ? -1 : 0;
-    else if (rtype == CIM_STRING) rval = !strcmpiW( (const WCHAR *)(INT_PTR)rval, trueW ) ? -1 : 0;
+    if (ltype == CIM_STRING) lval = !wcsicmp( (const WCHAR *)(INT_PTR)lval, trueW ) ? -1 : 0;
+    else if (rtype == CIM_STRING) rval = !wcsicmp( (const WCHAR *)(INT_PTR)rval, trueW ) ? -1 : 0;
 
     switch (op)
     {
@@ -166,6 +203,35 @@ static HRESULT eval_boolcmp( UINT op, LONGLONG lval, LONGLONG rval, UINT ltype,
     return S_OK;
 }
 
+static inline BOOL is_refcmp( const struct complex_expr *expr, UINT ltype, UINT rtype )
+{
+    if (ltype == CIM_REFERENCE && expr->left->type == EXPR_PROPVAL && expr->right->type == EXPR_SVAL) return TRUE;
+    else if (rtype == CIM_REFERENCE && expr->right->type == EXPR_PROPVAL && expr->left->type == EXPR_SVAL) return TRUE;
+    return FALSE;
+}
+
+static HRESULT eval_refcmp( UINT op, const WCHAR *lstr, const WCHAR *rstr, LONGLONG *val )
+{
+    if (!lstr || !rstr)
+    {
+        *val = 0;
+        return S_OK;
+    }
+    switch (op)
+    {
+    case OP_EQ:
+        *val = !wcsicmp( lstr, rstr );
+        break;
+    case OP_NE:
+        *val = wcsicmp( lstr, rstr );
+        break;
+    default:
+        ERR("unhandled operator %u\n", op);
+        return WBEM_E_INVALID_QUERY;
+    }
+    return S_OK;
+}
+
 static UINT resolve_type( UINT left, UINT right )
 {
     switch (left)
@@ -201,13 +267,17 @@ static UINT resolve_type( UINT left, UINT right )
         if (right == CIM_BOOLEAN) return CIM_BOOLEAN;
         break;
 
+    case CIM_REFERENCE:
+        if (right == CIM_REFERENCE) return CIM_REFERENCE;
+        break;
+
     default:
         break;
     }
     return CIM_ILLEGAL;
 }
 
-static const WCHAR *format_int( WCHAR *buf, CIMTYPE type, LONGLONG val )
+static const WCHAR *format_int( WCHAR *buf, UINT len, CIMTYPE type, LONGLONG val )
 {
     static const WCHAR fmt_signedW[] = {'%','d',0};
     static const WCHAR fmt_unsignedW[] = {'%','u',0};
@@ -219,13 +289,13 @@ static const WCHAR *format_int( WCHAR *buf, CIMTYPE type, LONGLONG val )
     case CIM_SINT8:
     case CIM_SINT16:
     case CIM_SINT32:
-        sprintfW( buf, fmt_signedW, val );
+        swprintf( buf, fmt_signedW, val );
         return buf;
 
     case CIM_UINT8:
     case CIM_UINT16:
     case CIM_UINT32:
-        sprintfW( buf, fmt_unsignedW, val );
+        swprintf( buf, fmt_unsignedW, val );
         return buf;
 
     case CIM_SINT64:
@@ -255,22 +325,28 @@ static HRESULT eval_binary( const struct table *table, UINT row, const struct co
 
     *type = resolve_type( ltype, rtype );
 
-    if (is_boolcmp( expr, ltype, rtype ))
-        return eval_boolcmp( expr->op, lval, rval, ltype, rtype, val );
-
     if (is_strcmp( expr, ltype, rtype ))
     {
         const WCHAR *lstr, *rstr;
         WCHAR lbuf[21], rbuf[21];
 
-        if (is_int( ltype )) lstr = format_int( lbuf, ltype, lval );
+        if (is_int( ltype )) lstr = format_int( lbuf, ARRAY_SIZE( lbuf ), ltype, lval );
         else lstr = (const WCHAR *)(INT_PTR)lval;
 
-        if (is_int( rtype )) rstr = format_int( rbuf, rtype, rval );
+        if (is_int( rtype )) rstr = format_int( rbuf, ARRAY_SIZE( rbuf ), rtype, rval );
         else rstr = (const WCHAR *)(INT_PTR)rval;
 
         return eval_strcmp( expr->op, lstr, rstr, val );
     }
+    if (is_boolcmp( expr, ltype, rtype ))
+    {
+        return eval_boolcmp( expr->op, lval, rval, ltype, rtype, val );
+    }
+    if (is_refcmp( expr, ltype, rtype ))
+    {
+        return eval_refcmp( expr->op, (const WCHAR *)(INT_PTR)lval, (const WCHAR *)(INT_PTR)rval, val );
+    }
+
     switch (expr->op)
     {
     case OP_EQ:
@@ -402,22 +478,243 @@ HRESULT eval_cond( const struct table *table, UINT row, const struct expr *cond,
     return WBEM_E_INVALID_QUERY;
 }
 
-HRESULT execute_view( struct view *view )
+static WCHAR *build_assoc_query( const WCHAR *class, UINT class_len )
+{
+    static const WCHAR fmtW[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','_','_','A','S','S','O','C','I','A','T','O','R','S',
+         ' ','W','H','E','R','E',' ','C','l','a','s','s','=','\'','%','s','\'',0};
+    UINT len = class_len + ARRAY_SIZE(fmtW);
+    WCHAR *ret;
+
+    if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
+    swprintf( ret, fmtW, class );
+    return ret;
+}
+
+static HRESULT create_assoc_enum( const WCHAR *class, UINT class_len, IEnumWbemClassObject **iter )
+{
+    WCHAR *query;
+    HRESULT hr;
+
+    if (!(query = build_assoc_query( class, class_len ))) return E_OUTOFMEMORY;
+    hr = exec_query( query, iter );
+    heap_free( query );
+    return hr;
+}
+
+static WCHAR *build_antecedent_query( const WCHAR *assocclass, const WCHAR *dependent )
+{
+    static const WCHAR fmtW[] =
+        {'S','E','L','E','C','T',' ','A','n','t','e','c','e','d','e','n','t',' ','F','R','O','M',' ','%','s',' ',
+         'W','H','E','R','E',' ','D','e','p','e','n','d','e','n','t','=','\'','%','s','\'',0};
+    UINT len = lstrlenW(assocclass) + lstrlenW(dependent) + ARRAY_SIZE(fmtW);
+    WCHAR *ret;
+
+    if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
+    swprintf( ret, fmtW, assocclass, dependent );
+    return ret;
+}
+
+static BSTR build_servername(void)
+{
+    WCHAR server[MAX_COMPUTERNAME_LENGTH + 1], *p;
+    DWORD len = ARRAY_SIZE( server );
+
+    if (!(GetComputerNameW( server, &len ))) return NULL;
+    for (p = server; *p; p++) *p = towupper( *p );
+    return SysAllocString( server );
+}
+
+static BSTR build_namespace(void)
+{
+    static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0};
+    return SysAllocString( cimv2W );
+}
+
+static WCHAR *build_canonical_path( const WCHAR *relpath )
+{
+    static const WCHAR fmtW[] = {'\\','\\','%','s','\\','%','s',':',0};
+    BSTR server, namespace;
+    WCHAR *ret;
+    UINT len, i;
+
+    if (!(server = build_servername())) return NULL;
+    if (!(namespace = build_namespace()))
+    {
+        SysFreeString( server );
+        return NULL;
+    }
+
+    len = ARRAY_SIZE( fmtW ) + SysStringLen( server ) + SysStringLen( namespace ) + lstrlenW( relpath );
+    if ((ret = heap_alloc( len * sizeof(WCHAR ) )))
+    {
+        len = swprintf( ret, fmtW, server, namespace );
+        for (i = 0; i < lstrlenW( relpath ); i ++)
+        {
+            if (relpath[i] == '\'') ret[len++] = '"';
+            else ret[len++] = relpath[i];
+        }
+        ret[len] = 0;
+    }
+
+    SysFreeString( server );
+    SysFreeString( namespace );
+    return ret;
+}
+
+static HRESULT get_antecedent( const WCHAR *assocclass, const WCHAR *dependent, BSTR *ret )
+{
+    static const WCHAR antecedentW[] = {'A','n','t','e','c','e','d','e','n','t',0};
+    WCHAR *fullpath, *str;
+    IEnumWbemClassObject *iter = NULL;
+    IWbemClassObject *obj;
+    HRESULT hr = E_OUTOFMEMORY;
+    ULONG count;
+    VARIANT var;
+
+    if (!(fullpath = build_canonical_path( dependent ))) return E_OUTOFMEMORY;
+    if (!(str = build_antecedent_query( assocclass, fullpath ))) goto done;
+    if ((hr = exec_query( str, &iter )) != S_OK) goto done;
+
+    IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, &obj, &count );
+    if (!count)
+    {
+        *ret = NULL;
+        goto done;
+    }
+
+    hr = IWbemClassObject_Get( obj, antecedentW, 0, &var, NULL, NULL );
+    IWbemClassObject_Release( obj );
+    if (hr != S_OK) goto done;
+    *ret = V_BSTR( &var );
+
+done:
+    if (iter) IEnumWbemClassObject_Release( iter );
+    heap_free( str );
+    heap_free( fullpath );
+    return hr;
+}
+
+static HRESULT do_query( const WCHAR *str, struct query **ret_query )
+{
+    struct query *query;
+    HRESULT hr;
+
+    if (!(query = create_query())) return E_OUTOFMEMORY;
+    if ((hr = parse_query( str, &query->view, &query->mem )) != S_OK || (hr = execute_view( query->view )) != S_OK)
+    {
+        release_query( query );
+        return hr;
+    }
+    *ret_query = query;
+    return S_OK;
+}
+
+static HRESULT get_antecedent_table( const WCHAR *assocclass, const WCHAR *dependent, struct table **table )
+{
+    BSTR antecedent = NULL;
+    struct path *path = NULL;
+    WCHAR *str = NULL;
+    struct query *query = NULL;
+    HRESULT hr;
+
+    if ((hr = get_antecedent( assocclass, dependent, &antecedent )) != S_OK) return hr;
+    if (!antecedent)
+    {
+        *table = NULL;
+        return S_OK;
+    }
+    if ((hr = parse_path( antecedent, &path )) != S_OK) goto done;
+    if (!(str = query_from_path( path )))
+    {
+        hr = E_OUTOFMEMORY;
+        goto done;
+    }
+
+    if ((hr = do_query( str, &query )) != S_OK) goto done;
+    if (query->view->table_count) *table = addref_table( query->view->table[0] );
+    else *table = NULL;
+
+done:
+    if (query) release_query( query );
+    free_path( path );
+    SysFreeString( antecedent );
+    heap_free( str );
+    return hr;
+}
+
+static HRESULT exec_assoc_view( struct view *view )
+{
+    static const WCHAR assocclassW[] = {'A','s','s','o','c','C','l','a','s','s',0};
+    IEnumWbemClassObject *iter = NULL;
+    struct path *path;
+    HRESULT hr;
+
+    if (view->keywordlist) FIXME( "ignoring keywords\n" );
+    if ((hr = parse_path( view->path, &path )) != S_OK) return hr;
+
+    if ((hr = create_assoc_enum( path->class, path->class_len, &iter )) != S_OK) goto done;
+    for (;;)
+    {
+        ULONG count;
+        IWbemClassObject *obj;
+        struct table *table;
+        VARIANT var;
+
+        IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, &obj, &count );
+        if (!count) break;
+
+        if ((hr = IWbemClassObject_Get( obj, assocclassW, 0, &var, NULL, NULL )) != S_OK)
+        {
+            IWbemClassObject_Release( obj );
+            goto done;
+        }
+        IWbemClassObject_Release( obj );
+
+        hr = get_antecedent_table( V_BSTR(&var), view->path, &table );
+        VariantClear( &var );
+        if (hr != S_OK) goto done;
+
+        if (table && (hr = append_table( view, table )) != S_OK)
+        {
+            release_table( table );
+            goto done;
+        }
+    }
+
+    if (view->table_count)
+    {
+        if (!(view->result = heap_alloc_zero( view->table_count * sizeof(UINT) ))) hr = E_OUTOFMEMORY;
+        else view->result_count = view->table_count;
+    }
+
+done:
+    if (iter) IEnumWbemClassObject_Release( iter );
+    free_path( path );
+    return hr;
+}
+
+static HRESULT exec_select_view( struct view *view )
 {
     UINT i, j = 0, len;
+    enum fill_status status = FILL_STATUS_UNFILTERED;
+    struct table *table;
+
+    if (!view->table_count) return S_OK;
 
-    if (!view->table) return S_OK;
-    if (view->table->fill)
+    table = view->table[0];
+    if (table->fill)
     {
-        clear_table( view->table );
-        view->table->fill( view->table, view->cond );
+        clear_table( table );
+        status = table->fill( table, view->cond );
     }
-    if (!view->table->num_rows) return S_OK;
+    if (status == FILL_STATUS_FAILED) return WBEM_E_FAILED;
+    if (!table->num_rows) return S_OK;
 
-    len = min( view->table->num_rows, 16 );
+    len = min( table->num_rows, 16 );
     if (!(view->result = heap_alloc( len * sizeof(UINT) ))) return E_OUTOFMEMORY;
 
-    for (i = 0; i < view->table->num_rows; i++)
+    for (i = 0; i < table->num_rows; i++)
     {
         HRESULT hr;
         LONGLONG val = 0;
@@ -430,13 +727,31 @@ HRESULT execute_view( struct view *view )
             if (!(tmp = heap_realloc( view->result, len * sizeof(UINT) ))) return E_OUTOFMEMORY;
             view->result = tmp;
         }
-        if ((hr = eval_cond( view->table, i, view->cond, &val, &type )) != S_OK) return hr;
+        if (status == FILL_STATUS_FILTERED) val = 1;
+        else if ((hr = eval_cond( table, i, view->cond, &val, &type )) != S_OK) return hr;
         if (val) view->result[j++] = i;
     }
-    view->count = j;
+
+    view->result_count = j;
     return S_OK;
 }
 
+HRESULT execute_view( struct view *view )
+{
+    switch (view->type)
+    {
+    case VIEW_TYPE_ASSOCIATORS:
+        return exec_assoc_view( view );
+
+    case VIEW_TYPE_SELECT:
+        return exec_select_view( view );
+
+    default:
+        ERR( "unhandled type %u\n", view->type );
+        return E_INVALIDARG;
+    }
+}
+
 struct query *create_query(void)
 {
     struct query *query;
@@ -486,14 +801,13 @@ done:
     return hr;
 }
 
-BOOL is_selected_prop( const struct view *view, const WCHAR *name )
+BOOL is_result_prop( const struct view *view, const WCHAR *name )
 {
     const struct property *prop = view->proplist;
-
     if (!prop) return TRUE;
     while (prop)
     {
-        if (!strcmpiW( prop->name, name )) return TRUE;
+        if (!wcsicmp( prop->name, name )) return TRUE;
         prop = prop->next;
     }
     return FALSE;
@@ -504,61 +818,34 @@ static BOOL is_system_prop( const WCHAR *name )
     return (name[0] == '_' && name[1] == '_');
 }
 
-static BSTR build_servername( const struct view *view )
-{
-    WCHAR server[MAX_COMPUTERNAME_LENGTH + 1], *p;
-    DWORD len = ARRAY_SIZE( server );
-
-    if (view->proplist) return NULL;
-
-    if (!(GetComputerNameW( server, &len ))) return NULL;
-    for (p = server; *p; p++) *p = toupperW( *p );
-    return SysAllocString( server );
-}
-
-static BSTR build_classname( const struct view *view )
-{
-    return SysAllocString( view->table->name );
-}
-
-static BSTR build_namespace( const struct view *view )
-{
-    static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0};
-
-    if (view->proplist) return NULL;
-    return SysAllocString( cimv2W );
-}
-
-static BSTR build_proplist( const struct view *view, UINT index, UINT count, UINT *len )
+static BSTR build_proplist( const struct table *table, UINT row, UINT count, UINT *len )
 {
     static const WCHAR fmtW[] = {'%','s','=','%','s',0};
-    UINT i, j, offset, row = view->result[index];
+    UINT i, j, offset;
     BSTR *values, ret = NULL;
 
     if (!(values = heap_alloc( count * sizeof(BSTR) ))) return NULL;
 
     *len = j = 0;
-    for (i = 0; i < view->table->num_cols; i++)
+    for (i = 0; i < table->num_cols; i++)
     {
-        if (view->table->columns[i].type & COL_FLAG_KEY)
+        if (table->columns[i].type & COL_FLAG_KEY)
         {
-            const WCHAR *name = view->table->columns[i].name;
-
-            values[j] = get_value_bstr( view->table, row, i );
-            *len += strlenW( fmtW ) + strlenW( name ) + strlenW( values[j] );
+            const WCHAR *name = table->columns[i].name;
+            values[j] = get_value_bstr( table, row, i );
+            *len += lstrlenW( fmtW ) + lstrlenW( name ) + lstrlenW( values[j] );
             j++;
         }
     }
     if ((ret = SysAllocStringLen( NULL, *len )))
     {
         offset = j = 0;
-        for (i = 0; i < view->table->num_cols; i++)
+        for (i = 0; i < table->num_cols; i++)
         {
-            if (view->table->columns[i].type & COL_FLAG_KEY)
+            if (table->columns[i].type & COL_FLAG_KEY)
             {
-                const WCHAR *name = view->table->columns[i].name;
-
-                offset += sprintfW( ret + offset, fmtW, name, values[j] );
+                const WCHAR *name = table->columns[i].name;
+                offset += swprintf( ret + offset, fmtW, name, values[j] );
                 if (j < count - 1) ret[offset++] = ',';
                 j++;
             }
@@ -569,32 +856,34 @@ static BSTR build_proplist( const struct view *view, UINT index, UINT count, UIN
     return ret;
 }
 
-static UINT count_key_columns( const struct view *view )
+static UINT count_key_columns( const struct table *table )
 {
     UINT i, num_keys = 0;
 
-    for (i = 0; i < view->table->num_cols; i++)
+    for (i = 0; i < table->num_cols; i++)
     {
-        if (view->table->columns[i].type & COL_FLAG_KEY) num_keys++;
+        if (table->columns[i].type & COL_FLAG_KEY) num_keys++;
     }
     return num_keys;
 }
 
-static BSTR build_relpath( const struct view *view, UINT index, const WCHAR *name )
+static BSTR build_relpath( const struct view *view, UINT table_index, UINT result_index, const WCHAR *name )
 {
     static const WCHAR fmtW[] = {'%','s','.','%','s',0};
     BSTR class, proplist, ret = NULL;
+    struct table *table = view->table[table_index];
+    UINT row = view->result[result_index];
     UINT num_keys, len;
 
     if (view->proplist) return NULL;
 
-    if (!(class = build_classname( view ))) return NULL;
-    if (!(num_keys = count_key_columns( view ))) return class;
-    if (!(proplist = build_proplist( view, index, num_keys, &len ))) goto done;
+    if (!(class = SysAllocString( view->table[table_index]->name ))) return NULL;
+    if (!(num_keys = count_key_columns( table ))) return class;
+    if (!(proplist = build_proplist( table, row, num_keys, &len ))) goto done;
 
-    len += strlenW( fmtW ) + SysStringLen( class );
+    len += lstrlenW( fmtW ) + SysStringLen( class );
     if (!(ret = SysAllocStringLen( NULL, len ))) goto done;
-    sprintfW( ret, fmtW, class, proplist );
+    swprintf( ret, fmtW, class, proplist );
 
 done:
     SysFreeString( class );
@@ -602,7 +891,7 @@ done:
     return ret;
 }
 
-static BSTR build_path( const struct view *view, UINT index, const WCHAR *name )
+static BSTR build_path( const struct view *view, UINT table_index, UINT result_index, const WCHAR *name )
 {
     static const WCHAR fmtW[] = {'\\','\\','%','s','\\','%','s',':','%','s',0};
     BSTR server, namespace = NULL, relpath = NULL, ret = NULL;
@@ -610,13 +899,13 @@ static BSTR build_path( const struct view *view, UINT index, const WCHAR *name )
 
     if (view->proplist) return NULL;
 
-    if (!(server = build_servername( view ))) return NULL;
-    if (!(namespace = build_namespace( view ))) goto done;
-    if (!(relpath = build_relpath( view, index, name ))) goto done;
+    if (!(server = build_servername())) return NULL;
+    if (!(namespace = build_namespace())) goto done;
+    if (!(relpath = build_relpath( view, table_index, result_index, name ))) goto done;
 
-    len = strlenW( fmtW ) + SysStringLen( server ) + SysStringLen( namespace ) + SysStringLen( relpath );
+    len = lstrlenW( fmtW ) + SysStringLen( server ) + SysStringLen( namespace ) + SysStringLen( relpath );
     if (!(ret = SysAllocStringLen( NULL, len ))) goto done;
-    sprintfW( ret, fmtW, server, namespace, relpath );
+    swprintf( ret, fmtW, server, namespace, relpath );
 
 done:
     SysFreeString( server );
@@ -630,30 +919,30 @@ BOOL is_method( const struct table *table, UINT column )
     return table->columns[column].type & COL_FLAG_METHOD;
 }
 
-static UINT count_properties( const struct view *view )
+static UINT count_properties( const struct table *table )
 {
     UINT i, num_props = 0;
 
-    for (i = 0; i < view->table->num_cols; i++)
+    for (i = 0; i < table->num_cols; i++)
     {
-        if (!is_method( view->table, i)) num_props++;
+        if (!is_method( table, i )) num_props++;
     }
     return num_props;
 }
 
-static UINT count_selected_properties( const struct view *view )
+static UINT count_result_properties( const struct view *view, UINT table_index )
 {
     const struct property *prop = view->proplist;
     UINT count;
 
-    if (!prop) return count_properties( view );
+    if (!prop) return count_properties( view->table[table_index] );
 
     count = 1;
     while ((prop = prop->next)) count++;
     return count;
 }
 
-static HRESULT get_system_propval( const struct view *view, UINT index, const WCHAR *name,
+static HRESULT get_system_propval( const struct view *view, UINT table_index, UINT result_index, const WCHAR *name,
                                    VARIANT *ret, CIMTYPE *type, LONG *flavor )
 {
     static const WCHAR classW[] = {'_','_','C','L','A','S','S',0};
@@ -666,17 +955,17 @@ static HRESULT get_system_propval( const struct view *view, UINT index, const WC
 
     if (flavor) *flavor = WBEM_FLAVOR_ORIGIN_SYSTEM;
 
-    if (!strcmpiW( name, classW ))
+    if (!wcsicmp( name, classW ))
     {
         if (ret)
         {
             V_VT( ret ) = VT_BSTR;
-            V_BSTR( ret ) = build_classname( view );
+            V_BSTR( ret ) = SysAllocString( view->table[table_index]->name );
         }
         if (type) *type = CIM_STRING;
         return S_OK;
     }
-    if (!strcmpiW( name, genusW ))
+    if (!wcsicmp( name, genusW ))
     {
         if (ret)
         {
@@ -686,52 +975,52 @@ static HRESULT get_system_propval( const struct view *view, UINT index, const WC
         if (type) *type = CIM_SINT32;
         return S_OK;
     }
-    else if (!strcmpiW( name, namespaceW ))
+    else if (!wcsicmp( name, namespaceW ))
     {
         if (ret)
         {
             V_VT( ret ) = VT_BSTR;
-            V_BSTR( ret ) = build_namespace( view );
+            V_BSTR( ret ) = view->proplist ? NULL : build_namespace();
         }
         if (type) *type = CIM_STRING;
         return S_OK;
     }
-    else if (!strcmpiW( name, pathW ))
+    else if (!wcsicmp( name, pathW ))
     {
         if (ret)
         {
             V_VT( ret ) = VT_BSTR;
-            V_BSTR( ret ) = build_path( view, index, name );
+            V_BSTR( ret ) = build_path( view, table_index, result_index, name );
         }
         if (type) *type = CIM_STRING;
         return S_OK;
     }
-    if (!strcmpiW( name, propcountW ))
+    if (!wcsicmp( name, propcountW ))
     {
         if (ret)
         {
             V_VT( ret ) = VT_I4;
-            V_I4( ret ) = count_selected_properties( view );
+            V_I4( ret ) = count_result_properties( view, table_index );
         }
         if (type) *type = CIM_SINT32;
         return S_OK;
     }
-    else if (!strcmpiW( name, relpathW ))
+    else if (!wcsicmp( name, relpathW ))
     {
         if (ret)
         {
             V_VT( ret ) = VT_BSTR;
-            V_BSTR( ret ) = build_relpath( view, index, name );
+            V_BSTR( ret ) = build_relpath( view, table_index, result_index, name );
         }
         if (type) *type = CIM_STRING;
         return S_OK;
     }
-    else if (!strcmpiW( name, serverW ))
+    else if (!wcsicmp( name, serverW ))
     {
         if (ret)
         {
             V_VT( ret ) = VT_BSTR;
-            V_BSTR( ret ) = build_servername( view );
+            V_BSTR( ret ) = view->proplist ? NULL : build_servername();
         }
         if (type) *type = CIM_STRING;
         return S_OK;
@@ -744,17 +1033,25 @@ VARTYPE to_vartype( CIMTYPE type )
 {
     switch (type)
     {
-    case CIM_BOOLEAN:  return VT_BOOL;
+    case CIM_BOOLEAN:   return VT_BOOL;
+
     case CIM_STRING:
-    case CIM_DATETIME: return VT_BSTR;
-    case CIM_SINT8:    return VT_I1;
-    case CIM_UINT8:    return VT_UI1;
-    case CIM_SINT16:   return VT_I2;
-    case CIM_UINT16:   return VT_UI2;
-    case CIM_SINT32:   return VT_I4;
-    case CIM_UINT32:   return VT_UI4;
-    case CIM_SINT64:   return VT_I8;
-    case CIM_UINT64:   return VT_UI8;
+    case CIM_REFERENCE:
+    case CIM_DATETIME:  return VT_BSTR;
+
+    case CIM_SINT8:     return VT_I1;
+    case CIM_UINT8:     return VT_UI1;
+    case CIM_SINT16:    return VT_I2;
+
+    case CIM_UINT16:
+    case CIM_SINT32:
+    case CIM_UINT32:    return VT_I4;
+
+    case CIM_SINT64:    return VT_I8;
+    case CIM_UINT64:    return VT_UI8;
+
+    case CIM_REAL32:    return VT_R4;
+
     default:
         ERR("unhandled type %u\n", type);
         break;
@@ -762,18 +1059,17 @@ VARTYPE to_vartype( CIMTYPE type )
     return 0;
 }
 
-SAFEARRAY *to_safearray( const struct array *array, CIMTYPE type )
+SAFEARRAY *to_safearray( const struct array *array, CIMTYPE basetype )
 {
     SAFEARRAY *ret;
-    UINT size = get_type_size( type );
-    VARTYPE vartype = to_vartype( type );
+    VARTYPE vartype = to_vartype( basetype );
     LONG i;
 
     if (!array || !(ret = SafeArrayCreateVector( vartype, 0, array->count ))) return NULL;
 
     for (i = 0; i < array->count; i++)
     {
-        void *ptr = (char *)array->ptr + i * size;
+        void *ptr = (char *)array->ptr + i * array->elem_size;
         if (vartype == VT_BSTR)
         {
             BSTR str = SysAllocString( *(const WCHAR **)ptr );
@@ -830,6 +1126,9 @@ void set_variant( VARTYPE type, LONGLONG val, void *val_ptr, VARIANT *ret )
         break;
     case VT_NULL:
         break;
+    case VT_R4:
+        V_R4( ret ) = *(FLOAT *)&val;
+        break;
     default:
         ERR("unhandled variant type %u\n", type);
         return;
@@ -837,48 +1136,88 @@ void set_variant( VARTYPE type, LONGLONG val, void *val_ptr, VARIANT *ret )
     V_VT( ret ) = type;
 }
 
-HRESULT get_propval( const struct view *view, UINT index, const WCHAR *name, VARIANT *ret,
-                     CIMTYPE *type, LONG *flavor )
+static HRESULT map_view_index( const struct view *view, UINT index, UINT *table_index, UINT *result_index )
+{
+    if (!view->table) return WBEM_E_NOT_FOUND;
+
+    switch (view->type)
+    {
+    case VIEW_TYPE_SELECT:
+        *table_index = 0;
+        *result_index = index;
+        break;
+
+    case VIEW_TYPE_ASSOCIATORS:
+        *table_index = *result_index = index;
+        break;
+
+    default:
+        ERR( "unhandled view type %u\n", view->type );
+        return WBEM_E_FAILED;
+    }
+    return S_OK;
+}
+
+struct table *get_view_table( const struct view *view, UINT index )
+{
+    switch (view->type)
+    {
+    case VIEW_TYPE_SELECT:
+        return view->table[0];
+
+    case VIEW_TYPE_ASSOCIATORS:
+        return view->table[index];
+
+    default:
+        ERR( "unhandled view type %u\n", view->type );
+        return NULL;
+    }
+}
+
+HRESULT get_propval( const struct view *view, UINT index, const WCHAR *name, VARIANT *ret, CIMTYPE *type,
+                     LONG *flavor )
 {
     HRESULT hr;
-    UINT column, row;
+    UINT column, row, table_index, result_index;
+    struct table *table;
     VARTYPE vartype;
     void *val_ptr = NULL;
     LONGLONG val;
 
-    if (is_system_prop( name )) return get_system_propval( view, index, name, ret, type, flavor );
-    if (!view->count || !is_selected_prop( view, name )) return WBEM_E_NOT_FOUND;
+    if ((hr = map_view_index( view, index, &table_index, &result_index )) != S_OK) return hr;
 
-    hr = get_column_index( view->table, name, &column );
-    if (hr != S_OK || is_method( view->table, column )) return WBEM_E_NOT_FOUND;
+    if (is_system_prop( name )) return get_system_propval( view, table_index, result_index, name, ret, type, flavor );
+    if (!view->result_count || !is_result_prop( view, name )) return WBEM_E_NOT_FOUND;
 
-    row = view->result[index];
-    hr = get_value( view->table, row, column, &val );
+    table = view->table[table_index];
+    hr = get_column_index( table, name, &column );
+    if (hr != S_OK || is_method( table, column )) return WBEM_E_NOT_FOUND;
+
+    row = view->result[result_index];
+    hr = get_value( table, row, column, &val );
     if (hr != S_OK) return hr;
 
-    if (type) *type = view->table->columns[column].type & COL_TYPE_MASK;
+    if (type) *type = table->columns[column].type & COL_TYPE_MASK;
     if (flavor) *flavor = 0;
 
     if (!ret) return S_OK;
 
-    vartype = view->table->columns[column].vartype;
-    if (view->table->columns[column].type & CIM_FLAG_ARRAY)
+    vartype = to_vartype( table->columns[column].type & CIM_TYPE_MASK );
+    if (table->columns[column].type & CIM_FLAG_ARRAY)
     {
-        CIMTYPE basetype = view->table->columns[column].type & CIM_TYPE_MASK;
+        CIMTYPE basetype = table->columns[column].type & CIM_TYPE_MASK;
 
         val_ptr = to_safearray( (const struct array *)(INT_PTR)val, basetype );
         if (!val_ptr) vartype = VT_NULL;
-        else if (!vartype) vartype = to_vartype( basetype ) | VT_ARRAY;
+        else vartype |= VT_ARRAY;
         set_variant( vartype, val, val_ptr, ret );
         return S_OK;
     }
 
-    switch (view->table->columns[column].type & COL_TYPE_MASK)
+    switch (table->columns[column].type & COL_TYPE_MASK)
     {
-    case CIM_BOOLEAN:
-        if (!vartype) vartype = VT_BOOL;
-        break;
     case CIM_STRING:
+    case CIM_REFERENCE:
     case CIM_DATETIME:
         if (val)
         {
@@ -888,34 +1227,25 @@ HRESULT get_propval( const struct view *view, UINT index, const WCHAR *name, VAR
         else
             vartype = VT_NULL;
         break;
-    case CIM_SINT8:
-        if (!vartype) vartype = VT_I1;
+    case CIM_SINT64:
+        vartype = VT_BSTR;
+        val_ptr = get_value_bstr( table, row, column );
         break;
-    case CIM_UINT8:
-        if (!vartype) vartype = VT_UI1;
+    case CIM_UINT64:
+        vartype = VT_BSTR;
+        val_ptr = get_value_bstr( table, row, column );
         break;
+    case CIM_BOOLEAN:
+    case CIM_SINT8:
+    case CIM_UINT8:
     case CIM_SINT16:
-        if (!vartype) vartype = VT_I2;
-        break;
     case CIM_UINT16:
-        if (!vartype) vartype = VT_UI2;
-        break;
     case CIM_SINT32:
-        if (!vartype) vartype = VT_I4;
-        break;
     case CIM_UINT32:
-        if (!vartype) vartype = VT_UI4;
-        break;
-    case CIM_SINT64:
-        vartype = VT_BSTR;
-        val_ptr = get_value_bstr( view->table, row, column );
-        break;
-    case CIM_UINT64:
-        vartype = VT_BSTR;
-        val_ptr = get_value_bstr( view->table, row, column );
+    case CIM_REAL32:
         break;
     default:
-        ERR("unhandled column type %u\n", view->table->columns[column].type);
+        ERR("unhandled column type %u\n", table->columns[column].type);
         return WBEM_E_FAILED;
     }
 
@@ -950,23 +1280,22 @@ static struct array *to_array( VARIANT *var, CIMTYPE *type )
     LONG bound, i;
     VARTYPE vartype;
     CIMTYPE basetype;
-    UINT size;
 
     if (SafeArrayGetVartype( V_ARRAY( var ), &vartype ) != S_OK) return NULL;
     if (!(basetype = to_cimtype( vartype ))) return NULL;
     if (SafeArrayGetUBound( V_ARRAY( var ), 1, &bound ) != S_OK) return NULL;
     if (!(ret = heap_alloc( sizeof(struct array) ))) return NULL;
 
-    ret->count = bound + 1;
-    size = get_type_size( basetype );
-    if (!(ret->ptr = heap_alloc_zero( ret->count * size )))
+    ret->count     = bound + 1;
+    ret->elem_size = get_type_size( basetype );
+    if (!(ret->ptr = heap_alloc_zero( ret->count * ret->elem_size )))
     {
         heap_free( ret );
         return NULL;
     }
     for (i = 0; i < ret->count; i++)
     {
-        void *ptr = (char *)ret->ptr + i * size;
+        void *ptr = (char *)ret->ptr + i * ret->elem_size;
         if (vartype == VT_BSTR)
         {
             BSTR str;
@@ -1046,45 +1375,56 @@ HRESULT to_longlong( VARIANT *var, LONGLONG *val, CIMTYPE *type )
 HRESULT put_propval( const struct view *view, UINT index, const WCHAR *name, VARIANT *var, CIMTYPE type )
 {
     HRESULT hr;
-    UINT column, row = view->result[index];
+    UINT row, column, table_index, result_index;
+    struct table *table;
     LONGLONG val;
 
-    hr = get_column_index( view->table, name, &column );
+    if ((hr = map_view_index( view, index, &table_index, &result_index )) != S_OK) return hr;
+
+    table = view->table[table_index];
+    hr = get_column_index( table, name, &column );
     if (hr != S_OK)
     {
         FIXME("no support for creating new properties\n");
         return WBEM_E_FAILED;
     }
-    if (is_method( view->table, column ) || !(view->table->columns[column].type & COL_FLAG_DYNAMIC))
+    if (is_method( table, column ) || !(table->columns[column].type & COL_FLAG_DYNAMIC))
         return WBEM_E_FAILED;
 
     hr = to_longlong( var, &val, &type );
     if (hr != S_OK) return hr;
 
-    return set_value( view->table, row, column, val, type );
+    row = view->result[result_index];
+    return set_value( table, row, column, val, type );
 }
 
-HRESULT get_properties( const struct view *view, LONG flags, SAFEARRAY **props )
+HRESULT get_properties( const struct view *view, UINT index, LONG flags, SAFEARRAY **props )
 {
     SAFEARRAY *sa;
     BSTR str;
-    UINT i, num_props = count_selected_properties( view );
+    UINT i, table_index, result_index, num_props;
+    struct table *table;
+    HRESULT hr;
     LONG j;
 
+    if ((hr = map_view_index( view, index, &table_index, &result_index )) != S_OK) return hr;
+
+    num_props = count_result_properties( view, table_index );
     if (!(sa = SafeArrayCreateVector( VT_BSTR, 0, num_props ))) return E_OUTOFMEMORY;
 
-    for (i = 0, j = 0; i < view->table->num_cols; i++)
+    table = view->table[table_index];
+    for (i = 0, j = 0; i < table->num_cols; i++)
     {
         BOOL is_system;
 
-        if (is_method( view->table, i )) continue;
-        if (!is_selected_prop( view, view->table->columns[i].name )) continue;
+        if (is_method( table, i )) continue;
+        if (!is_result_prop( view, table->columns[i].name )) continue;
 
-        is_system = is_system_prop( view->table->columns[i].name );
+        is_system = is_system_prop( table->columns[i].name );
         if ((flags & WBEM_FLAG_NONSYSTEM_ONLY) && is_system) continue;
         else if ((flags & WBEM_FLAG_SYSTEM_ONLY) && !is_system) continue;
 
-        str = SysAllocString( view->table->columns[i].name );
+        str = SysAllocString( table->columns[i].name );
         if (!str || SafeArrayPutElement( sa, &j, str ) != S_OK)
         {
             SysFreeString( str );
index c45cbbe..1cbad2d 100644 (file)
@@ -20,7 +20,6 @@
 
 #define COBJMACROS
 
-#include "config.h"
 #include <stdarg.h>
 
 #include "windef.h"
index d3057e0..3ad7321 100644 (file)
@@ -20,7 +20,6 @@
 
 #define COBJMACROS
 
-#include "config.h"
 #include <stdarg.h>
 
 #include "windef.h"
index b096c5c..53010bc 100644 (file)
@@ -20,7 +20,6 @@
 
 #define COBJMACROS
 
-#include "config.h"
 #include <stdarg.h>
 
 #include "windef.h"
index 599a421..b0840fb 100644 (file)
 
 #define COBJMACROS
 
-#include "config.h"
 #include <stdarg.h>
+#ifdef __REACTOS__
+#include <wchar.h>
+#endif
 
 #include "windef.h"
 #include "winbase.h"
@@ -27,7 +29,6 @@
 #include "wbemcli.h"
 
 #include "wine/debug.h"
-#include "wine/unicode.h"
 #include "wbemprox_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
@@ -279,7 +280,7 @@ static HRESULT WINAPI wbem_services_OpenNamespace(
     TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strNamespace), lFlags,
           pCtx, ppWorkingNamespace, ppResult);
 
-    if ((strcmpiW( strNamespace, cimv2W ) && strcmpiW( strNamespace, defaultW )) || ws->namespace)
+    if ((wcsicmp( strNamespace, cimv2W ) && wcsicmp( strNamespace, defaultW )) || ws->namespace)
         return WBEM_E_INVALID_NAMESPACE;
 
     return WbemServices_create( cimv2W, (void **)ppWorkingNamespace );
@@ -322,15 +323,7 @@ static HRESULT WINAPI wbem_services_QueryObjectSink(
     return WBEM_E_FAILED;
 }
 
-struct path
-{
-    WCHAR *class;
-    UINT   class_len;
-    WCHAR *filter;
-    UINT   filter_len;
-};
-
-static HRESULT parse_path( const WCHAR *str, struct path **ret )
+HRESULT parse_path( const WCHAR *str, struct path **ret )
 {
     struct path *path;
     const WCHAR *p = str, *q;
@@ -340,31 +333,47 @@ static HRESULT parse_path( const WCHAR *str, struct path **ret )
 
     if (*p == '\\')
     {
-        static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2'};
-
+        static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0};
         WCHAR server[MAX_COMPUTERNAME_LENGTH+1];
         DWORD server_len = ARRAY_SIZE(server);
 
         p++;
-        if (*p != '\\') return WBEM_E_INVALID_OBJECT_PATH;
+        if (*p != '\\')
+        {
+            heap_free( path );
+            return WBEM_E_INVALID_OBJECT_PATH;
+        }
         p++;
 
         q = p;
         while (*p && *p != '\\') p++;
-        if (!*p) return WBEM_E_INVALID_OBJECT_PATH;
+        if (!*p)
+        {
+            heap_free( path );
+            return WBEM_E_INVALID_OBJECT_PATH;
+        }
 
         len = p - q;
-        if (!GetComputerNameW( server, &server_len ) || server_len != len
-                || memcmp( q, server, server_len * sizeof(WCHAR) ))
+        if (!GetComputerNameW( server, &server_len ) || server_len != len || _wcsnicmp( q, server, server_len ))
+        {
+            heap_free( path );
             return WBEM_E_NOT_SUPPORTED;
+        }
 
         q = ++p;
         while (*p && *p != ':') p++;
-        if (!*p) return WBEM_E_INVALID_OBJECT_PATH;
+        if (!*p)
+        {
+            heap_free( path );
+            return WBEM_E_INVALID_OBJECT_PATH;
+        }
 
         len = p - q;
-        if (len != ARRAY_SIZE(cimv2W) || memcmp( q, cimv2W, sizeof(cimv2W) ))
+        if (len != ARRAY_SIZE(cimv2W) - 1 || _wcsnicmp( q, cimv2W, ARRAY_SIZE(cimv2W) - 1 ))
+        {
+            heap_free( path );
             return WBEM_E_INVALID_NAMESPACE;
+        }
         p++;
     }
 
@@ -401,14 +410,15 @@ static HRESULT parse_path( const WCHAR *str, struct path **ret )
     return S_OK;
 }
 
-static void free_path( struct path *path )
+void free_path( struct path *path )
 {
+    if (!path) return;
     heap_free( path->class );
     heap_free( path->filter );
     heap_free( path );
 }
 
-static WCHAR *query_from_path( const struct path *path )
+WCHAR *query_from_path( const struct path *path )
 {
     static const WCHAR selectW[] =
         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','%','s',' ',
@@ -422,14 +432,14 @@ static WCHAR *query_from_path( const struct path *path )
     {
         len = path->class_len + path->filter_len + ARRAY_SIZE(selectW);
         if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
-        sprintfW( query, selectW, path->class, path->filter );
+        swprintf( query, selectW, path->class, path->filter );
     }
     else
     {
         len = path->class_len + ARRAY_SIZE(select_allW);
         if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
-        strcpyW( query, select_allW );
-        strcatW( query, path->class );
+        lstrcpyW( query, select_allW );
+        lstrcatW( query, path->class );
     }
     return query;
 }
@@ -653,7 +663,7 @@ static HRESULT WINAPI wbem_services_ExecQuery(
           debugstr_w(strQuery), lFlags, pCtx, ppEnum);
 
     if (!strQueryLanguage || !strQuery || !strQuery[0]) return WBEM_E_INVALID_PARAMETER;
-    if (strcmpiW( strQueryLanguage, wqlW )) return WBEM_E_INVALID_QUERY_TYPE;
+    if (wcsicmp( strQueryLanguage, wqlW )) return WBEM_E_INVALID_QUERY_TYPE;
     return exec_query( strQuery, ppEnum );
 }
 
@@ -823,6 +833,7 @@ static HRESULT WINAPI wbem_services_ExecMethod(
     struct path *path;
     WCHAR *str;
     class_method *func;
+    struct table *table;
     HRESULT hr;
 
     TRACE("%p, %s, %s, %08x, %p, %p, %p, %p\n", iface, debugstr_w(strObjectPath),
@@ -850,10 +861,11 @@ static HRESULT WINAPI wbem_services_ExecMethod(
     hr = EnumWbemClassObject_create( query, (void **)&result );
     if (hr != S_OK) goto done;
 
-    hr = create_class_object( query->view->table->name, result, 0, NULL, &obj );
+    table = get_view_table( query->view, 0 );
+    hr = create_class_object( table->name, result, 0, NULL, &obj );
     if (hr != S_OK) goto done;
 
-    hr = get_method( query->view->table, strMethodName, &func );
+    hr = get_method( table, strMethodName, &func );
     if (hr != S_OK) goto done;
 
     hr = func( obj, pInParams, ppOutParams );
index ad56e0c..8e08d95 100644 (file)
 
 #define COBJMACROS
 
-#include "config.h"
 #include <stdarg.h>
+#ifdef __REACTOS__
+#include <wchar.h>
+#endif
 
 #include "windef.h"
 #include "winbase.h"
@@ -35,7 +37,7 @@ HRESULT get_column_index( const struct table *table, const WCHAR *name, UINT *co
     UINT i;
     for (i = 0; i < table->num_cols; i++)
     {
-        if (!strcmpiW( table->columns[i].name, name ))
+        if (!wcsicmp( table->columns[i].name, name ))
         {
             *column = i;
             return S_OK;
@@ -65,8 +67,11 @@ UINT get_type_size( CIMTYPE type )
     case CIM_UINT64:
         return sizeof(INT64);
     case CIM_DATETIME:
+    case CIM_REFERENCE:
     case CIM_STRING:
         return sizeof(WCHAR *);
+    case CIM_REAL32:
+        return sizeof(FLOAT);
     default:
         ERR("unhandled type %u\n", type);
         break;
@@ -111,6 +116,7 @@ HRESULT get_value( const struct table *table, UINT row, UINT column, LONGLONG *v
         *val = *(const int *)ptr;
         break;
     case CIM_DATETIME:
+    case CIM_REFERENCE:
     case CIM_STRING:
         *val = (INT_PTR)*(const WCHAR **)ptr;
         break;
@@ -138,6 +144,9 @@ HRESULT get_value( const struct table *table, UINT row, UINT column, LONGLONG *v
     case CIM_UINT64:
         *val = *(const UINT64 *)ptr;
         break;
+    case CIM_REAL32:
+        memcpy( val, ptr, sizeof(FLOAT) );
+        break;
     default:
         ERR("invalid column type %u\n", table->columns[column].type & COL_TYPE_MASK);
         *val = 0;
@@ -174,21 +183,22 @@ BSTR get_value_bstr( const struct table *table, UINT row, UINT column )
         else return SysAllocString( falseW );
 
     case CIM_DATETIME:
+    case CIM_REFERENCE:
     case CIM_STRING:
         if (!val) return NULL;
-        len = strlenW( (const WCHAR *)(INT_PTR)val ) + 2;
+        len = lstrlenW( (const WCHAR *)(INT_PTR)val ) + 2;
         if (!(ret = SysAllocStringLen( NULL, len ))) return NULL;
-        sprintfW( ret, fmt_strW, (const WCHAR *)(INT_PTR)val );
+        swprintf( ret, fmt_strW, (const WCHAR *)(INT_PTR)val );
         return ret;
 
     case CIM_SINT16:
     case CIM_SINT32:
-        sprintfW( number, fmt_signedW, val );
+        swprintf( number, fmt_signedW, val );
         return SysAllocString( number );
 
     case CIM_UINT16:
     case CIM_UINT32:
-        sprintfW( number, fmt_unsignedW, val );
+        swprintf( number, fmt_unsignedW, val );
         return SysAllocString( number );
 
     case CIM_SINT64:
@@ -221,6 +231,7 @@ HRESULT set_value( const struct table *table, UINT row, UINT column, LONGLONG va
     switch (table->columns[column].type & COL_TYPE_MASK)
     {
     case CIM_DATETIME:
+    case CIM_REFERENCE:
     case CIM_STRING:
         *(WCHAR **)ptr = (WCHAR *)(INT_PTR)val;
         break;
@@ -263,7 +274,7 @@ HRESULT get_method( const struct table *table, const WCHAR *name, class_method *
     {
         for (j = 0; j < table->num_cols; j++)
         {
-            if (table->columns[j].type & COL_FLAG_METHOD && !strcmpW( table->columns[j].name, name ))
+            if (table->columns[j].type & COL_FLAG_METHOD && !wcscmp( table->columns[j].name, name ))
             {
                 HRESULT hr;
                 LONGLONG val;
@@ -288,7 +299,7 @@ void free_row_values( const struct table *table, UINT row )
         if (!(table->columns[i].type & COL_FLAG_DYNAMIC)) continue;
 
         type = table->columns[i].type & COL_TYPE_MASK;
-        if (type == CIM_STRING || type == CIM_DATETIME)
+        if (type == CIM_STRING || type == CIM_DATETIME || type == CIM_REFERENCE)
         {
             if (get_value( table, row, i, &val ) == S_OK) heap_free( (void *)(INT_PTR)val );
         }
@@ -357,7 +368,7 @@ struct table *grab_table( const WCHAR *name )
 
     LIST_FOR_EACH_ENTRY( table, table_list, struct table, entry )
     {
-        if (!strcmpiW( table->name, name ))
+        if (name && !wcsicmp( table->name, name ))
         {
             TRACE("returning %p\n", table);
             return addref_table( table );
@@ -392,7 +403,7 @@ BOOL add_table( struct table *table )
 
     LIST_FOR_EACH_ENTRY( iter, table_list, struct table, entry )
     {
-        if (!strcmpiW( iter->name, table->name ))
+        if (!wcsicmp( iter->name, table->name ))
         {
             TRACE("table %s already exists\n", debugstr_w(table->name));
             return FALSE;
index fe26a87..7bd49c8 100644 (file)
@@ -18,7 +18,6 @@
 
 #define COBJMACROS
 
-#include "config.h"
 #include <stdarg.h>
 
 #include "windef.h"
@@ -27,7 +26,6 @@
 #include "wbemcli.h"
 
 #include "wine/debug.h"
-#include "wine/unicode.h"
 #include "wbemprox_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
@@ -93,16 +91,16 @@ static BOOL is_local_machine( const WCHAR *server )
     WCHAR buffer[MAX_COMPUTERNAME_LENGTH + 1];
     DWORD len = ARRAY_SIZE( buffer );
 
-    if (!server || !strcmpW( server, dotW ) || !strcmpiW( server, localhostW )) return TRUE;
-    if (GetComputerNameW( buffer, &len ) && !strcmpiW( server, buffer )) return TRUE;
+    if (!server || !wcscmp( server, dotW ) || !wcsicmp( server, localhostW )) return TRUE;
+    if (GetComputerNameW( buffer, &len ) && !wcsicmp( server, buffer )) return TRUE;
     return FALSE;
 }
 
 static HRESULT parse_resource( const WCHAR *resource, WCHAR **server, WCHAR **namespace )
 {
     static const WCHAR rootW[] = {'R','O','O','T'};
-    static const WCHAR cimv2W[] = {'C','I','M','V','2'};
-    static const WCHAR defaultW[] = {'D','E','F','A','U','L','T'};
+    static const WCHAR cimv2W[] = {'C','I','M','V','2',0};
+    static const WCHAR defaultW[] = {'D','E','F','A','U','L','T',0};
     HRESULT hr = WBEM_E_INVALID_NAMESPACE;
     const WCHAR *p, *q;
     unsigned int len;
@@ -133,16 +131,15 @@ static HRESULT parse_resource( const WCHAR *resource, WCHAR **server, WCHAR **na
     p = q;
     while (*q && *q != '\\' && *q != '/') q++;
     len = q - p;
-    if (len >= ARRAY_SIZE( rootW ) && memicmpW( rootW, p, len )) goto done;
+    if (len >= ARRAY_SIZE( rootW ) && _wcsnicmp( rootW, p, len )) goto done;
     if (!*q)
     {
         hr = S_OK;
         goto done;
     }
     q++;
-    len = strlenW( q );
-    if ((len != ARRAY_SIZE( cimv2W ) || memicmpW( q, cimv2W, len )) &&
-        (len != ARRAY_SIZE( defaultW ) || memicmpW( q, defaultW, len )))
+    len = lstrlenW( q );
+    if (wcsicmp( q, cimv2W ) && wcsicmp( q, defaultW ))
         goto done;
     if (!(*namespace = heap_alloc( (len + 1) * sizeof(WCHAR) ))) hr = E_OUTOFMEMORY;
     else
index 596ad21..5c04c45 100644 (file)
@@ -21,7 +21,9 @@
 #include "wine/debug.h"
 #include "wine/heap.h"
 #include "wine/list.h"
-#include "wine/unicode.h"
+#ifdef __REACTOS__
+#include <winnls.h>
+#endif
 
 IClientSecurity client_security DECLSPEC_HIDDEN;
 struct list *table_list DECLSPEC_HIDDEN;
@@ -92,7 +94,6 @@ struct column
 {
     const WCHAR *name;
     UINT type;
-    VARTYPE vartype; /* 0 for default mapping */
 };
 
 enum fill_status
@@ -127,6 +128,7 @@ struct property
 
 struct array
 {
+    UINT elem_size;
     UINT count;
     void *ptr;
 };
@@ -134,7 +136,6 @@ struct array
 struct field
 {
     UINT type;
-    VARTYPE vartype; /* 0 for default mapping */
     union
     {
         LONGLONG ival;
@@ -150,13 +151,30 @@ struct record
     struct table *table;
 };
 
+struct keyword
+{
+    const WCHAR *name;
+    const WCHAR *value;
+    const struct keyword *next;
+};
+
+enum view_type
+{
+    VIEW_TYPE_SELECT,
+    VIEW_TYPE_ASSOCIATORS,
+};
+
 struct view
 {
-    const struct property *proplist;
-    struct table *table;
+    enum view_type type;
+    const WCHAR *path;                      /* ASSOCIATORS OF query */
+    const struct keyword *keywordlist;
+    const struct property *proplist;        /* SELECT query */
     const struct expr *cond;
+    UINT table_count;
+    struct table **table;
+    UINT result_count;
     UINT *result;
-    UINT  count;
 };
 
 struct query
@@ -166,16 +184,29 @@ struct query
     struct list mem;
 };
 
+struct path
+{
+    WCHAR *class;
+    UINT   class_len;
+    WCHAR *filter;
+    UINT   filter_len;
+};
+
+HRESULT parse_path( const WCHAR *, struct path ** ) DECLSPEC_HIDDEN;
+void free_path( struct path * ) DECLSPEC_HIDDEN;
+WCHAR *query_from_path( const struct path * ) DECLSPEC_HIDDEN;
+
 struct query *create_query(void) DECLSPEC_HIDDEN;
 void free_query( struct query * ) DECLSPEC_HIDDEN;
 struct query *addref_query( struct query * ) DECLSPEC_HIDDEN;
 void release_query( struct query *query ) DECLSPEC_HIDDEN;
 HRESULT exec_query( const WCHAR *, IEnumWbemClassObject ** ) DECLSPEC_HIDDEN;
 HRESULT parse_query( const WCHAR *, struct view **, struct list * ) DECLSPEC_HIDDEN;
-HRESULT create_view( const struct property *, const WCHAR *, const struct expr *,
-                     struct view ** ) DECLSPEC_HIDDEN;
+HRESULT create_view( enum view_type, const WCHAR *, const struct keyword *, const WCHAR *, const struct property *,
+                     const struct expr *, struct view ** ) DECLSPEC_HIDDEN;
 void destroy_view( struct view * ) DECLSPEC_HIDDEN;
 HRESULT execute_view( struct view * ) DECLSPEC_HIDDEN;
+struct table *get_view_table( const struct view *, UINT ) DECLSPEC_HIDDEN;
 void init_table_list( void ) DECLSPEC_HIDDEN;
 struct table *grab_table( const WCHAR * ) DECLSPEC_HIDDEN;
 struct table *addref_table( struct table * ) DECLSPEC_HIDDEN;
@@ -195,15 +226,14 @@ BSTR get_value_bstr( const struct table *, UINT, UINT ) DECLSPEC_HIDDEN;
 HRESULT set_value( const struct table *, UINT, UINT, LONGLONG, CIMTYPE ) DECLSPEC_HIDDEN;
 BOOL is_method( const struct table *, UINT ) DECLSPEC_HIDDEN;
 HRESULT get_method( const struct table *, const WCHAR *, class_method ** ) DECLSPEC_HIDDEN;
-HRESULT get_propval( const struct view *, UINT, const WCHAR *, VARIANT *,
-                     CIMTYPE *, LONG * ) DECLSPEC_HIDDEN;
+HRESULT get_propval( const struct view *, UINT, const WCHAR *, VARIANT *, CIMTYPE *, LONG * ) DECLSPEC_HIDDEN;
 HRESULT put_propval( const struct view *, UINT, const WCHAR *, VARIANT *, CIMTYPE ) DECLSPEC_HIDDEN;
 HRESULT to_longlong( VARIANT *, LONGLONG *, CIMTYPE * ) DECLSPEC_HIDDEN;
 SAFEARRAY *to_safearray( const struct array *, CIMTYPE ) DECLSPEC_HIDDEN;
 VARTYPE to_vartype( CIMTYPE ) DECLSPEC_HIDDEN;
 void destroy_array( struct array *, CIMTYPE ) DECLSPEC_HIDDEN;
-BOOL is_selected_prop( const struct view *, const WCHAR * ) DECLSPEC_HIDDEN;
-HRESULT get_properties( const struct view *, LONG, SAFEARRAY ** ) DECLSPEC_HIDDEN;
+BOOL is_result_prop( const struct view *, const WCHAR * ) DECLSPEC_HIDDEN;
+HRESULT get_properties( const struct view *, UINT, LONG, SAFEARRAY ** ) DECLSPEC_HIDDEN;
 HRESULT get_object( const WCHAR *, IWbemClassObject ** ) DECLSPEC_HIDDEN;
 BSTR get_method_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN;
 void set_variant( VARTYPE, LONGLONG, void *, VARIANT * ) DECLSPEC_HIDDEN;
@@ -233,7 +263,17 @@ static inline WCHAR *heap_strdupW( const WCHAR *src )
 {
     WCHAR *dst;
     if (!src) return NULL;
-    if ((dst = heap_alloc( (strlenW( src ) + 1) * sizeof(WCHAR) ))) strcpyW( dst, src );
+    if ((dst = heap_alloc( (lstrlenW( src ) + 1) * sizeof(WCHAR) ))) lstrcpyW( dst, src );
+    return dst;
+}
+
+static inline WCHAR *heap_strdupAW( const char *src )
+{
+    int len;
+    WCHAR *dst;
+    if (!src) return NULL;
+    len = MultiByteToWideChar( CP_ACP, 0, src, -1, NULL, 0 );
+    if ((dst = heap_alloc( len * sizeof(*dst) ))) MultiByteToWideChar( CP_ACP, 0, src, -1, dst, len );
     return dst;
 }
 
index 42e8232..6224955 100644 (file)
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.  */
+/* A Bison parser, made by GNU Bison 3.4.1.  */
 
 /* Bison implementation for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+   Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    define necessary library symbols; they are noted "INFRINGES ON
    USER NAME SPACE" below.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 /* Identify Bison output.  */
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "3.0"
+#define YYBISON_VERSION "3.4.1"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -67,8 +71,8 @@
 #define yynerrs         wql_nerrs
 
 
-/* Copy the first part of user declarations.  */
-#line 1 "wql.y" /* yacc.c:339  */
+/* First part of user prologue.  */
+#line 1 "wql.y"
 
 
 /*
@@ -89,7 +93,6 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "config.h"
 #include <stdarg.h>
 
 #include "windef.h"
 
 #include "wine/list.h"
 #include "wine/debug.h"
-#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
 
@@ -138,6 +140,18 @@ static struct property *alloc_property( struct parser *parser, const WCHAR *clas
     return prop;
 }
 
+static struct keyword *alloc_keyword( struct parser *parser, const WCHAR *name, const WCHAR *value )
+{
+    struct keyword *keyword = alloc_mem( parser, sizeof(*keyword) );
+    if (keyword)
+    {
+        keyword->name  = name;
+        keyword->value = value;
+        keyword->next  = NULL;
+    }
+    return keyword;
+}
+
 static WCHAR *get_string( struct parser *parser, const struct string *str )
 {
     const WCHAR *p = str->data;
@@ -158,6 +172,24 @@ static WCHAR *get_string( struct parser *parser, const struct string *str )
     return ret;
 }
 
+static WCHAR *get_path( struct parser *parser, const struct string *str )
+{
+    const WCHAR *p = str->data;
+    int len = str->len;
+    WCHAR *ret;
+
+    if (p[0] == '{' && p[len - 1] == '}')
+    {
+        p++;
+        len -= 2;
+    }
+
+    if (!(ret = alloc_mem( parser, (len + 1) * sizeof(WCHAR) ))) return NULL;
+    memcpy( ret, p, len * sizeof(WCHAR) );
+    ret[len] = 0;
+    return ret;
+}
+
 static int get_int( struct parser *parser )
 {
     const WCHAR *p = &parser->cmd[parser->idx];
@@ -255,13 +287,17 @@ static int wql_lex( void *val, struct parser *parser );
     result = current_view
 
 
-#line 259 "wql.tab.c" /* yacc.c:339  */
+#line 291 "wql.tab.c"
 
-# ifndef YY_NULL
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULL nullptr
+# ifndef YY_NULLPTR
+#  if defined __cplusplus
+#   if 201103L <= __cplusplus
+#    define YY_NULLPTR nullptr
+#   else
+#    define YY_NULLPTR 0
+#   endif
 #  else
-#   define YY_NULL 0
+#   define YY_NULLPTR ((void*)0)
 #  endif
 # endif
 
@@ -273,8 +309,8 @@ static int wql_lex( void *val, struct parser *parser );
 # define YYERROR_VERBOSE 1
 #endif
 
-/* In a future release of Bison, this section will be replaced
-   by #include "wql.tab.h".  */
+/* Use api.header.include to #include this header
+   instead of duplicating it here.  */
 #ifndef YY_WQL_E_REACTOSSYNC_GCC_DLL_WIN32_WBEMPROX_WQL_TAB_H_INCLUDED
 # define YY_WQL_E_REACTOSSYNC_GCC_DLL_WIN32_WBEMPROX_WQL_TAB_H_INCLUDED
 /* Debug traces.  */
@@ -307,37 +343,42 @@ extern int wql_debug;
     TK_MINUS = 272,
     TK_ILLEGAL = 273,
     TK_BY = 274,
-    TK_STRING = 275,
-    TK_ID = 276,
-    TK_OR = 277,
-    TK_AND = 278,
-    TK_NOT = 279,
-    TK_EQ = 280,
-    TK_NE = 281,
-    TK_LT = 282,
-    TK_GT = 283,
-    TK_LE = 284,
-    TK_GE = 285,
-    TK_LIKE = 286
+    TK_ASSOCIATORS = 275,
+    TK_OF = 276,
+    TK_STRING = 277,
+    TK_ID = 278,
+    TK_PATH = 279,
+    TK_OR = 280,
+    TK_AND = 281,
+    TK_NOT = 282,
+    TK_EQ = 283,
+    TK_NE = 284,
+    TK_LT = 285,
+    TK_GT = 286,
+    TK_LE = 287,
+    TK_GE = 288,
+    TK_LIKE = 289
   };
 #endif
 
 /* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE YYSTYPE;
 union YYSTYPE
 {
-#line 194 "wql.y" /* yacc.c:355  */
+#line 222 "wql.y"
 
     struct string str;
     WCHAR *string;
     struct property *proplist;
+    struct keyword *keywordlist;
     struct view *view;
     struct expr *expr;
     int integer;
 
-#line 340 "wql.tab.c" /* yacc.c:355  */
+#line 379 "wql.tab.c"
+
 };
+typedef union YYSTYPE YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_DECLARED 1
 #endif
@@ -348,9 +389,7 @@ int wql_parse (struct parser *ctx);
 
 #endif /* !YY_WQL_E_REACTOSSYNC_GCC_DLL_WIN32_WBEMPROX_WQL_TAB_H_INCLUDED  */
 
-/* Copy the second part of user declarations.  */
 
-#line 354 "wql.tab.c" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -371,13 +410,13 @@ typedef signed char yytype_int8;
 #ifdef YYTYPE_UINT16
 typedef YYTYPE_UINT16 yytype_uint16;
 #else
-typedef unsigned short int yytype_uint16;
+typedef unsigned short yytype_uint16;
 #endif
 
 #ifdef YYTYPE_INT16
 typedef YYTYPE_INT16 yytype_int16;
 #else
-typedef short int yytype_int16;
+typedef short yytype_int16;
 #endif
 
 #ifndef YYSIZE_T
@@ -389,7 +428,7 @@ typedef short int yytype_int16;
 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
-#  define YYSIZE_T unsigned int
+#  define YYSIZE_T unsigned
 # endif
 #endif
 
@@ -407,14 +446,24 @@ typedef short int yytype_int16;
 # endif
 #endif
 
-#ifndef __attribute__
-/* This feature is available in gcc versions 2.5 and later.  */
-# if (! defined __GNUC__ || __GNUC__ < 2 \
-      || (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
-#  define __attribute__(Spec) /* empty */
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__                                               \
+      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
+     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+#  define YY_ATTRIBUTE(Spec) /* empty */
 # endif
 #endif
 
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
 # define YYUSE(E) ((void) (E))
@@ -422,7 +471,7 @@ typedef short int yytype_int16;
 # define YYUSE(E) /* empty */
 #endif
 
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
 /* Suppress an incorrect diagnostic about yylval being uninitialized.  */
 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
     _Pragma ("GCC diagnostic push") \
@@ -442,6 +491,8 @@ typedef short int yytype_int16;
 #endif
 
 
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
 #if ! defined yyoverflow || YYERROR_VERBOSE
 
 /* The parser invokes alloca or malloc; define the necessary symbols.  */
@@ -571,29 +622,29 @@ union yyalloc
 #endif /* !YYCOPY_NEEDED */
 
 /* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  9
+#define YYFINAL  13
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   85
+#define YYLAST   91
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  32
+#define YYNTOKENS  35
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  10
+#define YYNNTS  15
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  40
+#define YYNRULES  49
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  74
+#define YYNSTATES  87
 
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
-   by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   286
+#define YYMAXUTOK   289
 
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, with out-of-bounds checking.  */
 #define YYTRANSLATE(YYX)                                                \
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+  ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
-   as returned by yylex, without out-of-bounds checking.  */
+   as returned by yylex.  */
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -624,18 +675,18 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   221,   221,   233,   245,   260,   261,   265,   272,   278,
-     287,   296,   303,   309,   315,   321,   327,   333,   339,   345,
-     351,   357,   363,   369,   375,   381,   387,   393,   399,   405,
-     411,   417,   423,   429,   435,   444,   453,   462,   468,   474,
-     480
+       0,   248,   248,   250,   254,   263,   269,   278,   279,   286,
+     298,   313,   325,   337,   352,   353,   357,   364,   370,   379,
+     388,   395,   401,   407,   413,   419,   425,   431,   437,   443,
+     449,   455,   461,   467,   473,   479,   485,   491,   497,   503,
+     509,   515,   521,   527,   536,   545,   554,   560,   566,   572
 };
 #endif
 
@@ -647,10 +698,11 @@ static const char *const yytname[] =
   "$end", "error", "$undefined", "TK_SELECT", "TK_FROM", "TK_STAR",
   "TK_COMMA", "TK_DOT", "TK_IS", "TK_LP", "TK_RP", "TK_NULL", "TK_FALSE",
   "TK_TRUE", "TK_INTEGER", "TK_WHERE", "TK_SPACE", "TK_MINUS",
-  "TK_ILLEGAL", "TK_BY", "TK_STRING", "TK_ID", "TK_OR", "TK_AND", "TK_NOT",
-  "TK_EQ", "TK_NE", "TK_LT", "TK_GT", "TK_LE", "TK_GE", "TK_LIKE",
-  "$accept", "select", "proplist", "prop", "id", "number", "expr",
-  "string_val", "prop_val", "const_val", YY_NULL
+  "TK_ILLEGAL", "TK_BY", "TK_ASSOCIATORS", "TK_OF", "TK_STRING", "TK_ID",
+  "TK_PATH", "TK_OR", "TK_AND", "TK_NOT", "TK_EQ", "TK_NE", "TK_LT",
+  "TK_GT", "TK_LE", "TK_GE", "TK_LIKE", "$accept", "query", "path",
+  "keyword", "keywordlist", "associatorsof", "select", "proplist", "prop",
+  "id", "number", "expr", "string_val", "prop_val", "const_val", YY_NULLPTR
 };
 #endif
 
@@ -662,14 +714,14 @@ static const yytype_uint16 yytoknum[] =
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
      275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
-     285,   286
+     285,   286,   287,   288,   289
 };
 # endif
 
-#define YYPACT_NINF -23
+#define YYPACT_NINF -25
 
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-23)))
+  (!!((Yystate) == (-25)))
 
 #define YYTABLE_NINF -1
 
@@ -680,14 +732,15 @@ static const yytype_uint16 yytoknum[] =
      STATE-NUM.  */
 static const yytype_int8 yypact[] =
 {
-      -2,    10,    34,    14,   -23,   -23,    29,    48,    46,   -23,
-     -23,    14,    11,    14,    42,   -23,   -23,    28,    28,   -16,
-     -23,   -23,   -23,   -23,    28,   -23,   -23,    22,    -8,   -22,
-      33,    14,    14,   -23,    28,    28,    27,    50,    54,    59,
-      59,    59,    59,    39,    14,    14,    14,    14,    14,    14,
-     -23,   -23,   -23,    52,   -23,   -23,    58,   -23,   -23,   -23,
-     -23,   -23,   -23,   -23,   -23,   -23,   -23,   -23,   -23,   -23,
-     -23,   -23,   -23,   -23
+       0,     8,   -13,    15,   -25,   -25,    10,   -25,   -25,    38,
+      37,    42,    26,   -25,   -25,    10,     9,    10,   -25,    57,
+      58,   -25,   -25,    10,    25,    10,   -25,    23,    25,   -24,
+     -25,   -25,   -25,   -25,    25,   -25,   -25,   -19,    -7,    51,
+     -25,    10,    20,    10,    10,   -25,    25,    25,    -9,    49,
+      53,    56,    56,    56,    56,    52,    10,    10,    10,    10,
+      10,    10,   -25,   -25,   -25,   -25,   -25,   -25,   -25,    65,
+     -25,   -25,   -25,   -25,   -25,   -25,   -25,   -25,   -25,   -25,
+     -25,   -25,   -25,   -25,   -25,   -25,   -25
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -695,26 +748,29 @@ static const yytype_int8 yypact[] =
      means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       0,     0,     0,     0,     7,    10,     0,     5,     9,     1,
-       2,     0,     0,     0,     3,     6,     8,     0,     0,     0,
-      40,    39,    11,    38,     0,    36,    37,     4,     0,     0,
-       0,     0,     0,    15,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     3,     2,     0,    16,    19,     0,
+      14,    18,     0,     1,    11,     0,     0,     0,     4,     9,
+      12,    15,    17,     0,     0,     7,    10,     5,     0,     0,
+      49,    48,    20,    47,     0,    45,    46,    13,     0,     0,
+       8,     0,     0,     0,     0,    24,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      12,    32,    34,    14,    13,    29,     0,    31,    16,    33,
-      21,    18,    17,    19,    20,    35,    28,    22,    27,    24,
-      23,    25,    26,    30
+       0,     0,     6,    21,    41,    43,    23,    22,    38,     0,
+      40,    25,    42,    30,    27,    26,    28,    29,    44,    37,
+      31,    36,    33,    32,    34,    35,    39
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 {
-     -23,   -23,    64,     1,    47,   -23,    12,   -23,   -20,    43
+     -25,   -25,   -25,   -25,    66,   -25,   -25,    61,    43,    -6,
+     -25,   -18,   -25,    -3,    36
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int8 yydefgoto[] =
 {
-      -1,     2,     6,    25,     8,    26,    27,    66,    28,    29
+      -1,     3,    19,    25,    26,     4,     5,     9,    35,    11,
+      36,    37,    79,    38,    39
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -722,62 +778,65 @@ static const yytype_int8 yydefgoto[] =
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_uint8 yytable[] =
 {
-      36,     1,     7,    44,    45,    46,    47,    48,    49,    31,
-      32,    51,    52,     7,     3,     4,     4,    37,    38,    39,
-      40,    41,    42,    43,    67,    68,    69,    70,    71,    72,
-      30,     5,     5,    11,     9,     5,    33,    18,    55,    19,
-      20,    21,    22,    50,    34,    35,    53,    54,    23,     5,
-      10,    56,    24,    13,    12,    34,    35,    17,    14,    65,
-      16,    57,    20,    21,    22,    59,    20,    21,    22,    73,
-      23,    20,    21,    22,    23,    35,    15,     0,     0,    23,
-      58,    60,    61,    62,    63,    64
+      14,    48,    68,     1,    43,    44,    46,    47,    12,    20,
+      42,    22,     6,     7,     7,    13,    45,    27,    69,    27,
+       2,    49,    50,    51,    52,    53,    54,    55,    66,    67,
+      63,     8,     8,     8,    28,    62,    29,    30,    31,    32,
+      64,    65,    15,    16,    10,    46,    47,    33,     8,    17,
+      18,    41,    34,    80,    81,    82,    83,    84,    85,    10,
+      70,    30,    31,    32,    72,    30,    31,    32,    30,    31,
+      32,    33,    23,    24,    78,    33,    86,    21,    33,    56,
+      57,    58,    59,    60,    61,    71,    73,    74,    75,    76,
+      77,    40
 };
 
-static const yytype_int8 yycheck[] =
+static const yytype_uint8 yycheck[] =
 {
-       8,     3,     1,    25,    26,    27,    28,    29,    30,    25,
-      26,    31,    32,    12,     4,     5,     5,    25,    26,    27,
-      28,    29,    30,    31,    44,    45,    46,    47,    48,    49,
-      18,    21,    21,     4,     0,    21,    24,     9,    11,    11,
-      12,    13,    14,    10,    22,    23,    34,    35,    20,    21,
-       3,    24,    24,     7,     6,    22,    23,    15,    11,    20,
-      13,    11,    12,    13,    14,    11,    12,    13,    14,    11,
-      20,    12,    13,    14,    20,    23,    12,    -1,    -1,    20,
-      37,    38,    39,    40,    41,    42
+       6,     8,    11,     3,    28,    29,    25,    26,    21,    15,
+      28,    17,     4,     5,     5,     0,    34,    23,    27,    25,
+      20,    28,    29,    30,    31,    32,    33,    34,    46,    47,
+      10,    23,    23,    23,     9,    41,    11,    12,    13,    14,
+      43,    44,     4,     6,     1,    25,    26,    22,    23,     7,
+      24,    28,    27,    56,    57,    58,    59,    60,    61,    16,
+      11,    12,    13,    14,    11,    12,    13,    14,    12,    13,
+      14,    22,    15,    15,    22,    22,    11,    16,    22,    28,
+      29,    30,    31,    32,    33,    49,    50,    51,    52,    53,
+      54,    25
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,     3,    33,     4,     5,    21,    34,    35,    36,     0,
-      36,     4,     6,     7,    36,    34,    36,    15,     9,    11,
-      12,    13,    14,    20,    24,    35,    37,    38,    40,    41,
-      38,    25,    26,    38,    22,    23,     8,    25,    26,    27,
-      28,    29,    30,    31,    25,    26,    27,    28,    29,    30,
-      10,    40,    40,    38,    38,    11,    24,    11,    41,    11,
-      41,    41,    41,    41,    41,    20,    39,    40,    40,    40,
-      40,    40,    40,    11
+       0,     3,    20,    36,    40,    41,     4,     5,    23,    42,
+      43,    44,    21,     0,    44,     4,     6,     7,    24,    37,
+      44,    42,    44,    15,    15,    38,    39,    44,     9,    11,
+      12,    13,    14,    22,    27,    43,    45,    46,    48,    49,
+      39,    28,    46,    28,    29,    46,    25,    26,     8,    28,
+      29,    30,    31,    32,    33,    34,    28,    29,    30,    31,
+      32,    33,    44,    10,    48,    48,    46,    46,    11,    27,
+      11,    49,    11,    49,    49,    49,    49,    49,    22,    47,
+      48,    48,    48,    48,    48,    48,    11
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    32,    33,    33,    33,    34,    34,    34,    35,    35,
-      36,    37,    38,    38,    38,    38,    38,    38,    38,    38,
-      38,    38,    38,    38,    38,    38,    38,    38,    38,    38,
-      38,    38,    38,    38,    38,    39,    40,    41,    41,    41,
-      41
+       0,    35,    36,    36,    37,    38,    38,    39,    39,    40,
+      40,    41,    41,    41,    42,    42,    42,    43,    43,    44,
+      45,    46,    46,    46,    46,    46,    46,    46,    46,    46,
+      46,    46,    46,    46,    46,    46,    46,    46,    46,    46,
+      46,    46,    46,    46,    47,    48,    49,    49,    49,    49
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
-       0,     2,     3,     4,     6,     1,     3,     1,     3,     1,
-       1,     1,     3,     3,     3,     2,     3,     3,     3,     3,
-       3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
-       4,     3,     3,     3,     3,     1,     1,     1,     1,     1,
-       1
+       0,     2,     1,     1,     1,     1,     3,     1,     2,     3,
+       5,     3,     4,     6,     1,     3,     1,     3,     1,     1,
+       1,     3,     3,     3,     2,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     3,     3,     3,     3,     3,     4,
+       3,     3,     3,     3,     1,     1,     1,     1,     1,     1
 };
 
 
@@ -793,22 +852,22 @@ static const yytype_uint8 yyr2[] =
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
-      yyerror (ctx, YY_("syntax error: cannot back up")); \
-      YYERROR;                                                  \
-    }                                                           \
-while (0)
+#define YYBACKUP(Token, Value)                                    \
+  do                                                              \
+    if (yychar == YYEMPTY)                                        \
+      {                                                           \
+        yychar = (Token);                                         \
+        yylval = (Value);                                         \
+        YYPOPSTACK (yylen);                                       \
+        yystate = *yyssp;                                         \
+        goto yybackup;                                            \
+      }                                                           \
+    else                                                          \
+      {                                                           \
+        yyerror (ctx, YY_("syntax error: cannot back up")); \
+        YYERROR;                                                  \
+      }                                                           \
+  while (0)
 
 /* Error token number */
 #define YYTERROR        1
@@ -848,38 +907,38 @@ do {                                                                      \
 } while (0)
 
 
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT.  |
-`----------------------------------------*/
+/*-----------------------------------.
+| Print this symbol's value on YYO.  |
+`-----------------------------------*/
 
 static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parser *ctx)
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, struct parser *ctx)
 {
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
+  FILE *yyoutput = yyo;
+  YYUSE (yyoutput);
   YYUSE (ctx);
   if (!yyvaluep)
     return;
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+    YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
 # endif
   YYUSE (yytype);
 }
 
 
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
+/*---------------------------.
+| Print this symbol on YYO.  |
+`---------------------------*/
 
 static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parser *ctx)
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, struct parser *ctx)
 {
-  YYFPRINTF (yyoutput, "%s %s (",
+  YYFPRINTF (yyo, "%s %s (",
              yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
 
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx);
-  YYFPRINTF (yyoutput, ")");
+  yy_symbol_value_print (yyo, yytype, yyvaluep, ctx);
+  YYFPRINTF (yyo, ")");
 }
 
 /*------------------------------------------------------------------.
@@ -913,7 +972,7 @@ do {                                                            \
 static void
 yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, struct parser *ctx)
 {
-  unsigned long int yylno = yyrline[yyrule];
+  unsigned long yylno = yyrline[yyrule];
   int yynrhs = yyr2[yyrule];
   int yyi;
   YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
@@ -924,7 +983,7 @@ yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, struct parser
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr,
                        yystos[yyssp[yyi + 1 - yynrhs]],
-                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                       &yyvsp[(yyi + 1) - (yynrhs)]
                                               , ctx);
       YYFPRINTF (stderr, "\n");
     }
@@ -1028,7 +1087,10 @@ yytnamerr (char *yyres, const char *yystr)
           case '\\':
             if (*++yyp != '\\')
               goto do_not_strip_quotes;
-            /* Fall through.  */
+            else
+              goto append;
+
+          append:
           default:
             if (yyres)
               yyres[yyn] = *yyp;
@@ -1046,7 +1108,7 @@ yytnamerr (char *yyres, const char *yystr)
   if (! yyres)
     return yystrlen (yystr);
 
-  return yystpcpy (yyres, yystr) - yyres;
+  return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
 }
 # endif
 
@@ -1062,11 +1124,11 @@ static int
 yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                 yytype_int16 *yyssp, int yytoken)
 {
-  YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
+  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
   YYSIZE_T yysize = yysize0;
   enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
   /* Internationalized format string. */
-  const char *yyformat = YY_NULL;
+  const char *yyformat = YY_NULLPTR;
   /* Arguments of yyformat. */
   char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
   /* Number of reported tokens (one for the "unexpected", one per
@@ -1123,11 +1185,11 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                   }
                 yyarg[yycount++] = yytname[yyx];
                 {
-                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+                  if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+                    yysize = yysize1;
+                  else
                     return 2;
-                  yysize = yysize1;
                 }
               }
         }
@@ -1139,6 +1201,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
       case N:                               \
         yyformat = S;                       \
       break
+    default: /* Avoid compiler warnings. */
       YYCASE_(0, YY_("syntax error"));
       YYCASE_(1, YY_("syntax error, unexpected %s"));
       YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
@@ -1150,9 +1213,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
 
   {
     YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+    if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+      yysize = yysize1;
+    else
       return 2;
-    yysize = yysize1;
   }
 
   if (*yymsg_alloc < yysize)
@@ -1283,23 +1347,33 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
   yychar = YYEMPTY; /* Cause a token to be read.  */
   goto yysetstate;
 
+
 /*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
+| yynewstate -- push a new state, which is found in yystate.  |
 `------------------------------------------------------------*/
- yynewstate:
+yynewstate:
   /* In all cases, when you get here, the value and location stacks
      have just been pushed.  So pushing a state here evens the stacks.  */
   yyssp++;
 
- yysetstate:
-  *yyssp = yystate;
+
+/*--------------------------------------------------------------------.
+| yynewstate -- set current state (the top of the stack) to yystate.  |
+`--------------------------------------------------------------------*/
+yysetstate:
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+  YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
+  *yyssp = (yytype_int16) yystate;
 
   if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+    goto yyexhaustedlab;
+#else
     {
       /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
+      YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
 
-#ifdef yyoverflow
+# if defined yyoverflow
       {
         /* Give user a chance to reallocate the stack.  Use copies of
            these so that the &'s don't force the real ones into
@@ -1315,14 +1389,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
                     &yyss1, yysize * sizeof (*yyssp),
                     &yyvs1, yysize * sizeof (*yyvsp),
                     &yystacksize);
-
         yyss = yyss1;
         yyvs = yyvs1;
       }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyexhaustedlab;
-# else
+# else /* defined YYSTACK_RELOCATE */
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
         goto yyexhaustedlab;
@@ -1338,35 +1408,33 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           goto yyexhaustedlab;
         YYSTACK_RELOCATE (yyss_alloc, yyss);
         YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-#  undef YYSTACK_RELOCATE
+# undef YYSTACK_RELOCATE
         if (yyss1 != yyssa)
           YYSTACK_FREE (yyss1);
       }
 # endif
-#endif /* no yyoverflow */
 
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                  (unsigned long int) yystacksize));
+                  (unsigned long) yystacksize));
 
       if (yyss + yystacksize - 1 <= yyssp)
         YYABORT;
     }
-
-  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
 
   if (yystate == YYFINAL)
     YYACCEPT;
 
   goto yybackup;
 
+
 /*-----------.
 | yybackup.  |
 `-----------*/
 yybackup:
-
   /* Do appropriate processing given the current state.  Read a
      lookahead token if we need one and don't already have one.  */
 
@@ -1424,7 +1492,6 @@ yybackup:
   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
   YY_IGNORE_MAYBE_UNINITIALIZED_END
-
   goto yynewstate;
 
 
@@ -1439,7 +1506,7 @@ yydefault:
 
 
 /*-----------------------------.
-| yyreduce -- Do a reduction.  |
+| yyreduce -- do a reduction.  |
 `-----------------------------*/
 yyreduce:
   /* yyn is the number of a rule to reduce with.  */
@@ -1459,400 +1526,471 @@ yyreduce:
   YY_REDUCE_PRINT (yyn);
   switch (yyn)
     {
-        case 2:
-#line 222 "wql.y" /* yacc.c:1646  */
+  case 4:
+#line 255 "wql.y"
+    {
+            (yyval.string) = get_path( ctx, &(yyvsp[0].str) );
+            if (!(yyval.string))
+                YYABORT;
+        }
+#line 1537 "wql.tab.c"
+    break;
+
+  case 5:
+#line 264 "wql.y"
+    {
+            (yyval.keywordlist) = alloc_keyword( ctx, (yyvsp[0].string), NULL );
+            if (!(yyval.keywordlist))
+                YYABORT;
+        }
+#line 1547 "wql.tab.c"
+    break;
+
+  case 6:
+#line 270 "wql.y"
+    {
+            (yyval.keywordlist) = alloc_keyword( ctx, (yyvsp[-2].string), (yyvsp[0].string) );
+            if (!(yyval.keywordlist))
+                YYABORT;
+        }
+#line 1557 "wql.tab.c"
+    break;
+
+  case 8:
+#line 280 "wql.y"
+    {
+            (yyvsp[-1].keywordlist)->next = (yyvsp[0].keywordlist);
+        }
+#line 1565 "wql.tab.c"
+    break;
+
+  case 9:
+#line 287 "wql.y"
     {
             HRESULT hr;
             struct parser *parser = ctx;
             struct view *view;
 
-            hr = create_view( NULL, (yyvsp[0].string), NULL, &view );
+            hr = create_view( VIEW_TYPE_ASSOCIATORS, (yyvsp[0].string), NULL, NULL, NULL, NULL, &view );
             if (hr != S_OK)
                 YYABORT;
 
             PARSER_BUBBLE_UP_VIEW( parser, (yyval.view), view );
         }
-#line 1476 "wql.tab.c" /* yacc.c:1646  */
+#line 1581 "wql.tab.c"
     break;
 
-  case 3:
-#line 234 "wql.y" /* yacc.c:1646  */
+  case 10:
+#line 299 "wql.y"
     {
             HRESULT hr;
             struct parser *parser = ctx;
             struct view *view;
 
-            hr = create_view( (yyvsp[-2].proplist), (yyvsp[0].string), NULL, &view );
+            hr = create_view( VIEW_TYPE_ASSOCIATORS, (yyvsp[-2].string), (yyvsp[0].keywordlist), NULL, NULL, NULL, &view );
             if (hr != S_OK)
                 YYABORT;
 
             PARSER_BUBBLE_UP_VIEW( parser, (yyval.view), view );
         }
-#line 1492 "wql.tab.c" /* yacc.c:1646  */
+#line 1597 "wql.tab.c"
     break;
 
-  case 4:
-#line 246 "wql.y" /* yacc.c:1646  */
+  case 11:
+#line 314 "wql.y"
     {
             HRESULT hr;
             struct parser *parser = ctx;
             struct view *view;
 
-            hr = create_view( (yyvsp[-4].proplist), (yyvsp[-2].string), (yyvsp[0].expr), &view );
+            hr = create_view( VIEW_TYPE_SELECT, NULL, NULL, (yyvsp[0].string), NULL, NULL, &view );
             if (hr != S_OK)
                 YYABORT;
 
             PARSER_BUBBLE_UP_VIEW( parser, (yyval.view), view );
         }
-#line 1508 "wql.tab.c" /* yacc.c:1646  */
+#line 1613 "wql.tab.c"
     break;
 
-  case 6:
-#line 262 "wql.y" /* yacc.c:1646  */
+  case 12:
+#line 326 "wql.y"
+    {
+            HRESULT hr;
+            struct parser *parser = ctx;
+            struct view *view;
+
+            hr = create_view( VIEW_TYPE_SELECT, NULL, NULL, (yyvsp[0].string), (yyvsp[-2].proplist), NULL, &view );
+            if (hr != S_OK)
+                YYABORT;
+
+            PARSER_BUBBLE_UP_VIEW( parser, (yyval.view), view );
+        }
+#line 1629 "wql.tab.c"
+    break;
+
+  case 13:
+#line 338 "wql.y"
+    {
+            HRESULT hr;
+            struct parser *parser = ctx;
+            struct view *view;
+
+            hr = create_view( VIEW_TYPE_SELECT, NULL, NULL, (yyvsp[-2].string), (yyvsp[-4].proplist), (yyvsp[0].expr), &view );
+            if (hr != S_OK)
+                YYABORT;
+
+            PARSER_BUBBLE_UP_VIEW( parser, (yyval.view), view );
+        }
+#line 1645 "wql.tab.c"
+    break;
+
+  case 15:
+#line 354 "wql.y"
     {
             (yyvsp[-2].proplist)->next = (yyvsp[0].proplist);
         }
-#line 1516 "wql.tab.c" /* yacc.c:1646  */
+#line 1653 "wql.tab.c"
     break;
 
-  case 7:
-#line 266 "wql.y" /* yacc.c:1646  */
+  case 16:
+#line 358 "wql.y"
     {
             (yyval.proplist) = NULL;
         }
-#line 1524 "wql.tab.c" /* yacc.c:1646  */
+#line 1661 "wql.tab.c"
     break;
 
-  case 8:
-#line 273 "wql.y" /* yacc.c:1646  */
+  case 17:
+#line 365 "wql.y"
     {
             (yyval.proplist) = alloc_property( ctx, (yyvsp[-2].string), (yyvsp[0].string) );
             if (!(yyval.proplist))
                 YYABORT;
         }
-#line 1534 "wql.tab.c" /* yacc.c:1646  */
+#line 1671 "wql.tab.c"
     break;
 
-  case 9:
-#line 279 "wql.y" /* yacc.c:1646  */
+  case 18:
+#line 371 "wql.y"
     {
             (yyval.proplist) = alloc_property( ctx, NULL, (yyvsp[0].string) );
             if (!(yyval.proplist))
                 YYABORT;
         }
-#line 1544 "wql.tab.c" /* yacc.c:1646  */
+#line 1681 "wql.tab.c"
     break;
 
-  case 10:
-#line 288 "wql.y" /* yacc.c:1646  */
+  case 19:
+#line 380 "wql.y"
     {
             (yyval.string) = get_string( ctx, &(yyvsp[0].str) );
             if (!(yyval.string))
                 YYABORT;
         }
-#line 1554 "wql.tab.c" /* yacc.c:1646  */
+#line 1691 "wql.tab.c"
     break;
 
-  case 11:
-#line 297 "wql.y" /* yacc.c:1646  */
+  case 20:
+#line 389 "wql.y"
     {
             (yyval.integer) = get_int( ctx );
         }
-#line 1562 "wql.tab.c" /* yacc.c:1646  */
+#line 1699 "wql.tab.c"
     break;
 
-  case 12:
-#line 304 "wql.y" /* yacc.c:1646  */
+  case 21:
+#line 396 "wql.y"
     {
             (yyval.expr) = (yyvsp[-1].expr);
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1572 "wql.tab.c" /* yacc.c:1646  */
+#line 1709 "wql.tab.c"
     break;
 
-  case 13:
-#line 310 "wql.y" /* yacc.c:1646  */
+  case 22:
+#line 402 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_AND, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1582 "wql.tab.c" /* yacc.c:1646  */
+#line 1719 "wql.tab.c"
     break;
 
-  case 14:
-#line 316 "wql.y" /* yacc.c:1646  */
+  case 23:
+#line 408 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_OR, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1592 "wql.tab.c" /* yacc.c:1646  */
+#line 1729 "wql.tab.c"
     break;
 
-  case 15:
-#line 322 "wql.y" /* yacc.c:1646  */
+  case 24:
+#line 414 "wql.y"
     {
             (yyval.expr) = expr_unary( ctx, (yyvsp[0].expr), OP_NOT );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1602 "wql.tab.c" /* yacc.c:1646  */
+#line 1739 "wql.tab.c"
     break;
 
-  case 16:
-#line 328 "wql.y" /* yacc.c:1646  */
+  case 25:
+#line 420 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_EQ, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1612 "wql.tab.c" /* yacc.c:1646  */
+#line 1749 "wql.tab.c"
     break;
 
-  case 17:
-#line 334 "wql.y" /* yacc.c:1646  */
+  case 26:
+#line 426 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_GT, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1622 "wql.tab.c" /* yacc.c:1646  */
+#line 1759 "wql.tab.c"
     break;
 
-  case 18:
-#line 340 "wql.y" /* yacc.c:1646  */
+  case 27:
+#line 432 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_LT, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1632 "wql.tab.c" /* yacc.c:1646  */
+#line 1769 "wql.tab.c"
     break;
 
-  case 19:
-#line 346 "wql.y" /* yacc.c:1646  */
+  case 28:
+#line 438 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_LE, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1642 "wql.tab.c" /* yacc.c:1646  */
+#line 1779 "wql.tab.c"
     break;
 
-  case 20:
-#line 352 "wql.y" /* yacc.c:1646  */
+  case 29:
+#line 444 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_GE, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1652 "wql.tab.c" /* yacc.c:1646  */
+#line 1789 "wql.tab.c"
     break;
 
-  case 21:
-#line 358 "wql.y" /* yacc.c:1646  */
+  case 30:
+#line 450 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_NE, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1662 "wql.tab.c" /* yacc.c:1646  */
+#line 1799 "wql.tab.c"
     break;
 
-  case 22:
-#line 364 "wql.y" /* yacc.c:1646  */
+  case 31:
+#line 456 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_EQ, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1672 "wql.tab.c" /* yacc.c:1646  */
+#line 1809 "wql.tab.c"
     break;
 
-  case 23:
-#line 370 "wql.y" /* yacc.c:1646  */
+  case 32:
+#line 462 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_GT, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1682 "wql.tab.c" /* yacc.c:1646  */
+#line 1819 "wql.tab.c"
     break;
 
-  case 24:
-#line 376 "wql.y" /* yacc.c:1646  */
+  case 33:
+#line 468 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_LT, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1692 "wql.tab.c" /* yacc.c:1646  */
+#line 1829 "wql.tab.c"
     break;
 
-  case 25:
-#line 382 "wql.y" /* yacc.c:1646  */
+  case 34:
+#line 474 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_LE, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1702 "wql.tab.c" /* yacc.c:1646  */
+#line 1839 "wql.tab.c"
     break;
 
-  case 26:
-#line 388 "wql.y" /* yacc.c:1646  */
+  case 35:
+#line 480 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_GE, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1712 "wql.tab.c" /* yacc.c:1646  */
+#line 1849 "wql.tab.c"
     break;
 
-  case 27:
-#line 394 "wql.y" /* yacc.c:1646  */
+  case 36:
+#line 486 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_NE, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1722 "wql.tab.c" /* yacc.c:1646  */
+#line 1859 "wql.tab.c"
     break;
 
-  case 28:
-#line 400 "wql.y" /* yacc.c:1646  */
+  case 37:
+#line 492 "wql.y"
     {
             (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_LIKE, (yyvsp[0].expr) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1732 "wql.tab.c" /* yacc.c:1646  */
+#line 1869 "wql.tab.c"
     break;
 
-  case 29:
-#line 406 "wql.y" /* yacc.c:1646  */
+  case 38:
+#line 498 "wql.y"
     {
             (yyval.expr) = expr_unary( ctx, (yyvsp[-2].expr), OP_ISNULL );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1742 "wql.tab.c" /* yacc.c:1646  */
+#line 1879 "wql.tab.c"
     break;
 
-  case 30:
-#line 412 "wql.y" /* yacc.c:1646  */
+  case 39:
+#line 504 "wql.y"
     {
             (yyval.expr) = expr_unary( ctx, (yyvsp[-3].expr), OP_NOTNULL );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1752 "wql.tab.c" /* yacc.c:1646  */
+#line 1889 "wql.tab.c"
     break;
 
-  case 31:
-#line 418 "wql.y" /* yacc.c:1646  */
+  case 40:
+#line 510 "wql.y"
     {
             (yyval.expr) = expr_unary( ctx, (yyvsp[-2].expr), OP_ISNULL );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1762 "wql.tab.c" /* yacc.c:1646  */
+#line 1899 "wql.tab.c"
     break;
 
-  case 32:
-#line 424 "wql.y" /* yacc.c:1646  */
+  case 41:
+#line 516 "wql.y"
     {
             (yyval.expr) = expr_unary( ctx, (yyvsp[0].expr), OP_ISNULL );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1772 "wql.tab.c" /* yacc.c:1646  */
+#line 1909 "wql.tab.c"
     break;
 
-  case 33:
-#line 430 "wql.y" /* yacc.c:1646  */
+  case 42:
+#line 522 "wql.y"
     {
             (yyval.expr) = expr_unary( ctx, (yyvsp[-2].expr), OP_NOTNULL );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1782 "wql.tab.c" /* yacc.c:1646  */
+#line 1919 "wql.tab.c"
     break;
 
-  case 34:
-#line 436 "wql.y" /* yacc.c:1646  */
+  case 43:
+#line 528 "wql.y"
     {
             (yyval.expr) = expr_unary( ctx, (yyvsp[0].expr), OP_NOTNULL );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1792 "wql.tab.c" /* yacc.c:1646  */
+#line 1929 "wql.tab.c"
     break;
 
-  case 35:
-#line 445 "wql.y" /* yacc.c:1646  */
+  case 44:
+#line 537 "wql.y"
     {
             (yyval.expr) = expr_sval( ctx, &(yyvsp[0].str) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1802 "wql.tab.c" /* yacc.c:1646  */
+#line 1939 "wql.tab.c"
     break;
 
-  case 36:
-#line 454 "wql.y" /* yacc.c:1646  */
+  case 45:
+#line 546 "wql.y"
     {
             (yyval.expr) = expr_propval( ctx, (yyvsp[0].proplist) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1812 "wql.tab.c" /* yacc.c:1646  */
+#line 1949 "wql.tab.c"
     break;
 
-  case 37:
-#line 463 "wql.y" /* yacc.c:1646  */
+  case 46:
+#line 555 "wql.y"
     {
             (yyval.expr) = expr_ival( ctx, (yyvsp[0].integer) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1822 "wql.tab.c" /* yacc.c:1646  */
+#line 1959 "wql.tab.c"
     break;
 
-  case 38:
-#line 469 "wql.y" /* yacc.c:1646  */
+  case 47:
+#line 561 "wql.y"
     {
             (yyval.expr) = expr_sval( ctx, &(yyvsp[0].str) );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1832 "wql.tab.c" /* yacc.c:1646  */
+#line 1969 "wql.tab.c"
     break;
 
-  case 39:
-#line 475 "wql.y" /* yacc.c:1646  */
+  case 48:
+#line 567 "wql.y"
     {
             (yyval.expr) = expr_bval( ctx, -1 );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1842 "wql.tab.c" /* yacc.c:1646  */
+#line 1979 "wql.tab.c"
     break;
 
-  case 40:
-#line 481 "wql.y" /* yacc.c:1646  */
+  case 49:
+#line 573 "wql.y"
     {
             (yyval.expr) = expr_bval( ctx, 0 );
             if (!(yyval.expr))
                 YYABORT;
         }
-#line 1852 "wql.tab.c" /* yacc.c:1646  */
+#line 1989 "wql.tab.c"
     break;
 
 
-#line 1856 "wql.tab.c" /* yacc.c:1646  */
+#line 1993 "wql.tab.c"
+
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -1877,14 +2015,13 @@ yyreduce:
   /* Now 'shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTOKENS];
+  {
+    const int yylhs = yyr1[yyn] - YYNTOKENS;
+    const int yyi = yypgoto[yylhs] + *yyssp;
+    yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+               ? yytable[yyi]
+               : yydefgoto[yylhs]);
+  }
 
   goto yynewstate;
 
@@ -1967,12 +2104,10 @@ yyerrlab:
 | yyerrorlab -- error raised explicitly by YYERROR.  |
 `---------------------------------------------------*/
 yyerrorlab:
-
-  /* Pacify compilers like GCC when the user code never invokes
-     YYERROR and the label yyerrorlab therefore never appears in user
-     code.  */
-  if (/*CONSTCOND*/ 0)
-     goto yyerrorlab;
+  /* Pacify compilers when the user code never invokes YYERROR and the
+     label yyerrorlab therefore never appears in user code.  */
+  if (0)
+    YYERROR;
 
   /* Do not reclaim the symbols of the rule whose action triggered
      this YYERROR.  */
@@ -2034,6 +2169,7 @@ yyacceptlab:
   yyresult = 0;
   goto yyreturn;
 
+
 /*-----------------------------------.
 | yyabortlab -- YYABORT comes here.  |
 `-----------------------------------*/
@@ -2041,6 +2177,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
+
 #if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
@@ -2051,6 +2188,10 @@ yyexhaustedlab:
   /* Fall through.  */
 #endif
 
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result.  |
+`-----------------------------------------------------*/
 yyreturn:
   if (yychar != YYEMPTY)
     {
@@ -2080,7 +2221,7 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 488 "wql.y" /* yacc.c:1906  */
+#line 580 "wql.y"
 
 
 HRESULT parse_query( const WCHAR *str, struct view **view, struct list *mem )
@@ -2131,16 +2272,18 @@ static const char id_char[] =
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 };
 
-struct keyword
+struct wql_keyword
 {
     const WCHAR *name;
     unsigned int len;
     int type;
 };
 
-#define MAX_TOKEN_LEN 6
+#define MIN_TOKEN_LEN 2
+#define MAX_TOKEN_LEN 11
 
 static const WCHAR andW[] = {'A','N','D'};
+static const WCHAR associatorsW[] = {'A','S','S','O','C','I','A','T','O','R','S'};
 static const WCHAR byW[] = {'B','Y'};
 static const WCHAR falseW[] = {'F','A','L','S','E'};
 static const WCHAR fromW[] = {'F','R','O','M'};
@@ -2148,34 +2291,37 @@ static const WCHAR isW[] = {'I','S'};
 static const WCHAR likeW[] = {'L','I','K','E'};
 static const WCHAR notW[] = {'N','O','T'};
 static const WCHAR nullW[] = {'N','U','L','L'};
+static const WCHAR ofW[] = {'O','F'};
 static const WCHAR orW[] = {'O','R'};
 static const WCHAR selectW[] = {'S','E','L','E','C','T'};
 static const WCHAR trueW[] = {'T','R','U','E'};
 static const WCHAR whereW[] = {'W','H','E','R','E'};
 
-static const struct keyword keyword_table[] =
+static const struct wql_keyword keyword_table[] =
 {
-  { andW,    ARRAY_SIZE(andW),    TK_AND },
-  { byW,     ARRAY_SIZE(byW),     TK_BY },
-  { falseW,  ARRAY_SIZE(falseW),  TK_FALSE },
-  { fromW,   ARRAY_SIZE(fromW),   TK_FROM },
-  { isW,     ARRAY_SIZE(isW),     TK_IS },
-  { likeW,   ARRAY_SIZE(likeW),   TK_LIKE },
-  { notW,    ARRAY_SIZE(notW),    TK_NOT },
-  { nullW,   ARRAY_SIZE(nullW),   TK_NULL },
-  { orW,     ARRAY_SIZE(orW),     TK_OR },
-  { selectW, ARRAY_SIZE(selectW), TK_SELECT },
-  { trueW,   ARRAY_SIZE(trueW),   TK_TRUE },
-  { whereW,  ARRAY_SIZE(whereW),  TK_WHERE }
+    { andW,         ARRAY_SIZE(andW),         TK_AND },
+    { associatorsW, ARRAY_SIZE(associatorsW), TK_ASSOCIATORS },
+    { byW,          ARRAY_SIZE(byW),          TK_BY },
+    { falseW,       ARRAY_SIZE(falseW),       TK_FALSE },
+    { fromW,        ARRAY_SIZE(fromW),        TK_FROM },
+    { isW,          ARRAY_SIZE(isW),          TK_IS },
+    { likeW,        ARRAY_SIZE(likeW),        TK_LIKE },
+    { notW,         ARRAY_SIZE(notW),         TK_NOT },
+    { nullW,        ARRAY_SIZE(nullW),        TK_NULL },
+    { ofW,          ARRAY_SIZE(ofW),          TK_OF },
+    { orW,          ARRAY_SIZE(orW),          TK_OR },
+    { selectW,      ARRAY_SIZE(selectW),      TK_SELECT },
+    { trueW,        ARRAY_SIZE(trueW),        TK_TRUE },
+    { whereW,       ARRAY_SIZE(whereW),       TK_WHERE }
 };
 
-static int cmp_keyword( const void *arg1, const void *arg2 )
+static int __cdecl cmp_keyword( const void *arg1, const void *arg2 )
 {
-    const struct keyword *key1 = arg1, *key2 = arg2;
+    const struct wql_keyword *key1 = arg1, *key2 = arg2;
     int len = min( key1->len, key2->len );
     int ret;
 
-    if ((ret = memicmpW( key1->name, key2->name, len ))) return ret;
+    if ((ret = _wcsnicmp( key1->name, key2->name, len ))) return ret;
     if (key1->len < key2->len) return -1;
     else if (key1->len > key2->len) return 1;
     return 0;
@@ -2183,14 +2329,14 @@ static int cmp_keyword( const void *arg1, const void *arg2 )
 
 static int keyword_type( const WCHAR *str, unsigned int len )
 {
-    struct keyword key, *ret;
+    struct wql_keyword key, *ret;
 
-    if (len > MAX_TOKEN_LEN) return TK_ID;
+    if (len < MIN_TOKEN_LEN || len > MAX_TOKEN_LEN) return TK_ID;
 
     key.name = str;
     key.len  = len;
     key.type = 0;
-    ret = bsearch( &key, keyword_table, ARRAY_SIZE(keyword_table), sizeof(struct keyword), cmp_keyword );
+    ret = bsearch( &key, keyword_table, ARRAY_SIZE(keyword_table), sizeof(struct wql_keyword), cmp_keyword );
     if (ret) return ret->type;
     return TK_ID;
 }
@@ -2205,7 +2351,7 @@ static int get_token( const WCHAR *s, int *token )
     case '\t':
     case '\r':
     case '\n':
-        for (i = 1; isspaceW( s[i] ); i++) {}
+        for (i = 1; iswspace( s[i] ); i++) {}
         *token = TK_SPACE;
         return i;
     case '-':
@@ -2218,6 +2364,15 @@ static int get_token( const WCHAR *s, int *token )
     case ')':
         *token = TK_RP;
         return 1;
+    case '{':
+        for (i = 1; s[i] && s[i] != '}'; i++) {}
+        if (s[i] != '}')
+        {
+            *token = TK_ILLEGAL;
+            return i;
+        }
+        *token = TK_PATH;
+        return i + 1;
     case '*':
         *token = TK_STAR;
         return 1;
@@ -2275,7 +2430,7 @@ static int get_token( const WCHAR *s, int *token )
         *token = TK_STRING;
         return i;
     case '.':
-        if (!isdigitW( s[1] ))
+        if (!iswdigit( s[1] ))
         {
             *token = TK_DOT;
             return 1;
@@ -2284,7 +2439,7 @@ static int get_token( const WCHAR *s, int *token )
     case '0': case '1': case '2': case '3': case '4':
     case '5': case '6': case '7': case '8': case '9':
         *token = TK_INTEGER;
-        for (i = 1; isdigitW( s[i] ); i++) {}
+        for (i = 1; iswdigit( s[i] ); i++) {}
         return i;
     default:
         if (!id_char[*s]) break;
index 3b0a77c..0630965 100644 (file)
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.  */
+/* A Bison parser, made by GNU Bison 3.4.1.  */
 
 /* Bison interface for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+   Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -30,6 +31,9 @@
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 #ifndef YY_WQL_E_REACTOSSYNC_GCC_DLL_WIN32_WBEMPROX_WQL_TAB_H_INCLUDED
 # define YY_WQL_E_REACTOSSYNC_GCC_DLL_WIN32_WBEMPROX_WQL_TAB_H_INCLUDED
 /* Debug traces.  */
@@ -62,37 +66,42 @@ extern int wql_debug;
     TK_MINUS = 272,
     TK_ILLEGAL = 273,
     TK_BY = 274,
-    TK_STRING = 275,
-    TK_ID = 276,
-    TK_OR = 277,
-    TK_AND = 278,
-    TK_NOT = 279,
-    TK_EQ = 280,
-    TK_NE = 281,
-    TK_LT = 282,
-    TK_GT = 283,
-    TK_LE = 284,
-    TK_GE = 285,
-    TK_LIKE = 286
+    TK_ASSOCIATORS = 275,
+    TK_OF = 276,
+    TK_STRING = 277,
+    TK_ID = 278,
+    TK_PATH = 279,
+    TK_OR = 280,
+    TK_AND = 281,
+    TK_NOT = 282,
+    TK_EQ = 283,
+    TK_NE = 284,
+    TK_LT = 285,
+    TK_GT = 286,
+    TK_LE = 287,
+    TK_GE = 288,
+    TK_LIKE = 289
   };
 #endif
 
 /* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE YYSTYPE;
 union YYSTYPE
 {
-#line 194 "wql.y" /* yacc.c:1909  */
+#line 222 "wql.y"
 
     struct string str;
     WCHAR *string;
     struct property *proplist;
+    struct keyword *keywordlist;
     struct view *view;
     struct expr *expr;
     int integer;
 
-#line 95 "wql.tab.h" /* yacc.c:1909  */
+#line 102 "wql.tab.h"
+
 };
+typedef union YYSTYPE YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_DECLARED 1
 #endif
index 0c48c98..9d74807 100644 (file)
@@ -18,7 +18,6 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "config.h"
 #include <stdarg.h>
 
 #include "windef.h"
@@ -28,7 +27,6 @@
 
 #include "wine/list.h"
 #include "wine/debug.h"
-#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
 
@@ -67,6 +65,18 @@ static struct property *alloc_property( struct parser *parser, const WCHAR *clas
     return prop;
 }
 
+static struct keyword *alloc_keyword( struct parser *parser, const WCHAR *name, const WCHAR *value )
+{
+    struct keyword *keyword = alloc_mem( parser, sizeof(*keyword) );
+    if (keyword)
+    {
+        keyword->name  = name;
+        keyword->value = value;
+        keyword->next  = NULL;
+    }
+    return keyword;
+}
+
 static WCHAR *get_string( struct parser *parser, const struct string *str )
 {
     const WCHAR *p = str->data;
@@ -87,6 +97,24 @@ static WCHAR *get_string( struct parser *parser, const struct string *str )
     return ret;
 }
 
+static WCHAR *get_path( struct parser *parser, const struct string *str )
+{
+    const WCHAR *p = str->data;
+    int len = str->len;
+    WCHAR *ret;
+
+    if (p[0] == '{' && p[len - 1] == '}')
+    {
+        p++;
+        len -= 2;
+    }
+
+    if (!(ret = alloc_mem( parser, (len + 1) * sizeof(WCHAR) ))) return NULL;
+    memcpy( ret, p, len * sizeof(WCHAR) );
+    ret[len] = 0;
+    return ret;
+}
+
 static int get_int( struct parser *parser )
 {
     const WCHAR *p = &parser->cmd[parser->idx];
@@ -187,7 +215,7 @@ static int wql_lex( void *val, struct parser *parser );
 
 %lex-param { struct parser *ctx }
 %parse-param { struct parser *ctx }
-%error-verbose
+%define parse.error verbose
 %pure-parser
 
 %union
@@ -195,28 +223,92 @@ static int wql_lex( void *val, struct parser *parser );
     struct string str;
     WCHAR *string;
     struct property *proplist;
+    struct keyword *keywordlist;
     struct view *view;
     struct expr *expr;
     int integer;
 }
 
 %token TK_SELECT TK_FROM TK_STAR TK_COMMA TK_DOT TK_IS TK_LP TK_RP TK_NULL TK_FALSE TK_TRUE
-%token TK_INTEGER TK_WHERE TK_SPACE TK_MINUS TK_ILLEGAL TK_BY
-%token <str> TK_STRING TK_ID
+%token TK_INTEGER TK_WHERE TK_SPACE TK_MINUS TK_ILLEGAL TK_BY TK_ASSOCIATORS TK_OF
+%token <str> TK_STRING TK_ID TK_PATH
 
-%type <string> id
+%type <string> id path
 %type <proplist> prop proplist
-%type <view> select
+%type <keywordlist> keyword keywordlist
+%type <view> query select associatorsof
 %type <expr> expr prop_val const_val string_val
 %type <integer> number
 
-%left TK_OR
-%left TK_AND
-%left TK_NOT
-%left TK_EQ TK_NE TK_LT TK_GT TK_LE TK_GE TK_LIKE
+%left TK_OR TK_AND TK_NOT TK_EQ TK_NE TK_LT TK_GT TK_LE TK_GE TK_LIKE
 
 %%
 
+query:
+    select
+  |
+    associatorsof
+    ;
+
+path:
+    TK_PATH
+        {
+            $$ = get_path( ctx, &$1 );
+            if (!$$)
+                YYABORT;
+        }
+    ;
+
+keyword:
+    id
+        {
+            $$ = alloc_keyword( ctx, $1, NULL );
+            if (!$$)
+                YYABORT;
+        }
+ | id TK_EQ id
+        {
+            $$ = alloc_keyword( ctx, $1, $3 );
+            if (!$$)
+                YYABORT;
+        }
+    ;
+
+keywordlist:
+    keyword
+  | keyword keywordlist
+        {
+            $1->next = $2;
+        }
+    ;
+
+associatorsof:
+    TK_ASSOCIATORS TK_OF path
+        {
+            HRESULT hr;
+            struct parser *parser = ctx;
+            struct view *view;
+
+            hr = create_view( VIEW_TYPE_ASSOCIATORS, $3, NULL, NULL, NULL, NULL, &view );
+            if (hr != S_OK)
+                YYABORT;
+
+            PARSER_BUBBLE_UP_VIEW( parser, $$, view );
+        }
+  | TK_ASSOCIATORS TK_OF path TK_WHERE keywordlist
+        {
+            HRESULT hr;
+            struct parser *parser = ctx;
+            struct view *view;
+
+            hr = create_view( VIEW_TYPE_ASSOCIATORS, $3, $5, NULL, NULL, NULL, &view );
+            if (hr != S_OK)
+                YYABORT;
+
+            PARSER_BUBBLE_UP_VIEW( parser, $$, view );
+        }
+    ;
+
 select:
     TK_SELECT TK_FROM id
         {
@@ -224,7 +316,7 @@ select:
             struct parser *parser = ctx;
             struct view *view;
 
-            hr = create_view( NULL, $3, NULL, &view );
+            hr = create_view( VIEW_TYPE_SELECT, NULL, NULL, $3, NULL, NULL, &view );
             if (hr != S_OK)
                 YYABORT;
 
@@ -236,7 +328,7 @@ select:
             struct parser *parser = ctx;
             struct view *view;
 
-            hr = create_view( $2, $4, NULL, &view );
+            hr = create_view( VIEW_TYPE_SELECT, NULL, NULL, $4, $2, NULL, &view );
             if (hr != S_OK)
                 YYABORT;
 
@@ -248,7 +340,7 @@ select:
             struct parser *parser = ctx;
             struct view *view;
 
-            hr = create_view( $2, $4, $6, &view );
+            hr = create_view( VIEW_TYPE_SELECT, NULL, NULL, $4, $2, $6, &view );
             if (hr != S_OK)
                 YYABORT;
 
@@ -535,16 +627,18 @@ static const char id_char[] =
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 };
 
-struct keyword
+struct wql_keyword
 {
     const WCHAR *name;
     unsigned int len;
     int type;
 };
 
-#define MAX_TOKEN_LEN 6
+#define MIN_TOKEN_LEN 2
+#define MAX_TOKEN_LEN 11
 
 static const WCHAR andW[] = {'A','N','D'};
+static const WCHAR associatorsW[] = {'A','S','S','O','C','I','A','T','O','R','S'};
 static const WCHAR byW[] = {'B','Y'};
 static const WCHAR falseW[] = {'F','A','L','S','E'};
 static const WCHAR fromW[] = {'F','R','O','M'};
@@ -552,34 +646,37 @@ static const WCHAR isW[] = {'I','S'};
 static const WCHAR likeW[] = {'L','I','K','E'};
 static const WCHAR notW[] = {'N','O','T'};
 static const WCHAR nullW[] = {'N','U','L','L'};
+static const WCHAR ofW[] = {'O','F'};
 static const WCHAR orW[] = {'O','R'};
 static const WCHAR selectW[] = {'S','E','L','E','C','T'};
 static const WCHAR trueW[] = {'T','R','U','E'};
 static const WCHAR whereW[] = {'W','H','E','R','E'};
 
-static const struct keyword keyword_table[] =
+static const struct wql_keyword keyword_table[] =
 {
-  { andW,    ARRAY_SIZE(andW),    TK_AND },
-  { byW,     ARRAY_SIZE(byW),     TK_BY },
-  { falseW,  ARRAY_SIZE(falseW),  TK_FALSE },
-  { fromW,   ARRAY_SIZE(fromW),   TK_FROM },
-  { isW,     ARRAY_SIZE(isW),     TK_IS },
-  { likeW,   ARRAY_SIZE(likeW),   TK_LIKE },
-  { notW,    ARRAY_SIZE(notW),    TK_NOT },
-  { nullW,   ARRAY_SIZE(nullW),   TK_NULL },
-  { orW,     ARRAY_SIZE(orW),     TK_OR },
-  { selectW, ARRAY_SIZE(selectW), TK_SELECT },
-  { trueW,   ARRAY_SIZE(trueW),   TK_TRUE },
-  { whereW,  ARRAY_SIZE(whereW),  TK_WHERE }
+    { andW,         ARRAY_SIZE(andW),         TK_AND },
+    { associatorsW, ARRAY_SIZE(associatorsW), TK_ASSOCIATORS },
+    { byW,          ARRAY_SIZE(byW),          TK_BY },
+    { falseW,       ARRAY_SIZE(falseW),       TK_FALSE },
+    { fromW,        ARRAY_SIZE(fromW),        TK_FROM },
+    { isW,          ARRAY_SIZE(isW),          TK_IS },
+    { likeW,        ARRAY_SIZE(likeW),        TK_LIKE },
+    { notW,         ARRAY_SIZE(notW),         TK_NOT },
+    { nullW,        ARRAY_SIZE(nullW),        TK_NULL },
+    { ofW,          ARRAY_SIZE(ofW),          TK_OF },
+    { orW,          ARRAY_SIZE(orW),          TK_OR },
+    { selectW,      ARRAY_SIZE(selectW),      TK_SELECT },
+    { trueW,        ARRAY_SIZE(trueW),        TK_TRUE },
+    { whereW,       ARRAY_SIZE(whereW),       TK_WHERE }
 };
 
-static int cmp_keyword( const void *arg1, const void *arg2 )
+static int __cdecl cmp_keyword( const void *arg1, const void *arg2 )
 {
-    const struct keyword *key1 = arg1, *key2 = arg2;
+    const struct wql_keyword *key1 = arg1, *key2 = arg2;
     int len = min( key1->len, key2->len );
     int ret;
 
-    if ((ret = memicmpW( key1->name, key2->name, len ))) return ret;
+    if ((ret = _wcsnicmp( key1->name, key2->name, len ))) return ret;
     if (key1->len < key2->len) return -1;
     else if (key1->len > key2->len) return 1;
     return 0;
@@ -587,14 +684,14 @@ static int cmp_keyword( const void *arg1, const void *arg2 )
 
 static int keyword_type( const WCHAR *str, unsigned int len )
 {
-    struct keyword key, *ret;
+    struct wql_keyword key, *ret;
 
-    if (len > MAX_TOKEN_LEN) return TK_ID;
+    if (len < MIN_TOKEN_LEN || len > MAX_TOKEN_LEN) return TK_ID;
 
     key.name = str;
     key.len  = len;
     key.type = 0;
-    ret = bsearch( &key, keyword_table, ARRAY_SIZE(keyword_table), sizeof(struct keyword), cmp_keyword );
+    ret = bsearch( &key, keyword_table, ARRAY_SIZE(keyword_table), sizeof(struct wql_keyword), cmp_keyword );
     if (ret) return ret->type;
     return TK_ID;
 }
@@ -609,7 +706,7 @@ static int get_token( const WCHAR *s, int *token )
     case '\t':
     case '\r':
     case '\n':
-        for (i = 1; isspaceW( s[i] ); i++) {}
+        for (i = 1; iswspace( s[i] ); i++) {}
         *token = TK_SPACE;
         return i;
     case '-':
@@ -622,6 +719,15 @@ static int get_token( const WCHAR *s, int *token )
     case ')':
         *token = TK_RP;
         return 1;
+    case '{':
+        for (i = 1; s[i] && s[i] != '}'; i++) {}
+        if (s[i] != '}')
+        {
+            *token = TK_ILLEGAL;
+            return i;
+        }
+        *token = TK_PATH;
+        return i + 1;
     case '*':
         *token = TK_STAR;
         return 1;
@@ -679,7 +785,7 @@ static int get_token( const WCHAR *s, int *token )
         *token = TK_STRING;
         return i;
     case '.':
-        if (!isdigitW( s[1] ))
+        if (!iswdigit( s[1] ))
         {
             *token = TK_DOT;
             return 1;
@@ -688,7 +794,7 @@ static int get_token( const WCHAR *s, int *token )
     case '0': case '1': case '2': case '3': case '4':
     case '5': case '6': case '7': case '8': case '9':
         *token = TK_INTEGER;
-        for (i = 1; isdigitW( s[i] ); i++) {}
+        for (i = 1; iswdigit( s[i] ); i++) {}
         return i;
     default:
         if (!id_char[*s]) break;
index 3098a88..def0389 100644 (file)
@@ -196,7 +196,7 @@ dll/win32/vbscript            # Synced to WineStaging-4.18
 dll/win32/version             # Synced to WineStaging-4.18
 dll/win32/vssapi              # Synced to WineStaging-4.18
 dll/win32/wbemdisp            # Synced to WineStaging-4.18
-dll/win32/wbemprox            # Synced to WineStaging-4.0
+dll/win32/wbemprox            # Synced to WineStaging-4.18
 dll/win32/windowscodecs       # Synced to WineStaging-4.0
 dll/win32/windowscodecsext    # Synced to WineStaging-2.9
 dll/win32/winemp3.acm         # Synced to WineStaging-3.3