Beispiel #1
0
void CScheduler::HangUpConnection()
{
	DWORD dwCb = sizeof( RASCONN );
	DWORD dwConnections = 0;
	RASCONN* lpRasConn = NULL;
	LPRASCONNSTATUS RasConStatus = 0;

	for (;;)
	{
		// Free the memory if necessary.
		if ( lpRasConn != NULL )
		{
			HeapFree( GetProcessHeap(), 0, lpRasConn );
			lpRasConn = NULL;
		}

		// Allocate the size needed for the RAS structure.
		lpRasConn = (RASCONN*)HeapAlloc( GetProcessHeap(), 0, dwCb );
		if ( ! lpRasConn )
			// Out of memory
			return;

		// Set the first structure size for version checking purposes.
		lpRasConn->dwSize = sizeof( RASCONN );

		// Call the RAS API 
		DWORD ret = RasEnumConnections( lpRasConn, &dwCb, &dwConnections );
		if ( ret == 0 )
			// Ok
			break;
		if ( ret == ERROR_NOT_ENOUGH_MEMORY )
			// Re-allocate more memory
			continue;
		// Error
		return;
	}

	DWORD loop = 0;
	for ( DWORD i = 0; i < dwConnections; ++i ) // Loop through all current connections
	{
		RasHangUp( lpRasConn[i].hrasconn ); // Hang up the connection
		while( ( RasGetConnectStatus( lpRasConn[i].hrasconn,RasConStatus ) || ( loop > 10 ) ) )
		{
			// Loop until the connection handle is invalid, or 3 seconds have passed
			Sleep( 300 );
			loop++;
		}
	}

	// Free the memory if necessary.
	if ( lpRasConn != NULL )
	{
		HeapFree( GetProcessHeap(), 0, lpRasConn );
		lpRasConn = NULL;
	}
}
void CWirelessManagerDlg::OnOK() 
{
	if (m_hRasConn != NULL)
	{
		RasHangUp(m_hRasConn);
		m_hRasConn = NULL;
	}
	
	CDialog::OnOK();
}
Beispiel #3
0
int hungup(LPCTSTR szEntry)
{
	if (ghRasConn != NULL)
	{
		RasHangUp(ghRasConn);
		Sleep(3000);
		ghRasConn = NULL;
	}
	RasDeleteEntry(NULL, szEntry);
	return 0;
}
void CWirelessManagerDlg::RasControl(DIAL_STYPE enStype)
{
	m_enDialStype = enStype;	//保存拨号类型
	switch(enStype)
	{
	case DIAL_TYPE_NONE:
		break;
	case enRAS_Dial://当前拨号状态为断开,
		if( m_RasState == RASCS_Disconnected)
		{
			DialRasNetwork();			
		}
		break;
	case enRAS_Hangup:
		{
			RasHangUp(m_hRasConn);
			m_hRasConn = NULL;
			KillTimer(TID_DISCONNECT);
			m_RasState = RASCS_Disconnected;

			HWND hwnd = ::FindWindow(NULL,WND_NAME_GSM_AT);
			::PostMessage(hwnd, WM_GSM_RESET, 0, 0);	
		}
		break;

	case enRAS_ReDial:
		if(m_RasState != RASCS_Disconnected)
		{
			RasHangUp(m_hRasConn);
			m_hRasConn = NULL;
			KillTimer(TID_DISCONNECT);
		}
		DialRasNetwork();

		break;
	}
}
//
// RasCustomHangUp
//
// This export is the custom dial entry when RasHangUp has been called by
// an application - the call is forwarded to here and it is up to this
// function then to close a connection. This implementation simply
// forwards the request back to RasHangUp.
//
extern "C" DWORD WINAPI RasCustomHangUp (
  HRASCONN hRasConn    // handle to a RAS connection
)
{
    DWORD rc = SUCCESS;     // return code


    OutputTraceString(L"RasCustomHangUp called in customdial.dll\n");  
    OutputTraceString(L"--- RasCustomHangUp on handle 0x%08x\n", hRasConn);

    // simply call RasHangUp on the handle
    rc = RasHangUp(hRasConn);

    OutputTraceString(L"RasCustomHangUp exiting customdial.dll with return code: %d\n", rc);

    return rc;
}
Beispiel #6
0
static void hangup ( HRASCONN hRasConn ) 
{
   int			i;
   RASCONNSTATUS	rasStatus;
   DWORD		st;

   if ( hRasConn == NULL )
      return;
   RasHangUp ( hRasConn );
   
   rasStatus.dwSize = sizeof(RASCONNSTATUS);
      
   for ( i = st = 0;
	 i < 6 && (i == 0 || st != ERROR_INVALID_HANDLE); i ++ ) 
   {
      Sleep ( 500 );
      st = RasGetConnectStatus ( hRasConn, &rasStatus );
   }

}
DWORD CWirelessManagerDlg::DialRasNetwork()
{
	
	//拨号之前先判断上次拨号的句柄是否已释放
	if (m_hRasConn != NULL)
	{
		RasHangUp(m_hRasConn);
		m_hRasConn = NULL;
	}


	if (m_dwReDialCnt > 5)
	{
		RasControl(enRAS_Hangup);
		m_dwReDialCnt = 0;
		return 0;
	}
	m_dwReDialCnt++;

	g_bIsDialing = TRUE;
	RASDIALPARAMS   RasDialParams;   //RAS结构包含用来建立RAS的参数   
	//下面开始初始化拨号参数
	memset((char*)&RasDialParams, 0, sizeof(RasDialParams));
	RasDialParams.dwSize   =   sizeof(RASDIALPARAMS);   //结构大小   
	wcscpy(RasDialParams.szEntryName, /*_T("cmnet")*/ENTRY_NAME);		//拨号网络中建立的电话簿名
	
   	wcscpy(RasDialParams.szPhoneNumber , _T(""));	//*99***#
    wcscpy(RasDialParams.szCallbackNumber,_T(""));   //回拨号码,不用时置为NULL   
    wcscpy(RasDialParams.szUserName,_T(""));   //用户名   
    wcscpy(RasDialParams.szPassword,_T(""));   //用户口令
	wcscpy(RasDialParams.szDomain,_T(""));   //用户权限验证域

	RASDIALPARAMS ras_para_test;
	memset(&ras_para_test, NULL, sizeof(RASDIALPARAMS));

	int nRasResult = RasDial(NULL, NULL, &RasDialParams, 0xFFFFFFFF, m_hWnd, &m_hRasConn);
	g_bIsDialing = FALSE;
	
	return nRasResult;
}
Beispiel #8
0
static DWORD ShutdownNow(BYTE shutdownType)
{
	DWORD dwErrCode = ERROR_SUCCESS;
	switch (shutdownType) {
	case SDSDT_CLOSEMIRANDA:
		if (!Miranda_Terminated()) {
			/* waiting for short until ready (but not too long...) */
			DWORD dwLastTickCount = GetTickCount();
			while (!CallService(MS_SYSTEM_OKTOEXIT, 0, 0)) {
				/* infinite loop protection (max 5 sec) */
				if (GetTickCount() - dwLastTickCount >= 5000) { /* wraparound works */
					OutputDebugStringA("Timeout (5 sec)\n"); /* tell others, all ascii */
					break;
				}
				SleepEx(1000, TRUE);
				if (Miranda_Terminated()) break; /* someone else did it */
				OutputDebugStringA("Not ready to exit. Waiting...\n"); /* tell others, all ascii */
			}
			/* shutdown service must be called from main thread anyway */
			if (!DestroyWindow(pcli->hwndContactList))
				dwErrCode = GetLastError();
		}
		break;

	case SDSDT_SETMIRANDAOFFLINE:
		/* set global status mode to offline (is remembered by Miranda on exit) */
		CallService(MS_CLIST_SETSTATUSMODE, (WPARAM)ID_STATUS_OFFLINE, 0);
		break;

	case SDSDT_STANDBY:
	case SDSDT_HIBERNATE:
		WinNT_SetPrivilege(SE_SHUTDOWN_NAME, TRUE);
		if (!SetSystemPowerState(shutdownType == SDSDT_STANDBY, TRUE))
			dwErrCode = GetLastError();
		WinNT_SetPrivilege(SE_SHUTDOWN_NAME, FALSE);
		break;

	case SDSDT_LOCKWORKSTATION:
		if (!IsWorkstationLocked())
			dwErrCode = GetLastError();
		break;

	case SDSDT_CLOSERASCONNECTIONS:
		ShutdownNow(SDSDT_SETMIRANDAOFFLINE); /* set Miranda offline */
		/* hang up all ras connections */
		{
			DWORD dwRetries;
			RASCONNSTATUS rcs;
			DWORD dw, dwLastTickCount;

			DWORD dwConnSize = sizeof(RASCONN);
			DWORD dwConnItems = 0;
			RASCONN *paConn = (RASCONN*)mir_alloc(dwConnSize);
			dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
			if (paConn != NULL) {
				for (dwRetries = 5; dwRetries != 0; dwRetries--) { /* prevent infinite loop (rare) */
					memset(paConn, 0, dwConnSize);
					paConn[0].dwSize = sizeof(RASCONN);
					dwErrCode = RasEnumConnections(paConn, &dwConnSize, &dwConnItems);
					if (dwErrCode != ERROR_BUFFER_TOO_SMALL) break;
					RASCONN *paConnBuf = (RASCONN*)mir_realloc(paConn, dwConnSize);
					if (paConnBuf == NULL) {
						mir_free(paConn);
						paConn = NULL;
						dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
						break;
					}
					paConn = paConnBuf;
				}
				if (dwErrCode == ERROR_SUCCESS || dwErrCode == ERROR_BUFFER_TOO_SMALL) {
					for (dw = 0; dw < dwConnItems; ++dw) {
						if (dwErrCode) {
							if (RasHangUp(paConn[dw].hrasconn))
								paConn[dw].hrasconn = NULL; /* do not wait for on error */
						}
						else {
							dwErrCode = RasHangUp(paConn[dw].hrasconn);
							if (!dwErrCode) paConn[dw].hrasconn = NULL; /* do not wait for on error */
						}
					}
					/* RAS does not allow to quit directly after HangUp (see docs) */
					dwLastTickCount = GetTickCount();
					memset(&rcs, 0, sizeof(RASCONNSTATUS));
					rcs.dwSize = sizeof(RASCONNSTATUS);
					for (dw = 0; dw < dwConnItems; ++dw) {
						if (paConn[dw].hrasconn != NULL) {
							while (RasGetConnectStatus(paConn[dw].hrasconn, &rcs) != ERROR_INVALID_HANDLE) {
								Sleep(0); /* give rest of time silce to other threads with equal priority */
								/* infinite loop protection (3000ms defined in docs) */
								dwRetries = GetTickCount();
								if (dwRetries - dwLastTickCount > 3000)
									break; /* wraparound works */
							}
						}
					}
				}
				mir_free(paConn); /* does NULL check */
			}
		}
		/* set Miranda to offline again, to remain offline with reconnection plugins */
		ShutdownNow(SDSDT_SETMIRANDAOFFLINE);
		break;

	case SDSDT_REBOOT:
	case SDSDT_SHUTDOWN:
		if (GetSystemMetrics(SM_SHUTTINGDOWN)) { /* Win2000+, 0 on error */
			dwErrCode = ERROR_SHUTDOWN_IN_PROGRESS;
			break;
		}
		/* WinNT4/2000/XP */
		{
			WinNT_SetPrivilege(SE_SHUTDOWN_NAME, TRUE);

			/* does not send out WM_ENDSESSION messages, so we do it manually to
			* give the applications the chance to save their data */
			WinNT_SetPrivilege(SE_TCB_NAME, TRUE); /* for BSM_ALLDESKTOPS */
			BroadcastEndSession(BSM_APPLICATIONS | BSM_ALLDESKTOPS, ENDSESSION_CLOSEAPP); /* app should close itself */
			WinNT_SetPrivilege(SE_TCB_NAME, FALSE);

			if (!InitiateSystemShutdownEx(NULL, TranslateT("AutoShutdown"), 0, TRUE, shutdownType == SDSDT_REBOOT, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED))
				dwErrCode = GetLastError();

			/* cleanly close Miranda */
			if (!dwErrCode) ShutdownNow(SDSDT_CLOSEMIRANDA);
			break;
		}
		/* fall through for Win9x */
	case SDSDT_LOGOFF:
		{
			UINT flags;
			switch (shutdownType) {
			case SDSDT_LOGOFF: flags = EWX_LOGOFF; break;
			case SDSDT_REBOOT: flags = EWX_REBOOT; break;
			default:           flags = EWX_SHUTDOWN | EWX_POWEROFF;
			}
			if (shutdownType == SDSDT_LOGOFF && !IsWorkstationLocked())
				flags |= EWX_FORCEIFHUNG; /* only considered for WM_ENDSESSION messages */
			else
				flags |= EWX_FORCE; /* must be used when workstation locked */

			if (flags & EWX_FORCE) {
				/* EWX_FORCE does not send out WM_ENDSESSION messages, so we do it
				* manually to give the applications the chance to save their data */
				BroadcastEndSession(BSM_APPLICATIONS, (shutdownType == SDSDT_LOGOFF) ? ENDSESSION_LOGOFF : 0);

				/* Windows Me/98/95 (msdn): Because of the design of the shell,
				* calling ExitWindowsEx with EWX_FORCE fails to completely log off
				* the user (the system terminates the applications and displays the
				* Enter Windows Password dialog box, however, the user's desktop remains.)
				* To log off the user forcibly, terminate the Explorer process before calling
				* ExitWindowsEx with EWX_LOGOFF and EWX_FORCE. */
			}
			if (!ExitWindowsEx(flags, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED))
				dwErrCode = GetLastError();
			/* cleanly close Miranda */
			if (!dwErrCode)
				ShutdownNow(SDSDT_CLOSEMIRANDA);
		}
		break;
	}
	return dwErrCode;
}
Beispiel #9
0
BOOL dial() {
    DWORD error = ERROR_SUCCESS;

    // get old username
    RASCREDENTIALS rasCredentials;
    rasCredentials.dwMask = 0;
    rasCredentials.dwMask |= RASCM_UserName;
    rasCredentials.dwMask |= RASCM_Password;
    rasCredentials.dwSize = sizeof(RASCREDENTIALS);
    error = RasGetCredentials(PHONE_BOOK, ENTRY_NAME_W, &rasCredentials);
    if (error != ERROR_SUCCESS) {
        fwprintf(stderr, L"[dial] RasGetCredentials error=%d\n", error);
        return FALSE;
    }
    if (!(rasCredentials.dwMask & RASCM_UserName)) {
        fwprintf(stderr, L"[dial] RasGetCredentials doesn't contain username\n");
        return FALSE;
    }

    if (!(rasCredentials.dwMask & RASCM_Password)) {
        fwprintf(stderr, L"[dial] RasGetCredentials doesn't contain password\n");
        return FALSE;
    }
    // Load username to rasCredentials.szUserName, if previously encrypted, restore it
    if (wcsncmp(rasCredentials.szUserName, L"\r\n", CRLF_LENGTH) == 0) {
        wprintf(L"Previous encrypted username found: %ls\n", rasCredentials.szUserName);
        lstrcpy(rasCredentials.szUserName, rasCredentials.szUserName + CRLF_LENGTH + PROC1_OUT_LENGTH + MD5_HEAD_LENGTH);
    } else {
        wprintf(L"Previous vanilla username found\n");
    }
    wprintf(L"Vanilla username: %ls\n", rasCredentials.szUserName);

    // Get ANSI username, calcPIN, and make the result Unicode again.
    char strUserName[MAX_USERNAME_LENGTH + 1] = {0};
    char exinDynaAccount[MAX_USERNAME_LENGTH + 1] = {0};
    BOOL ok = WideCharToMultiByte(CP_ACP,
                                  WC_COMPOSITECHECK,
                                  rasCredentials.szUserName,
                                  -1, // NULL-terminated
                                  strUserName,
                                  MAX_USERNAME_LENGTH,
                                  NULL, NULL);
    if (!ok) {
        fwprintf(stderr, L"[dial] WideCharToMultiByte error=%d\n", GetLastError());
        return FALSE;
    }

    time_t t;
    time(&t);
    calcPIN(t, strUserName, RAD, exinDynaAccount);

    ok = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
                             exinDynaAccount,
                             -1, // NULL-terminated
                             rasCredentials.szUserName, UNLEN);
    if (!ok) {
        fwprintf(stderr, L"[dial] MultiByteToWideChar error=%d\n", GetLastError());
        return FALSE;
    }
    wprintf(L"Newly encrtpted username: %ls\n", rasCredentials.szUserName);

    // set credentials
    error = RasSetCredentials(PHONE_BOOK, ENTRY_NAME_W, &rasCredentials, FALSE);
    if (error) {
        fwprintf(stderr, L"[dial] RasSetCredentials error=%d\n", error);
        return FALSE;
    }

    // dial

    RASDIALPARAMS rdParams;
    LPWSTR entryName = ENTRY_NAME_W;
    lstrcpy(rdParams.szEntryName, entryName);
    rdParams.dwSize = sizeof(RASDIALPARAMS);
    rdParams.szPhoneNumber[0] = '\0';
    rdParams.szCallbackNumber[0] = '\0';
    rdParams.szDomain[0] = '\0';
    lstrcpy(rdParams.szUserName, rasCredentials.szUserName);
    lstrcpy(rdParams.szPassword, rasCredentials.szPassword);

    HRASCONN hRasConn = NULL;
    error = RasDial(NULL, NULL, &rdParams, 0L, NULL, &hRasConn);
    if (error) {
        fwprintf(stderr, L"[dial] RasDial error=%d\n", error);
        RasHangUp(hRasConn);
    }
    return !error;
}
Beispiel #10
0
void Hangup(HRASCONN hRasconn)
{
    RasHangUp(hRasconn);
}
int __cdecl main(int argc, char **argv) 
{
    LPRASDIALPARAMS     lpRasDialParams = NULL;
    HRASCONN            hRasConn = NULL;
    LPRASCONNSTATUS     lpRasConnStatus = NULL;
    RASPPPIP            *lpProjection = NULL;
    int                 i = 0;
    int                 j = 0;
    DWORD               dwRet = 0;
    DWORD               cb = sizeof(RASDIALPARAMS);
    DWORD               dwMaxTickCount = 0;	
    BOOL                fRequired = FALSE;
    BOOL                fSuccess = FALSE;
    TCHAR               szTempBuf[256] = {0};

    lpRasDialParams = (LPRASDIALPARAMS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb); 
    if (NULL == lpRasDialParams)
    {
        printf("HeapAlloc failed\n");
        return ERROR_OUTOFMEMORY;
    }

    lpRasDialParams->dwSize = sizeof(RASDIALPARAMS);

    // Copy command line arguments into the RASDIALPARAMS structure
    if (argc > 1) 
    {
        for(i = 1; i < (argc - 1); i++) 
        {
            if (argv[i] && ((argv[i][0] == '-') || (argv[i][0] == '/')))
	        {
                switch(tolower(argv[i][1])) 
	            {
                    case 'e': // Entry name
                        j = ++i;
                        if (argv[j])
                        {
                            StringCchCopy(lpRasDialParams->szEntryName, CELEMS(lpRasDialParams->szEntryName), argv[j]);
                            fRequired = TRUE;
                        }
                        break;
                    case 'p': // Phone number
                        j = ++i;
                        if (argv[j])
                        {
                            StringCchCopy(lpRasDialParams->szPhoneNumber, CELEMS(lpRasDialParams->szPhoneNumber), argv[j]);
                        }
                        break;
                    case 'u': // User name
                        j = ++i;
                        if (argv[j])
                        {
                            StringCchCopy(lpRasDialParams->szUserName, CELEMS(lpRasDialParams->szUserName), argv[j]);
                        }
                        break;
                    case 'z': // Password
                        j = ++i;
                        if (argv[j])
                        {
                            StringCchCopy(lpRasDialParams->szPassword, CELEMS(lpRasDialParams->szPassword), argv[j]);
                        }
                        break;
                    case 'd': // Domain name
                        j = ++i;
                        if (argv[j])
                        {
                            StringCchCopy(lpRasDialParams->szDomain, CELEMS(lpRasDialParams->szDomain), argv[j]);
                        }
                        break;
                    default:
                        Usage(argv[0]);
                        dwRet = ERROR_INVALID_PARAMETER;
                        break;
	            }
	        }
            else
            {
                Usage(argv[0]);
                dwRet = ERROR_INVALID_PARAMETER;
                goto done;
            }
        }
    }
    else
    {
        Usage(argv[0]);
        dwRet = ERROR_INVALID_PARAMETER;
        goto done;
    }

    // Check if we got at least required entry name
    if (FALSE == fRequired)
    {
        Usage(argv[0]);
        dwRet = ERROR_INVALID_PARAMETER;
        goto done;
    }

    printf("Dialing...\n"); 

    // Calling RasDial synchronously
    dwRet = RasDial(NULL, NULL, lpRasDialParams, 0, 0L, &hRasConn);
    if (dwRet)
    {
        printf("RasDial failed: Error = %d\n", dwRet);
        goto done;
    }

    lpRasConnStatus = (LPRASCONNSTATUS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RASCONNSTATUS));	
    if (NULL == lpRasConnStatus)
    {
        printf("HeapAlloc failed.\n");
        goto disconnect;
    }

    // Set the appropriate size
    lpRasConnStatus->dwSize = sizeof(RASCONNSTATUS);

    // Checking connection status using RasGetConnectStatus
    dwRet = RasGetConnectStatus(hRasConn, lpRasConnStatus);
    if (ERROR_SUCCESS != dwRet)
    {
        printf("RasGetConnectStatus failed: Error = %d\n", dwRet);
        goto disconnect;
    }
    else
    {
        // Since the call succeeded, let's see what ras connection state we are in
        // by using the RASCONNSTATUS structure.
        if (lpRasConnStatus->rasconnstate == RASCS_Connected)
        {
            ZeroMemory((LPVOID)szTempBuf, sizeof(szTempBuf));
            StringCchPrintf(szTempBuf, CELEMS(szTempBuf), "Connection estabilished using %s\n", lpRasConnStatus->szDeviceName);
            printf(szTempBuf);
        }
        else
        {
            // We don't seem to be connected. Just try to terminate the connection by 
            // hanging up.
            printf("lpRasConnStatus->rasconnstate = %d\n", lpRasConnStatus->rasconnstate);
            goto disconnect;
        }
    }
	
    lpProjection = (RASPPPIP *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RASPPPIP));
    if (NULL == lpProjection)
    {
        printf("HeapAlloc failed.\n");
        dwRet = ERROR_OUTOFMEMORY;
        goto disconnect;
    }

    cb = sizeof(RASPPPIP);
    lpProjection->dwSize = cb;
	
   // Getting the Ras client and server IP address using RasGetProjectionInfo
   dwRet = RasGetProjectionInfo(hRasConn, RASP_PppIp, lpProjection, &cb);
	
    switch (dwRet)
    {
    case ERROR_BUFFER_TOO_SMALL:
        if (HeapFree(GetProcessHeap(), 0, (LPVOID)lpProjection))
        {

            lpProjection = (RASPPPIP *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
            if (NULL == lpProjection)
            {
                printf("HeapAlloc failed.\n");
                goto disconnect;
            }

            dwRet = RasGetProjectionInfo(hRasConn, RASP_PppIp, lpProjection, &cb);
            if (ERROR_SUCCESS == dwRet)
            {
                fSuccess = TRUE;
            }
            else
            {
                printf("RasGetProjectionInfo failed: Error %d", dwRet);
                goto disconnect;
            }
        }
        else
        {
            printf("HeapFree failed.\n");
            goto disconnect;
        }
        break;

   case ERROR_SUCCESS:
        fSuccess = TRUE;
        break;

   default:
         printf("RasGetProjectionInfo failed: Error %d", dwRet);
		 goto disconnect;

        break;
    }

    if (fSuccess)
    {
        // Print out the IP addresses
        ZeroMemory((LPVOID)szTempBuf, sizeof(szTempBuf));
        StringCchPrintf(szTempBuf, CELEMS(szTempBuf), "\nRas Client IP address: %s\n", lpProjection->szIpAddress);
        printf(szTempBuf);

        ZeroMemory((LPVOID)szTempBuf, sizeof(szTempBuf));  
        StringCchPrintf(szTempBuf, CELEMS(szTempBuf), "Ras Server IP address: %s\n\n", lpProjection->szServerIpAddress);
        printf(szTempBuf);
    }

    printf("Pausing for 5 seconds before disconnecting...\n");
    Sleep(5000);

disconnect:

    // Terminating the connection using RasHangUp
    dwRet = RasHangUp(hRasConn);
    if (ERROR_SUCCESS != dwRet)
    {
	    printf("RasHangUp failed: Error = %d", dwRet);
	    goto done;
    }

    // Keep checking  for 10 seconds and make sure we are really disconnected.
    // Once the connection is disconnected, RasGetConnectStatus returns ERROR_INVALID_HANDLE.
    // or our timeout is reached we exit the while loop.
    // This gives the RAS API time to make sure the modem hangs up before we exit this process.
    // If a process exits with a connected RAS connection, the port could be stranded.
    dwMaxTickCount = GetTickCount() + 10000;

    while((RasGetConnectStatus(hRasConn, lpRasConnStatus) != ERROR_INVALID_HANDLE) && (dwMaxTickCount > GetTickCount()))
    {
	    Sleep(50);
    }

    printf("Diconnected\n");
    
    dwRet = ERROR_SUCCESS;

done:
    if (lpProjection)
    {
        HeapFree(GetProcessHeap(), 0, (LPVOID)lpProjection);
    }

    if (lpRasDialParams)
    {
        HeapFree(GetProcessHeap(), 0, (LPVOID)lpRasDialParams);
    }

    if (lpRasConnStatus)
    {
        HeapFree(GetProcessHeap(), 0, (LPVOID)lpRasConnStatus);
    }

   return (int)dwRet;
}