Previous page

Next page

Print this page

Obtaining Server Handle and Logging In

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

  1. Load the Parallels Virtualization SDK library using the SdkWrap_Load function.
  2. Initialize the API using the PrlApi_Init function.
  3. Create a server handle using the PrlSrv_Create function.
  4. Call PrlSrv_Login (or PrlSrv_LoginLocal) with valid login credentials.

If these steps are executed without errors, the handle created in step 3 will reference a server object (the handle type will be PHT_SERVER) identifying the Parallels Service . Parallels Service is a combination of processes running on the host machine that make programmatic access to a Parallels virtualization product possible (the names "server object" and "server handle" are a legacy terms).  A handle to a valid server object is required to access most of the functionality within the Parallels C API. The PrlSrv_Login function (step 4) establishes a connection with a specified Parallels Service and performs a login operation using 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 a Parallels Service, the following steps must be performed before existing an 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.

C API Sample

The following is a complete sample program that demonstrates how to perform the steps described above. Before compiling and running the program on your machine, substitute the hard-coded IP address, user name, and password values with the ones appropriate to your setup. The PrlSrv_Login function is used for both local and remote login operations. To login to a Parallels Service running on the local host, use 127.0.0.1 or localhost as the host parameter. The rest of the code can be left unchanged. Please note that if you are using the API to access Parallels Desktop, you can use the local login only.

#include "Parallels.h"

#include "Wrappers/SdkWrap/SdkWrap.h"

#include <stdio.h>

#include <stdlib.h>

//////////////////////////////////////////////////////////////////////

#ifdef _WIN_

#include <windows.h>

#else

#include <unistd.h>

#endif

//////////////////////////////////////////////////////////////////////

int main(int argc, char* argv[])

{

// Variables for handles.

PRL_HANDLE hJob = PRL_INVALID_HANDLE; // job handle

PRL_HANDLE hJobResult = PRL_INVALID_HANDLE; // job result

PRL_HANDLE hServer = PRL_INVALID_HANDLE;    // server handle

// Variables for return codes.

PRL_RESULT ret = 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. By default, the API will be initialized

// in the Parallels-Server mode. To initialize in the Parallels-Desktop mode, use

// the PrlApi_InitEx function passing the appropriate parameter.

ret = PrlApi_Init(PARALLELS_API_VER);

if (PRL_FAILED(ret))

{

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

prl_result_to_string(ret));

PrlApi_Deinit();

SdkWrap_Unload();

return ret;

}

// Create a server handle (PHT_SERVER).

ret = PrlSrv_Create(&hServer);

if (PRL_FAILED(ret))

{

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

prl_result_to_string(ret));

PrlHandle_Free(hServer);

PrlApi_Deinit();

SdkWrap_Unload();

return -1;

}

// Log in (asynchronous call).

// Substitute the IP address, name, and password

// with your own.

hJob = PrlSrv_Login(

hServer,        // Server handle

"10.30.22.159", // Host IP address

"jdoe",         // User name

"secret",       // Password

0,              // Previous session ID

0,              // Port number

0,              // Timeout

PSL_NORMAL_SECURITY); // Security level.

// The minimum allowable security

// level can be determined using

// PrlDispCfg_GetMinSecurityLevel.

// Wait for a maximum of 10 seconds for

// the job to complete.

ret = PrlJob_Wait(hJob, 1000);

if (PRL_FAILED(ret))

{

fprintf(stderr,

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

prl_result_to_string(ret));

PrlHandle_Free(hJob);

PrlHandle_Free(hServer);

PrlApi_Deinit();

SdkWrap_Unload();

return -1;

}

// Analyze the result of PrlSrv_Login.

ret = PrlJob_GetRetCode(hJob, &nJobReturnCode);

// First, check PrlJob_GetRetCode success/failure.

if (PRL_FAILED(ret))

{

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

prl_result_to_string(ret));

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" );

}

/****************************************************

*

*  To test sample functions provided in this guide,

*  call them from here. Higher level functions take a

*  server handle as a parameter. Pass the hServer

*  variable (the server handle that we obtain earlier

*  in the program).

*

****************************************************/

// Log off.

hJob = PrlSrv_Logoff(hServer);

ret = PrlJob_Wait(hJob, 1000);

if (PRL_FAILED(ret))

{

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

prl_result_to_string(ret));

PrlHandle_Free(hJob);

PrlHandle_Free(hServer);

PrlApi_Deinit();

SdkWrap_Unload();

return -1;

}

// Get the Logoff operation return code.

ret = PrlJob_GetRetCode(hJob, &nJobReturnCode);

// Check the PrlJob_GetRetCode success/failure.

if (PRL_FAILED(ret))

{

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

prl_result_to_string(ret));

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();

printf( "\n\nEnd of program.\n\n" );

// Wait for user to press a key...

char c;

scanf( &c, "%c" );

return 0;

}

Please send us your feedback on this help page