Previous page

Next page

Obtaining Server Handle and Logging In

The following steps are required in any program using the Parallels C API:

  1. Load the Parallels Virtualization SDK library using the SdkWrap_Load function.
  2. Initialize the API using the PrlApi_InitEx function. The API must be initialized properly for the given Parallels product, such as Parallels Server, Parallels Desktop. The initialization mode is determined by the value of the nAppMode parameter passed to the PrlApi_InitEx  function. The value must be one of the enumerators from the PRL_APPLICATION_MODE enumeration.
  3. Create a server handle using the PrlSrv_Create function.
  4. Call PrlSrv_LoginLocal or PrlSrv_Login to login to the Parallels Virtualization Service (or simply Parallels Service). Parallels Service is a combination of processes running on the host machine that comprise the Parallels virtualization product. The first function is used when the program and the target Parallels Service are running on the same host. The second function (PrlSrv_Login) is used to log in to a remote Parallels Service. Please note that remote login is supported in Parallels Server-based virtualization products only.

If the above steps are executed without errors, the handle created in step 3 will reference a Server object (a handle of type PHT_SERVER) identifying the Parallels Service. A handle to a valid Server object is required to access most of the functionality within the Parallels C API. The PrlSrv_LoginLocal function (step 4) establishes a connection with a specified Parallels Service and performs a login operation using the specified credentials. The function operates on the Server object created in step 3. Upon successful login, the object can be used to perform other operations.

To end the session with the Parallels Service, the following steps must be performed before exiting the application:

  1. Call PrlSrv_Logoff to log off the Parallels Service.
  2. Free the Server handle using PrlHandle_Free.
  3. Call PrlApi_Deinit to de-initialize the library.
  4. Call SdkWrap_Unload to unload the API.

Example

The following sample functions demonstrates how to perform the steps described above.

// Intializes the SDK library and

// logs in to the local Parallels Service.

// Obtains a handle of type PHT_SERVER identifying

// the Parallels Service.

  

PRL_RESULT LoginLocal(PRL_HANDLE &hServer)

{

    // Variables for handles.

    PRL_HANDLE hJob = PRL_INVALID_HANDLE; // job handle

    PRL_HANDLE hJobResult = PRL_INVALID_HANDLE; // job result

    

    // Variables for return codes.

    PRL_RESULT err = PRL_ERR_UNINITIALIZED;

    PRL_RESULT nJobReturnCode = PRL_ERR_UNINITIALIZED;

    

    // Use the correct dynamic library depending on the platform.

    #ifdef _WIN_

    #define SDK_LIB_NAME "prl_sdk.dll"

    #elif defined(_LIN_)

    #define SDK_LIB_NAME "libprl_sdk.so"

    #elif defined(_MAC_)

    #define SDK_LIB_NAME "libprl_sdk.dylib"

    #endif

    

    // Load SDK library.

    if (PRL_FAILED(SdkWrap_Load(SDK_LIB_NAME)) &&

        PRL_FAILED(SdkWrap_Load("./" SDK_LIB_NAME)))

    {

        fprintf( stderr, "Failed to load " SDK_LIB_NAME "\n" );

        return -1;

    }

    

    // Initialize the API. In this example, we are initializing the

    // API for Parallels Desktop.

    // To initialize in the Parallels Desktop mode, pass PAM_DESKTOP

    // as the second parameter.

    // To initialize for Parallels Server, pass PAM_SERVER.

    // See the PRL_APPLICATION_MODE enumeration for all possible options.

    //

    err = PrlApi_InitEx(PARALLELS_API_VER, PAM_WORKSTATION, 0, 0);

  

    if (PRL_FAILED(err))

    {

        fprintf(stderr, "PrlApi_InitEx returned with error: %s.\n",

            prl_result_to_string(err));

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

    

    // Create a server handle (PHT_SERVER).

    err = PrlSrv_Create(&hServer);

    if (PRL_FAILED(err))

    {

        fprintf(stderr, "PrlSvr_Create failed, error: %s",

            prl_result_to_string(err));

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

    

    // Log in (asynchronous call).

    hJob = PrlSrv_LoginLocal(hServer, NULL, NULL, PSL_NORMAL_SECURITY);

    

    // Wait for a maximum of 10 seconds for

    // the job to complete.

    err = PrlJob_Wait(hJob, 1000);

    if (PRL_FAILED(err))

    {

        fprintf(stderr,

            "PrlJob_Wait for PrlSrv_Login returned with error: %s\n",

            prl_result_to_string(err));

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

    

    // Analyze the result of PrlSrv_Login.

    err = PrlJob_GetRetCode(hJob, &nJobReturnCode);

    

    // First, check PrlJob_GetRetCode success/failure.

    if (PRL_FAILED(err))

    {

        fprintf(stderr, "PrlJob_GetRetCode returned with error: %s\n",

            prl_result_to_string(err));

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

    

    // Now check the Login operation success/failure.

    if (PRL_FAILED(nJobReturnCode))

    {

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        printf("Login job returned with error: %s\n",

            prl_result_to_string(nJobReturnCode));

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

    else

    {

        printf( "Login was successful.\n" );

    }

  

    return 0;

}

  

  

// Log off the Parallels Service and

// deinitializes the SDK library.

//

PRL_RESULT LogOff(PRL_HANDLE &hServer)

{

    PRL_HANDLE hJob = PRL_INVALID_HANDLE;

    PRL_HANDLE hJobResult = PRL_INVALID_HANDLE;

    

    PRL_RESULT err = PRL_ERR_UNINITIALIZED;

    PRL_RESULT nJobReturnCode = PRL_ERR_UNINITIALIZED;    

  

    // Log off.

    hJob = PrlSrv_Logoff(hServer);

    err = PrlJob_Wait(hJob, 1000);

    if (PRL_FAILED(err))

    {

        fprintf(stderr, "PrlJob_Wait for PrlSrv_Logoff returned error: %s\n",

            prl_result_to_string(err));

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

    

    // Get the Logoff operation return code.

    err = PrlJob_GetRetCode(hJob, &nJobReturnCode);

    

    // Check the PrlJob_GetRetCode success/failure.

    if (PRL_FAILED(err))

    {

        fprintf(stderr, "PrlJob_GetRetCode failed for PrlSrv_Logoff with error: %s\n",

            prl_result_to_string(err));

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

    

    // Report success or failure of PrlSrv_Logoff.

    if (PRL_FAILED(nJobReturnCode))

    {

        fprintf(stderr, "PrlSrv_Logoff failed with error: %s\n",

            prl_result_to_string(nJobReturnCode));

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

    else

    {

        printf( "Logoff was successful.\n" );

    }

    

    // Free handles that are no longer required.

    PrlHandle_Free(hJob);

    PrlHandle_Free(hServer);

    

    // De-initialize the Parallels API, and unload the SDK.

    PrlApi_Deinit();

    SdkWrap_Unload();

  

    return 0;

}