def _create_wmi_node(grph, root_node, entity_host, name_space, class_name, entity_id): """Adds a WMI node and other stuff, for the class name.""" wmiurl = lib_wmi.GetWmiUrl(entity_host, name_space, class_name, entity_id) if wmiurl is None: return # There might be "http:" or the port number around the host. wmi_node = lib_common.NodeUrl(wmiurl) grph.add((root_node, pc.property_wmi_data, wmi_node)) # TODO: Shame, we just did it in GetWmiUrl. ip_only = lib_util.EntHostToIp(entity_host) try: # It simply returns if it cannot connect. conn_wmi = lib_wmi.WmiConnect(ip_only, name_space, False) if not conn_wmi: raise Exception("Cannot connect") lib_wmi.WmiAddClassQualifiers(grph, conn_wmi, wmi_node, class_name, False) # Now displays the base classes, to the top of the inheritance tree. pair_name_node = lib_wmi.WmiAddBaseClasses(grph, conn_wmi, wmi_node, ip_only, name_space, class_name) except Exception as exc: pair_name_node = None # TODO: If the class is not defined, maybe do not display it. err_msg = "WMI connection %s: %s" % (ip_only, str(exc)) grph.add((wmi_node, lib_common.MakeProp("WMI Error"), lib_util.NodeLiteral(err_msg))) url_name_space = lib_wmi.NamespaceUrl(name_space, ip_only, class_name) grph.add((wmi_node, pc.property_information, lib_common.NodeUrl(url_name_space))) return pair_name_node
def CreateWmiNode(grph, rootNode, entity_host, nameSpace, className, entity_id): wmiurl = lib_wmi.GetWmiUrl(entity_host, nameSpace, className, entity_id) if wmiurl is None: return # There might be "http:" or the port number around the host. # hostOnly = lib_util.EntHostToIp(entity_host) # sys.stderr.write("entity_host=%s nameSpace=%s entity_type=%s className=%s wmiurl=%s\n" % ( entity_host, nameSpace, entity_type, className, str(wmiurl) ) ) wmiNode = lib_common.NodeUrl(wmiurl) grph.add((rootNode, pc.property_wmi_data, wmiNode)) # TODO: Shame, we just did it in GetWmiUrl. ipOnly = lib_util.EntHostToIp(entity_host) try: # It simply returns if it cannot connect. connWmi = lib_wmi.WmiConnect(ipOnly, nameSpace, False) lib_wmi.WmiAddClassQualifiers(grph, connWmi, wmiNode, className, False) # Now displays the base classes, to the top of the inheritance tree. pairNameNode = lib_wmi.WmiAddBaseClasses(grph, connWmi, wmiNode, ipOnly, nameSpace, className) except Exception: pairNameNode = None # TODO: If the class is not defined, maybe do not display it. exc = sys.exc_info()[1] grph.add((wmiNode, lib_common.MakeProp("WMI Error"), lib_common.NodeLiteral(str(exc)))) urlNameSpace = lib_wmi.NamespaceUrl(nameSpace, ipOnly, className) # sys.stderr.write("entity_host=%s urlNameSpace=%s\n"%(entity_host,urlNameSpace)) grph.add( (wmiNode, pc.property_information, lib_common.NodeUrl(urlNameSpace))) return pairNameNode
def Main(): paramkeyEnumInstances = "Enumerate instances" cgiEnv = lib_common.CgiEnv(parameters={paramkeyEnumInstances: False}) flagEnumInstances = bool(cgiEnv.get_parameters(paramkeyEnumInstances)) grph = cgiEnv.GetGraph() nameSpace, className = cgiEnv.get_namespace_type() INFO("nameSpace=%s className=%s", nameSpace, className) # If nameSpace is not provided, it is set to "root/CIMV2" by default. if not className: lib_common.ErrorMessageHtml("Class name should not be empty") cimomUrl = cgiEnv.GetHost() rootNode = lib_util.EntityClassNode(className, nameSpace, cimomUrl, "WMI") AddExtraNodes(grph, rootNode) # Not sure why, but sometimes backslash replaced by slash, depending where we come from ? nameSpace = nameSpace.replace("/", "\\") try: connWmi = lib_wmi.WmiConnect(cimomUrl, nameSpace) except: exc = sys.exc_info()[1] lib_common.ErrorMessageHtml( "WMI Connecting to cimomUrl=%s nameSpace=%s Caught:%s\n" % (cimomUrl, nameSpace, str(exc))) # http://rchateau-hp:8000/survol/class_wmi.py?xid=\\rchateau-HP\root\CIMV2%3ACIM_Directory. # http://rchateau-hp:8000/survol/class_wmi.py?xid=\rchateau-HP\root\CIMV2%3ACIM_Directory.&mode=html lib_wmi.WmiAddClassQualifiers(grph, connWmi, rootNode, className, True) # Inutilisable pour: # root/CIMV2/CIM_LogicalFile # car il y en a beaucoup trop. # TODO: pEUT-ETRE QUE wql POURRAQIT PERMETTRE UNE LIMITE ?? # Ou bien arguments: De 1 a 100 etc... mais ca peut nous obliger de creer des liens bidons # pour aller aux elements suivants ou precedents. Notons que ca revient a creer des scripts artificiels. # Et aussi, revenir vers l'arborescence des classes dans ce namespace. try: wmiClass = getattr(connWmi, className) except Exception: exc = sys.exc_info()[1] lib_common.ErrorMessageHtml( "class_wmi.py cimomUrl=%s nameSpace=%s className=%s Caught:%s\n" % (cimomUrl, nameSpace, className, str(exc))) # wmiClass=[Abstract, Locale(1033): ToInstance, UUID("{8502C55F-5FBB-11D2-AAC1-006008C78BC7}"): ToInstance] # class CIM_Directory : CIM_LogicalFile # { # }; DEBUG("wmiClass=%s", str(wmiClass)) # Some examples of WMI queries. # http://timgolden.me.uk/python/wmi/tutorial.html # # logical_disk = wmi.WMI(moniker="//./root/cimv2:Win32_LogicalDisk") # c_drive = wmi.WMI(moniker='//./root/cimv2:Win32_LogicalDisk.DeviceID="C:"') # c = wmi.WMI("MachineB", user=r"MachineB\fred", password="******") # # A WMI class can be "called" with simple equal-to parameters to narrow down the list. # This filtering is happening at the WMI level. # for disk in c.Win32_LogicalDisk(DriveType=3): # for service in c.Win32_Service(Name="seclogon"): # # Arbitrary WQL queries can be run, but apparently WQL selects first all elements from WMI, # then only does its filtering: # for disk in wmi.WMI().query("SELECT Caption, Description FROM Win32_LogicalDisk WHERE DriveType <> 3"): # if flagEnumInstances: # Biggest difficulty is the impossibility to limit the numbers of results fetched by WMI. # Many classes have to many elements to display them. # This makes it virtually impossible to select their elements. if lib_wmi.WmiTooManyInstances(className): lib_common.ErrorMessageHtml("Too many elements in className=%s\n" % (className)) try: lstObj = wmiClass() except Exception: exc = sys.exc_info()[1] lib_common.ErrorMessageHtml("Caught when getting list of %s\n" % className) numLstObj = len(lstObj) DEBUG("className=%s type(wmiClass)=%s len=%d", className, str(type(wmiClass)), numLstObj) if numLstObj == 0: grph.add((rootNode, pc.property_information, lib_common.NodeLiteral("No instances in this class"))) for wmiObj in lstObj: # Full natural path: We must try to merge it with WBEM Uris. # '\\\\RCHATEAU-HP\\root\\cimv2:Win32_Process.Handle="0"' # https://jdd:[email protected]:5959/cimv2:Win32_SoftwareFeature.Name="Havana",ProductName="Havana",Version="1.0" try: fullPth = str(wmiObj.path()) except UnicodeEncodeError: # UnicodeEncodeError: 'ascii' codec can't encode characters in position 104-108: ordinal not in range(128) exc = sys.exc_info()[1] WARNING("Exception %s", str(exc)) continue # sys.stderr.write("fullPth=%s\n" % fullPth) if fullPth == "": WARNING("Empty path wmiObj=%s", str(wmiObj)) # The class Win32_PnPSignedDriver (Maybe others) generates dozens of these messages. # This is not really an issue as this class should be hidden from applications. # WARNING Empty path wmiObj= # instance of Win32_PnPSignedDriver # { # ClassGuid = NULL; # CompatID = NULL; # Description = NULL; # DeviceClass = "LEGACYDRIVER"; # DeviceID = "ROOT\\LEGACY_LSI_FC\\0000"; # DeviceName = "LSI_FC"; # DevLoader = NULL; # DriverName = NULL; # DriverProviderName = NULL; # DriverVersion = NULL; # FriendlyName = NULL; # HardWareID = NULL; # InfName = NULL; # Location = NULL; # Manufacturer = NULL; # PDO = NULL; # }; continue # fullPth=\\RCHATEAU-HP\root\CIMV2:Win32_SoundDevice.DeviceID="HDAUDIO\\FUNC_01&VEN_10EC&DEV_0221&SUBSYS_103C18E9&REV_1000\\4&3BC582&0&0001" fullPth = fullPth.replace("&", "&") wmiInstanceUrl = lib_util.EntityUrlFromMoniker(fullPth) DEBUG("wmiInstanceUrl=%s", wmiInstanceUrl) wmiInstanceNode = lib_common.NodeUrl(wmiInstanceUrl) # infos = lib_wbem_cim.get_inst_info(iname, klass, include_all=True, keys_only=True) grph.add((rootNode, pc.property_class_instance, wmiInstanceNode)) # TODO: On pourrait rassembler par classes, et aussi afficher les liens d'heritages des classes. cgiEnv.OutCgiRdf("LAYOUT_RECT", [pc.property_class_instance])
def Main(): paramkey_enum_instances = "Enumerate instances" cgiEnv = lib_common.ScriptEnvironment( parameters={paramkey_enum_instances: False}) flag_enum_instances = bool(cgiEnv.get_parameters(paramkey_enum_instances)) grph = cgiEnv.GetGraph() name_space, class_name = cgiEnv.get_namespace_type() logging.info("name_space=%s class_name=%s", name_space, class_name) # If name_space is not provided, it is set to "root/CIMV2" by default. if not class_name: lib_common.ErrorMessageHtml("Class name should not be empty") cimom_url = cgiEnv.GetHost() root_node = lib_util.EntityClassNode(class_name, name_space, cimom_url, "WMI") _add_extra_nodes(grph, root_node) # Not sure why, but sometimes backslash replaced by slash, depending where we come from ? name_space = name_space.replace("/", "\\") try: conn_wmi = lib_wmi.WmiConnect(cimom_url, name_space) except Exception as exc: lib_common.ErrorMessageHtml( "WMI Connecting to cimom_url=%s name_space=%s Caught:%s\n" % (cimom_url, name_space, str(exc))) # http://mymachine:8000/survol/class_wmi.py?xid=\\mymachine\root\CIMV2%3ACIM_Directory. # http://mymachine:8000/survol/class_wmi.py?xid=\mymachine\root\CIMV2%3ACIM_Directory.&mode=html lib_wmi.WmiAddClassQualifiers(grph, conn_wmi, root_node, class_name, True) try: wmi_class = getattr(conn_wmi, class_name) except Exception as exc: lib_common.ErrorMessageHtml( "class_wmi.py cimom_url=%s name_space=%s class_name=%s Caught:%s\n" % (cimom_url, name_space, class_name, str(exc))) # wmi_class=[Abstract, Locale(1033): ToInstance, UUID("{8502C55F-5FBB-11D2-AAC1-006008C78BC7}"): ToInstance] # class CIM_Directory : CIM_LogicalFile # { # }; logging.debug("wmi_class=%s", str(wmi_class)) # Some examples of WMI queries. # http://timgolden.me.uk/python/wmi/tutorial.html # # logical_disk = wmi.WMI(moniker="//./root/cimv2:Win32_LogicalDisk") # c_drive = wmi.WMI(moniker='//./root/cimv2:Win32_LogicalDisk.DeviceID="C:"') # c = wmi.WMI("MachineB", user=r"MachineB\fred", password="******") # # A WMI class can be "called" with simple equal-to parameters to narrow down the list. # This filtering is happening at the WMI level. # for disk in c.Win32_LogicalDisk(DriveType=3): # for service in c.Win32_Service(Name="seclogon"): # # Arbitrary WQL queries can be run, but apparently WQL selects first all elements from WMI, # then only does its filtering: # for disk in wmi.WMI().query("SELECT Caption, Description FROM Win32_LogicalDisk WHERE DriveType <> 3"): # if flag_enum_instances: # Biggest difficulty is the impossibility to limit the numbers of results fetched by WMI. # Many classes have to many elements to display them. # This makes it virtually impossible to select their elements. if lib_wmi.WmiTooManyInstances(class_name): lib_common.ErrorMessageHtml( "Too many elements in class_name=%s\n" % class_name) try: lst_obj = wmi_class() except Exception as exc: lib_common.ErrorMessageHtml("Caught when getting list of %s\n" % class_name) num_lst_obj = len(lst_obj) logging.debug("class_name=%s type(wmi_class)=%s len=%d", class_name, str(type(wmi_class)), num_lst_obj) if num_lst_obj == 0: grph.add((root_node, pc.property_information, lib_util.NodeLiteral("No instances in this class"))) for wmi_obj in lst_obj: # Full natural path: We must try to merge it with WBEM Uris. # '\\\\MYMACHINE\\root\\cimv2:Win32_Process.Handle="0"' # https://jdd:[email protected]:5959/cimv2:Win32_SoftwareFeature.Name="Havana",ProductName="Havana",Version="1.0" try: full_pth = str(wmi_obj.path()) except UnicodeEncodeError as exc: # UnicodeEncodeError: 'ascii' codec can't encode characters in position 104-108: ordinal not in range(128) logging.warning("Exception %s", str(exc)) continue if full_pth == "": logging.warning("Empty path wmi_obj=%s", str(wmi_obj)) # The class Win32_PnPSignedDriver (Maybe others) generates dozens of these messages. # This is not really an issue as this class should be hidden from applications. # logging.warning Empty path wmi_obj= # instance of Win32_PnPSignedDriver # { # ClassGuid = NULL; # CompatID = NULL; # Description = NULL; # DeviceClass = "LEGACYDRIVER"; # DeviceID = "ROOT\\LEGACY_LSI_FC\\0000"; # DeviceName = "LSI_FC"; # DevLoader = NULL; # DriverName = NULL; # DriverProviderName = NULL; # DriverVersion = NULL; # FriendlyName = NULL; # HardWareID = NULL; # InfName = NULL; # Location = NULL; # Manufacturer = NULL; # PDO = NULL; # }; continue # full_pth=\\MYMACHINE\root\CIMV2:Win32_SoundDevice.DeviceID="HDAUDIO\\FUNC_01&VEN_10EC&DEV_0221&SUBSYS_103C18E9&REV_1000\\4&3BC582&0&0001" full_pth = full_pth.replace("&", "&") wmi_instance_url = lib_util.EntityUrlFromMoniker(full_pth) logging.debug("wmi_instance_url=%s", wmi_instance_url) wmi_instance_node = lib_common.NodeUrl(wmi_instance_url) grph.add( (root_node, pc.property_class_instance, wmi_instance_node)) # TODO: On pourrait rassembler par classes, et aussi afficher les liens d'heritages des classes. cgiEnv.OutCgiRdf("LAYOUT_RECT", [pc.property_class_instance])