4.4 Registration

Registration

Figure 9: Registration

The preceding figure shows the sequence for a COMA client that attempts registration of a component on a COMA server, on behalf of a client application. The client has already performed session and capability negotiation, as shown in example 4.1. It is assumed that the COMA server has a partition {41e90f3e-56c1-4633-81c3-6e8bac8bdd70} with conglomeration {3fe02b83-6551-410b-a58a-b231fd7c0c2e}. It is also assumed that the client knows about the partition and the conglomeration on the COMA server by means of a query on a COMA server or by some other way. It is also assumed that the module file path is something that a COMA client acquired beforehand by its own custom means. For example, the client application might be an administrative tool, and an administrative user provided the path when requesting registration.

  • The client calls IRegister2::RegisterModule2 (section 3.1.4.11.4) as follows:

    • The client sets the ConglomerationIdentifier and the PartitionIdentifier parameters to specify the conglomeration of the component belonging to the module.

    • The client passes in an array of string to specify the path of the module for the COMA server in ppModules. Since in this case there is only one module, the client puts it in an array of 1 element. It sets cModules to 1.

    • No special flags are needed for this registration. Thus the client sets dwFlags to 0.

    • The client wants to register all the components in the module, so it does not specify any requested CLSIDs using the pRequestedCLSID and cRequested parameter.

    • The client passes in buffers for the rest of the parameters to receive data from the server.

      The client initiates the call.

     HRESULT RegisterModule2(
       [in] GUID ConglomerationIdentifier = {
                                    3fe02b83-6551-410b-a58a-b231fd7c0c2e},
       [in] GUID PartitionIdentifier = {
                                    41e90f3e-56c1-4633-81c3-6e8bac8bdd70},
       [in, string, size_is(cModules,)] LPWSTR* ppModules = 
                                    {"SomeModule.dll"},
       [in] DWORD cModules = 0x0000001,
       [in] DWORD dwFlags = 0x00000000,
       [in, size_is(cRequested), unique] GUID* pRequestedCLSIDs = NULL,
       [in] DWORD cRequested = 0x00000000,
       [out, size_is(,cModules)] DWORD** ppModuleFlags = {Pointer to 
                          uninitialized memory to hold a pointer to an 
                          array of Module Flags},
       [out] DWORD* pcResults = {Pointer to uninitialized memory to hold the 
                                    count of 
                         components registered},
       [out, size_is(,*pcResults)] GUID** ppResultCLSIDs = {Pointer to 
                         uninitialized memory to hold an array of CLSIDs of
                         the registered components},
       [out, string, size_is(,*pcResults)] LPWSTR** ppResultNames = {
                         Pointer to uninitialized memory to hold an array of
                         names of the registered components},
       [out, size_is(,*pcResults)] DWORD** ppResultFlags = {Pointer to 
                         uninitialized memory to hold an array of 
                         implementation-specific flags 
                         relating to the  registered components},
       [out, size_is(,*pcResults)] LONG** ppResultHRs = {Pointer to 
                         uninitialized memory to hold an array of HRESULT 
                         for registration success or failure of the 
     components}
     );
      
    

    The server receives the call and performs the following validation steps:

    • It validates that both the conglomeration and the partition exist, and that the conglomeration specified is associated with the partition.

    • It verifies that the path to the modules given is valid and that they are compatible with the COMA server implementation.

  • The server then proceeds with the registration process as follows:

    • It creates the entry for the components in the module in the component full configuration table.

    • It creates entries for the interfaces for each component in the module into the interfaces table.

    • It makes entries for each of the methods in the interfaces to the methods table.

  • The server populates the ppModule flags to fMODULE_LOADED as the module was successfully loaded by it.

  • The server then gathers the CLSID, names of the components, implementation-specific settings associated with the components, and the individual HRESULT associated with their registration. It populates these values into ppRequestCLSIDs, ppResultNames, ppResultFlags, and ppResultHRs arrays.

  • The server returns S_OK.

     HRESULT = S_OK
     RegisterModule2(
       [in] GUID ConglomerationIdentifier = {unchanged},
       [in] GUID PartitionIdentifier = {unchanged},
       [in, string, size_is(cModules,)] LPWSTR* ppModules = {unchanged},
       [in] DWORD cModules = {unchanged},
       [in] DWORD dwFlags = {unchanged},
       [in, size_is(cRequested), unique] GUID* pRequestedCLSIDs = {
                         unchanged},
       [in] DWORD cRequested = {unchanged},
       [out, size_is(,cModules)] DWORD** ppModuleFlags = {fMODULE_LOADED},
       [out] DWORD* pcResults = 0x00000001,
       [out, size_is(,*pcResults)] GUID** ppResultCLSIDs = {{
                         463575e4-a992-11d2-a8e2-0000f805c6d2}},
       [out, string, size_is(,*pcResults)] LPWSTR** ppResultNames ={
                         "SomeComponent"} ,
       [out, size_is(,*pcResults)] DWORD** ppResultFlags = {
                         Implementation-specific flag},
       [out, size_is(,*pcResults)] LONG** ppResultHRs = {{S_OK}}
     );
      
    
  • The client, on successful completion of the call, now calls ICatalogUtils::WaitForEndWrites (section 3.1.4.17.2)).

  • The server receives the call and ensures that all pending writes on its store are completed. If all goes well, which it does in this case, the server returns S_OK.