4.1 Querying the Private Properties of Resources

This example shows a client that is retrieving from a server the "Address" private property of a resource whose resource type is "IP Address". Although the example PROPERTY_LIST contains one property, a server can return additional properties. The property "Address" will have a string value of "10.1.2.3". The following diagram represents the example PROPERTY_LIST.

The property with name "Address" can be located anywhere in the PROPERTY_LIST. It can be preceded by zero or more properties in the PROPERTY_LIST, and it can have zero or more properties after it. In this example, "Address" is the first property in the list.

Organization of a PROPERTY_LIST structure

Figure 5: Organization of a PROPERTY_LIST structure

The following steps describe connecting to a cluster, opening a cluster resource , determining the size of the private PROPERTY_LIST, getting the private PROPERTY_LIST from the resource, and parsing the PROPERTY_LIST into its name/value pairs. The following diagram depicts the message flow.

Message flow: Obtaining PROPERTY_LIST

Figure 6: Message flow: Obtaining PROPERTY_LIST

First, a client initializes an RPC connection to the cluster, as specified in section 3.2.3. Any implementation-specific method can be used to locate the cluster.

Next, the client calls ApiCreateEnum (section 3.1.4.1.8 for protocol version 2, or 3.1.4.2.8 for protocol version 3) and specifies the enumeration type CLUSTER_ENUM_RESOURCE (also specified in ApiCreateEnum). The server returns an ENUM_LIST (section 2.2.3.5) containing an ENUM_ENTRY (section 2.2.3.4) for each resource in the cluster state.

For each entry in the ENUM_ENTRY, the client calls ApiOpenResource (section 3.1.4.1.9 for protocol version 2, or 3.1.4.2.9 for protocol version 3) providing the ENUM_ENTRY Name buffer as the resource name parameter. This ApiOpenResource call obtains an HRES_RPC context handle to the resource that is represented by the ENUM_ENTRY.

The client then calls ApiGetResourceType (section 3.1.4.1.16 for protocol version 2, or 3.1.4.2.16 for protocol version 3) on the HRES_RPC context handle. The returned buffer contains the resource's resource type name as a null-terminated Unicode string.

Next, because the client is searching for a resource that has the type name "IP Address", the client performs a case-insensitive comparison of the returned resource type string to the null-terminated Unicode string "IP Address".

When a resource type name match is found, the client calls ApiResourceControl (section 3.1.4.1.74 for protocol version 2, or 3.1.4.2.74 for protocol version 3) passing the control code CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES (0x001000081), as specified in section 3.1.4.3.1.17. The client sets the output buffer lpOutBuffer to a non-null pointer and sets the nOutputBuffer parameter to 0.

The server returns ERROR_MORE_DATA (234) and returns the size, in bytes, that is required for the output buffer by means of the lpcbRequired parameter.

The client allocates an output buffer of the prescribed size and calls ApiResourceControl again; this time the client specifies control code CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES (0x001000081), the allocated buffer, and the prescribed buffer size.

The server returns a status code of ERROR_SUCCESS and writes the private properties of the resource into the buffer that is indicated by lpOutBuffer. The format of the buffer is a PROPERTY_LIST (section 2.2.3.10).

The client now parses the PROPERTY_LIST to extract the value that is associated with the "Address" property. The client follows these steps:

  1. Reads the first 4 bytes of the output buffer. These 4 bytes contain the count of properties in the PROPERTY_LIST. For this example, the count is 0xb.

  2. Advances the pointer 4 bytes to get to the syntax for the property name of the first property.

  3. Reads the next 4 bytes of the buffer. The value is 0x00040003 (CLUSPROP_SYNTAX_NAME).

  4. Advances the pointer 4 bytes to get to the length of the property name.

  5. Reads the next 4 bytes in the buffer. The value is 16: the length of the Unicode string "Address" plus the terminating Unicode null character. No additional padding needs to be added to the 16-byte buffer to attain 4-byte alignment.

  6. Advances the pointer 4 bytes to get to the name buffer. The pointer is now pointing to the beginning of the property name.

  7. Performs a case-insensitive string comparison of the property name to the Unicode string "Address". In this example, the property name matches.

  8. Advances the pointer 16 bytes to get past the property name and to the syntax of its value.

  9. Reads the next 4 bytes. The value is 0x00010003 (CLUSPROP_SYNTAX_LIST_VALUE_SZ), indicating that the property value buffer contains data that is a null-terminated Unicode string.

  10. Advances the pointer 4 bytes to get to the length of the value buffer.

  11. Reads the next 4 bytes. The value is 20, the length of the string "10.1.2.3" plus the terminating null character, plus 2 bytes of padding to attain 4-byte alignment.

  12. Advances the pointer 4 bytes to get to the value buffer. The pointer is now at the beginning of a null-terminated string that is the value for this property.

  13. The client reads that address string ("10.1.2.3") and performs whatever client-specific operations were intended for that address.

  14. Advances the pointer 20 bytes to get past the value buffer and to the end mark syntax.

  15. Reads the next 4 bytes. The value is 0x00000000 (CLUSPROP_SYNTAX_ENDMARK) because it is the end of the value list for the first property.

  16. Advances the pointer 4 bytes. If there are additional properties in the list (indicated by the property count obtained in step 1), the pointer points to the CLUSPROP_SYNTAX_NAME enumeration of the next property in the PROPERTY_LIST. If there are no more properties, the pointer points to the end of the buffer.

The client now calls ApiCloseResource (section 3.1.4.1.12 for protocol version 2, or 3.1.4.2.12 for protocol version 3) to close the HRES_RPC context handle that represents the resource.

After the client is finished processing the enumeration, the client can free the ENUM_LIST. The client then closes the RPC connection to the server.