Share via


4.1 LSM Enumeration Example

The following example shows how to enumerate sessions on a terminal server. This example uses TermSrvBindSecure from section 4.3.

  1. Get the LSM Binding.

     HANDLE GetLSMBinding(LPWSTR pszServerName)
     {
       HANDLE hLSMBinding = NULL;
       RPC_STATUS rpcStatus = RPC_S_OK;
      
       //ASSERT( NULL != pszServerName );
       rpcStatus = TermSrvBindSecure(
         gpszPublicUuid,
         gpszRemoteProtocolSequence,
         pszServerName,
         TSRPC_REMOTE_ENDPOINT,
         gpszOptions,
         &hLSMBinding
         );
      
       if( rpcStatus != RPC_S_OK || hLSMBinding == NULL)
       {
         wprintf(L"ERR: TermSrvBindSecure failed: %d\n", 
                 rpcStatus );
         SetLastError( rpcStatus );
       }
      
       return hLSMBinding;
     }
      
    
  2. Enumerate the sessions.

     RpcTryExcept 
     {
       hr = RpcOpenEnum( hLSMBind, &hEnum );
       if(hr == S_OK)
       {
         hr = RpcGetEnumResult( hEnum, &pAllSessions, 
                         CURRENT_ENUM_LEVEL, &Entries );
         if(hr == S_OK)
         {
           for(ULONG i=0;i<Entries;i++)
           {
             wprintf(L"%-10d %-20s %-40s\n", 
               pAllSessions[i].Data.SessionEnum_Level3.SessionId, 
               WinstationStateClassNames[pAllSessions[i].Data.
                                         SessionEnum_Level3.State], 
               pAllSessions[i].Data.SessionEnum_Level3.Name);
      
               if( NULL != pAllSessions[i].Data.SessionEnum_Level3.
                           pProtocolData )
               {
                 MIDL_user_free( pAllSessions[i].Data.
                              SessionEnum_Level3.pProtocolData );                    
               }
           }
      
           rv1 = TRUE;
         }
         else
         {
           wprintf(L"ERR: RpcGetEnumResult failed %d\n",hr );
         }
      
         if ( pAllSessions )
         {
           MIDL_user_free(pAllSessions);
         }
      
       }
       else
       {
         wprintf(L"ERR: RpcOpenEnum failed %d\n",hr );
       }
      
     }
      
     RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) 
     {
       wprintf(L"ERR: RPC Exception %d\n",RpcExceptionCode() );
     }
      
     RpcEndExcept
             
      
      
    
  3. Close the handles.

     if(hEnum)
       RpcCloseEnum(&hEnum);
      
     if(hLSMBind)
       RpcBindingFree(&hLSMBind);
      
    

The following diagram illustrates the message sequence for enumerating the sessions.

LSM session enumeration sequence

Figure 1: LSM session enumeration sequence

The sequence of messages for enumerating sessions on the server is as follows:

  1. After an RPC binding has been established to the server, the client requests a session enumeration handle to be opened by the server by calling the RpcOpenEnum method.

  2. The server, in response, opens a handle of the type ENUM_HANDLE and returns to the client.

  3. The client then calls the RpcGetEnumResult method by passing this handle, along with an uninitialized buffer, to get the list of sessions.

  4. The server, on receiving the request, allocates memory for the buffer and fills it with an array of SESSIONENUM structures containing session information, one for each session on the server. It also returns the number of sessions on the server.

  5. The client, on receiving the data, calls the RpcCloseEnum method to inform the server to close the enumeration handle.

  6. The server, on receiving the RpcCloseEnum call, closes the enumeration handle.

  7. The client frees the array of SESSIONENUM structures it received before exiting.