Modifying Existing Classes
If you wish to modify existing classes within the CIM schema or Win32 extended schema, you must obtain permission first from the schema designer. Situations in which you must obtain permission include the addition of a method or property to an existing class or the addition of a completely new class or association. If you decide to populate Microsoft's CIMV2 namespace with your own classes, then you must be careful to obtain permission in case any of your additional classes conflict with the designer's plans for the namespace.
Managed Object Format
Beyond the CIM and extended schemas, we look further at the structure of classes, properties, methods, and associations, initially through examples written in the MOF defined by the DMTF. Later in this chapter, we shall use Microsoft's WMI CIM Studio to explore and modify the CIM repository.
We use the MOF language to define object definitions within the CIM in a textual format. As we shall see in the WMI CIM Studio, MOF is not the only way to modify the CIM repository, but it is beneficial to have some knowledge of the MOF syntax and its semantics. MOF provides a basic understanding of the terminology you will encounter when you use Microsoft's WMI CIM Studio to move through the CIM repository. In addition, it provides you with a concept of the structures that make up the CIM.
MOF files can populate technologies that implement the CIM. In other words, a MOF file exported from a Windows XP/.NET WMI installation theoretically would compile on a UNIX implementation of the CIM. Although this is the DMTF's intention, currently various minor differences exist between Microsoft's and the DMTF's interpretation of the language. In reality, you may have to modify certain elements of the MOF file to remove Microsoft-specific qualifiers to export to non-Microsoft platforms.
To add classes, instances, or associations to the CIM repository, you first must specify the destination namespace of the objects that you wish to add. If you do not specify a destination namespace, WMI will place all entries in the root/default namespace in the CIM repository. You have several options for specifying a destination namespace. First, you can specify a namespace as a command-line switch for the MOF comp executable by using the N switch. This approach is limited, because you can specify only a single destination namespace for the entire MOF file. Second, you can specify the namespace as part of the MOF file. This option will override all others. To do this use, the #pragma namespace compiler directive that follows:
#pragma namespace (destination namespace)
In the next example, any classes, instances, or associations that follow this statement will be destined for the local CIMV2 namespace.
The MOF includes various compiler directives that allow developers to set conditions that affect the compilation process. Compiler directives include locale, source, nonlocal, include, and instancelocale.
#pragma locale(language_country) The locale directive tells the compiler which language and country settings the MOF file will use. Remember that all MOF keywords (such as "class," "instance," and "association") are always listed in English. When not specified, the default value is en_US (language = english and country = United States).
#pragma source(<namespace type>://<namespace_handle>) Tells the compiler on which CIM implementation to locate the metadata that follows. You can use this pragma on class instances or association instances. You also can use the source qualifier on individual class and association instances.
#pragma nonlocal(<namespace type>://<namespace_handle>) Tells the compiler to reference an object instance in another CIM implementation. This allows the CIM to share management information between machines and to allow enterprise-wide identification of objects. With this compiler directive, we can identify objects located on a machine across the network from the current host machine. For instance, while compiling on host machine A, we could reference an object instance held on a CIM-compliant repository on machine B on a different part of the network (that is, #pragma nonlocal("namespacetype://namespace_handle")). #pragma include("another.mof") Tells the compiler to insert the contents of the MOF file given as a parameter into the current MOF file from this point onward. #pragma instancelocale() Tells the compiler to use the locale that follows the directive for instances declared in the MOF file. This, in effect, means that instances within the MOF file can have a different locale from that declared for classes. We shall cover how to declare instances using MOF later in this chapter.
You compile class definitions into the CIM repository.
You import instance information into the CIM repository.
MOF Class Declaration
Declaring a class using MOF syntax is quite simple and not dissimilar from using C++. In Figure 4.6, we declare a fictitious class that represents some of the attributes of a CD-ROM drive. For the sake of simplicity, we do not derive this class from any classes within the CIM schema or Win32 extended schema.
Figure 4.6 A MOF class declaration
The class name is the domain of the properties or methods that it contains. In Figure 4.6, the property DeviceId has a domain of class Storage and the property Model has the domain of MySchema_CDROM. In the case of associations, which we discuss shortly, each reference has a range. The range refers to the class to which the reference points.
All keywords in MOF are case INSENSITIVE
In Figure 4.6, we declared the class CD_ROM as a subclass of class Storage. To compile correctly, we must declare the class Storage before class CD_ROM.
We have declared four properties, ManufacturerName, Model, BIOSVersion, and ReadSpeed, as part of the class. Property names must not contain any spaces or underscores; otherwise, the compilation process will fail. Also observe that we used the // to place comments in the class declaration. The compilation process ignores these comments.
Qualifiers are the mechanism in MOF through which we can assign characteristics to any of the elements within a schema. These elements include methods, method parameters, properties, classes, and associations. A qualifier has the following components:
A name (that is, description, abstract, read, write, . . . )
An intrinsic data type (that is, real32, string, uint16, . . . )
A value of the corresponding type (that is, Manufacturer_Name could be assigned the value "Mitsubishi")
A scope, to determine whether the qualifier can be applied to classes, methods, properties, and associations
A flavor, to determine whether the qualifier can be inherited by subclasses or instances, or can be overridden
The DMTF defines a number of standard qualifiers for use when working with any schema (which are listed in the DMTF CIM Specification document). It is also possible to define your own qualifiers. Microsoft defines a number of custom qualifiers as part of their implementation of WMI. In Figure 4.7, we add default qualifiers and Microsoft-specific qualifiers to the class.
Figure 4.7 Example qualifiers
Figure 4.7 shows the qualifiers listed in bold type. Always arrange qualifiers in blocks that immediately precede the class, method, or property that they characterize, and always enclose the blocks in square brackets: [ ]. For example:
[ Description ("This is a legal qualifier block")]
The Description qualifier at the start of the class declaration in Figure 4.7 is the qualifier name and provides a simple text description of class MySchema_CDROM. You must enclose the text itself in curved brackets and straight (nondirectional) quotation marks. Later, applications can use this text to retrieve a description of the class from the CIM repository.