PRL_RESULT ConnectToConsole( PRL_HANDLE vm ) {

  PRL_RESULT err, nJobReturnCode = PRL_ERR_UNINITIALIZED;
  PRL_HANDLE hJob = PrlDevDisplay_ConnectToVm( vm, PDCT_LOW_QUALITY_WITHOUT_COMPRESSION );
  err = PrlJob_Wait(hJob, 10000);
  if (PRL_FAILED(err)) {
      fprintf(stderr, "PrlJob_Wait for PrlDevDisplay_ConnectToVm returned with error: %s\n",
      prl_result_to_string(err));
      PrlHandle_Free(hJob);
      return err;
  }
  err = PrlJob_GetRetCode(hJob, &nJobReturnCode);
  if (PRL_FAILED(err)) {
      fprintf(stderr, "PrlJob_GetRetCode returned with error: %s\n", prl_result_to_string(err));
      PrlHandle_Free(hJob);
      return err;
  }
  if (PRL_FAILED(nJobReturnCode)) {
      fprintf(stderr, "PrlDevDisplay_ConnectToVm returned with error: %s\n", prl_result_to_string(nJobReturnCode));
      PrlHandle_Free(hJob);
      return nJobReturnCode;
  }

  return PRL_ERR_SUCCESS;
}
bool SimpleServerWrapper::Login(char *sUserLogin, bool bUseNonInteractiveMode)
{
	SdkHandleWrap hJob;
	PRL_UINT32 nFlags = bUseNonInteractiveMode
		? PACF_NON_INTERACTIVE_MODE
		: 0;
	if (sUserLogin)
	{
		hJob.reset(PrlSrv_LoginEx(m_ServerHandle, TestConfig::getRemoteHostName(),	sUserLogin,
								TestConfig::getUserPassword(), NULL, 0, 0, PSL_HIGH_SECURITY, nFlags));
	}
	else
	{
		hJob.reset(PrlSrv_LoginLocalEx(m_ServerHandle, NULL, 0, PSL_HIGH_SECURITY, nFlags));
	}

	if (PRL_SUCCEEDED(PrlJob_Wait(hJob, PRL_JOB_WAIT_TIMEOUT)))
	{
		PRL_RESULT nRetCode;
		if (PRL_SUCCEEDED(PrlJob_GetRetCode(hJob, &nRetCode)))
		{
			if (!PRL_SUCCEEDED(nRetCode))
				WRITE_TRACE(DBG_FATAL, "Failed to login to server");
			else
				return (true);
		}
		else
			WRITE_TRACE(DBG_FATAL, "Failed to get job return code");
	}
	else
		WRITE_TRACE(DBG_FATAL, "Failed to wait server login async job");

	return (false);
}
void PrlNetworkShapingTest::cleanup()
{

	DestroyVm();
	RestoreNetworkClassesConfig();

	m_hJob.reset(PrlSrv_Logoff(m_hServer));
	PrlJob_Wait(m_hJob, PRL_JOB_WAIT_TIMEOUT);
}
void PrlApiTest::cleanup()
{
	if (m_JobHandle)
	{
		m_JobHandle.reset(PrlSrv_Logoff(m_Handle));
		PrlJob_Wait(m_JobHandle, PRL_JOB_WAIT_TIMEOUT);
	}
	m_Handle.reset();
	m_JobHandle.reset();
}
PRL_RESULT LoginLocal(PRL_HANDLE &hServer) {

    PRL_HANDLE hJob, hJobResult = PRL_INVALID_HANDLE;
    PRL_RESULT err, nJobReturnCode = PRL_ERR_UNINITIALIZED;

    err = PrlApi_InitEx(PARALLELS_API_VER, PAM_DESKTOP, 0, 0);
    if (PRL_FAILED(err)) {
        fprintf(stderr, "PrlApi_InitEx returned with error: %s.\n", prl_result_to_string(err));
        PrlApi_Deinit();
        return err;
    }
    err = PrlSrv_Create(&hServer);
    if (PRL_FAILED(err)) {
        fprintf(stderr, "PrlSvr_Create failed, error: %s", prl_result_to_string(err));
        PrlApi_Deinit();
        return err;
    }
    hJob = PrlSrv_LoginLocal(hServer, NULL, NULL, PSL_NORMAL_SECURITY);
    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();
        return err;
    }
    err = PrlJob_GetRetCode(hJob, &nJobReturnCode);
    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();
        return err;
    }
    if (PRL_FAILED(nJobReturnCode)) {
        PrlHandle_Free(hJob);
        PrlHandle_Free(hServer);
        fprintf(stderr, "Login job returned with error: %s\n", prl_result_to_string(nJobReturnCode));
        PrlHandle_Free(hJob);
        PrlHandle_Free(hServer);
        PrlApi_Deinit();
        return err;
    }
    return PRL_ERR_SUCCESS;
}
bool SimpleServerWrapper::Logoff()
{
	m_isLocalAdminInited = false;

	SdkHandleWrap hJob(PrlSrv_Logoff(m_ServerHandle));
	if (PRL_SUCCEEDED(PrlJob_Wait(hJob, PRL_JOB_WAIT_TIMEOUT)))
	{
		PRL_RESULT nRetCode = PRL_ERR_UNINITIALIZED;
		if (PRL_SUCCEEDED(PrlJob_GetRetCode(hJob, &nRetCode)))
		{
			if (PRL_SUCCEEDED(nRetCode))
				return (true);
			else
				WRITE_TRACE(DBG_FATAL, "Logoff operation failed with retcode: 0x%.8X '%s'",\
					nRetCode, PRL_RESULT_TO_STRING(nRetCode));
		}
		else
			WRITE_TRACE(DBG_FATAL, "Failed to extract return code from the job object");
	}
	else
		WRITE_TRACE(DBG_FATAL, "Failed to wait logoff job");

	return (false);
}
void PrlNetworkShapingTest::DestroyVm()
{
	SdkHandleWrap hJob(PrlVm_Delete(m_hVm, PRL_INVALID_HANDLE));
	PrlJob_Wait(hJob, PRL_JOB_WAIT_TIMEOUT);
}
        PrlHandle_Free(hJob);
        PrlHandle_Free(hServer);
        PrlApi_Deinit();
        return err;
    }
    return PRL_ERR_SUCCESS;
}

PRL_RESULT LogOff(PRL_HANDLE &hServer) {
    PRL_HANDLE hJob, hJobResult = PRL_INVALID_HANDLE;
    PRL_RESULT err, nJobReturnCode = PRL_ERR_UNINITIALIZED;

    nanosleep((struct timespec[]){{1, 100000000}}, NULL);

    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();
        return err;
     }
    err = PrlJob_GetRetCode(hJob, &nJobReturnCode);
    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();
        return err;
    }