Connection to the Internet using VC++  MFC

keep_it
keep_it used Ask the Experts™
on
Hi All,
I have a following problem :
I need to connect to the Internet using VC++ MFC Windows Application.
After internet connection, some username and password is given through my Windows Application and it should be verified at the website(which is not a part of my windows application) with which my application is connected.If username and password is OK, my application will go to next windows form otherwise error popup will come.
And one more thing, all this web verification should be done in background means no web page should be opened.
Please reply ASAP
Thanks in Advance..
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Have you read it?
http://msdn.microsoft.com/en-us/library/w4t598dt.aspx
 http://msdn.microsoft.com/ru-ru/library/e96ak973.aspx
Here is one more tutorial an example: http://www.tenouk.com/visualcplusmfc/visualcplusmfcwinsock.html
Here is how to write such applications: http://msdn.microsoft.com/ru-ru/library/6f7sbkyc.aspx
Here is a simple app: http://www.codeproject.com/KB/IP/MFC_telnet.aspx
Of course, there are a lot of ways to solve the task you described. I understood the question so. Maybe it will be enough for you to use something even simplier.
 

Author

Commented:
Hi pgnatyuk,
Can u please provide some sample code related to this since i m new to VC++ and MFC.

Thanks

Commented:
There are few samples in my previous comment.
To build an application for you that will work with the username and password - I need a support from the web-server side or you need to specify with which server you want to work.
I attached as an example a high-level login function just to show one of the possible ways.

WCHAR szUrl[MAX_PATH]={0};
_snwprintf(szUrl,MAX_PATH,L"http://%s/login/?user=%s&pwd=%s", m_szServer,szUser,szPsw);
BOOL ret = m_httpManager.ParseURL(szUrl);

Open in new window

Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

Author

Commented:
Hi pgnatyuk,
I want to work with the web server like our mail id.
And if the username and password are verified on the web server, my application will continue othrwise popup will occur showing error.
And i didnt understand the code given by you in your previous comment that how to use it.
Please explain it.

Thanks

Commented:
You said "our mail id" - what do you mean? Here on this site - EE?
You don't want to say that we work in the same company? :)
Maybe better just an ftp?
I attached code taken from here:
http://msdn.microsoft.com/en-us/library/sb35xf67.aspx
It will be great to modify it and add the username and password. There is no GUI (wininet, actually, always without GUI).
Then let's take another example. With the HTTP and make an app with GET and POST.
ParseURL(szUrl); - from the previous example is high-level function that covers few WinInet functions - they are in the examples from the link above.
There is nothing special or difficult in this subject. But for the commercial projects it is always required an an integration with the server side.
 

#include <afxinet.h>
 
void GetFtpFile(LPCTSTR pszServerName, LPCTSTR pszRemoteFile, LPCTSTR pszLocalFile)
{
   CInternetSession session(_T("My FTP Session"));
   CFtpConnection* pConn = NULL;
 
   pConn = session.GetFtpConnection(pszServerName);
   //get the file
   if (!pConn->GetFile(pszRemoteFile, pszLocalFile))
   {
      //display an error
   }
   delete pConn;
   session.Close();
}

Open in new window

Author

Commented:
Hi pgnatyuk,
Sorry it is not ftp...
I want to connect through HTTP connection.
For example my gmail id.
If I'll open gmail.com through HTTPS connection and verify my email id and password on it.
This is the situation.
Please explain.

Thanks

Commented:
So if it is just gmail, I don't need to do anything. Here is a lib (gmail API):
http://sourceforge.net/projects/gmail-api/
http://johnvey.com/features/gmailapi/
It is open source.
You can find there the attached example for .Net. All explanations are there.
Make your code, if it does not work, post it here, we will be glad to help.

// init new adapter
GmailAdapter gmail = new GmailAdapter();
 
// create new session and assign username and password
GmailSession myAccount = new GmailSession();
myAccount.Username = "googler";
myAccount.Password = "showmethemoney";
 
// login and retrieve mailbox info
GmailAdapter.RequestResponseType loginResult = gmail.Refresh(myAccount);
 
// display mailbox info
if(loginResult == GmailAdapter.RequestResponseType.Success) {
 
    // show new inbox count
    Console.WriteLine("New Threads: " + myAccount.DefaultSearchCounts["Inbox"]);
 
    // if new threads exist, show the subject of the first one
    if(myAccount.UnreadThreads.Count > 0) {
        GmailThread newThread = (GmailThread)myAccount.UnreadThreads[0];
        Console.WriteLine("Latest thread subject: " + newThread.SubjectHtml);
    }
}

Open in new window

Commented:
I'd like to hope that the following "explanation" will bring my points from these 2 threads. :)
I attached a part from my mail class (it is not about gmail) that performs the basic flow:
1. Create session
2. Connect to server
3. Open URL
4. Open/Send request.
Everything works in this way. I really don't beleive that I can explain better then MSDN:
Writing an Internet Client Application Using MFC WinInet Classes: http://msdn.microsoft.com/en-us/library/6f7sbkyc.aspx\
 http://msdn.microsoft.com/en-us/library/aa384322(VS.85).aspx (there is an example downloading the resource from internet without any GUI).
MSDN: http://msdn.microsoft.com/en-us/library/cc185684(VS.85).aspx (asynchronous example)
MSND (MFC, CInternetSession class) : http://msdn.microsoft.com/en-us/library/cc185684(VS.85).aspx

BOOL CHttpMail::Open()
{
	m_hSession = m_DLL.InternetOpen(lpctstrAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	return (m_hSession != NULL);
}
 
BOOL CHttpMail::Connect()
{
	if ((m_hSession != NULL) && (_tcslen(m_strServer) > 0))
	{
		m_hConnect = m_DLL.InternetConnect(m_hSession, m_strServer,INTERNET_DEFAULT_HTTP_PORT,
			NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
	}
	return (m_hConnect != NULL);
}
 
BOOL CHttpMail::OpenUrl(LPCTSTR lpctstrUrl)
{
	BOOL bRet = FALSE;
	if (m_hSession != NULL)
	{
		DWORD dwContext = 1;
		HINTERNET hUrl = m_DLL.InternetOpenUrl(m_hSession, lpctstrUrl, NULL, 0, 0, dwContext);
		bRet = hUrl != NULL;
		if (hUrl != NULL)
		{
			m_DLL.InternetCloseHandle(hUrl);
		}
	}
	return (bRet);
}
 
BOOL CHttpMail::OpenRequest()
{
	if (m_hConnect != NULL)
	{
		m_hRequest = m_DLL.HttpOpenRequest(m_hConnect, "POST", lpctstrFormAction,
			NULL, NULL, &lpctstrAccept, 
			//INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD, 
			INTERNET_FLAG_RELOAD, 
			1);
	}
	return (m_hRequest != NULL);
}
 
BOOL CHttpMail::SendRequest(LPVOID lpRequest, DWORD dwRequest)
{
	BOOL bRet = FALSE;
	if (m_hRequest != NULL)
	{
		bRet = m_DLL.HttpSendRequest(m_hRequest, lpctstrHeaders, lstrlen(lpctstrHeaders),
			lpRequest, dwRequest);
#ifdef _DEBUG_ADD
		if (!bRet)
		{
			DWORD dwError = GetLastError();
			TCHAR strError[MAX_PATH];
			ZeroMemory(strError, MAX_PATH * sizeof(TCHAR));
			_stprintf(strError, "Error = %d\n", dwError);
			::OutputDebugString("SendRequest failed\n");
			::OutputDebugString(strError);
		}
#endif
	}
	return (bRet);
}
 
void CHttpMail::Close()
{
	if (m_hRequest != NULL)
	{
		m_DLL.InternetCloseHandle(m_hRequest);
		m_hRequest = NULL;
	}
	if (m_hConnect != NULL)
	{
		m_DLL.InternetCloseHandle(m_hConnect);
		m_hConnect = NULL;
	}
	if (m_hSession != NULL)
	{
		m_DLL.InternetCloseHandle(m_hSession);
		m_hSession = NULL;
	}
}

Open in new window

Author

Commented:
Hi,
I started with the following code and it is working till SendRequest.
But sendRequest is not working since it is giving error code 12005
which means ERROR_INTERNET_INVALID_URL(The URL is invalid.)
The Code is as follows:


CString csFilePath = _T("http://www.google.com");
 
// Initialize the Internet DLL
 
HINTERNET hSession = ::InternetOpen(_T("HTML Reader"),PRE_CONFIG_INTERNET_ACCESS, _T(""),INTERNET_INVALID_PORT_NUMBER, 0);
 
// Initialize HTTP session
 
HINTERNET hConnect = ::InternetConnect(hSession, csFilePath,
 
INTERNET_INVALID_PORT_NUMBER, _T(""), _T(""),
 
INTERNET_SERVICE_HTTP, 0, 0);
// Open an HTTP request handle
 
HINTERNET hHttpFile = ::HttpOpenRequest(hConnect, _T("GET"),
 
csFilePath, _T("HTTP/1.1"), NULL, 0,
 
INTERNET_FLAG_DONT_CACHE, 0);
 
// Send the request
 
BOOL bSendRequest = ::HttpSendRequest(hHttpFile, NULL, 0, 0, 0);
DWORD dw = GetLastError();
 
if (bSendRequest)
 
{
AfxMessageBox(_T("Request Sent"));
}

Open in new window

Author

Commented:
Hi pgnatyuk,
How the GmailAdapter and its API is used in VC++?
How Johnvey.GmailAgent Namespace and the API will be used in VC++ since the code is in .Net (C#,.cs files)which i have downloaded with the Johnvey.GmailAgent.dll .
I m unable to use code given by you.

Also please provide me details for the simple mail (code given by you in the next thread).
i.e what is "m_DLL" etc.
And please reply to my above thread query also.

Thanks

Commented:
m_DLL is just a wrapper for WinInet.dll - ignore it.
OpenRequest/SendRequest in the code you posted looks strange. I will check it tomorrow.

Commented:
http://www.codeproject.com/KB/IP/webgrab.aspx
Right now found this link in another thread on. Probably there is a memory issue, but there is a source code to download.
Commented:
I see that you have downloaded this .Net gmail api (http://sourceforge.net/projects/gmail-api/files/).
Fine. You can find all nessesary parameters to work with gmail.
BTW, here you can find more info (includeing Win32 agent): http://www.johnvey.com/features/gmailapi/
I hope this step already works for you:

#include afxinet.h
void CInternetTestDlg::OnBnClickedButtonOpen()
{
UpdateData();
if (m_strURL.IsEmpty())
return;

CInternetSession session(_T("Internet Demo"));
CHttpFile* pFile = (CHttpFile*)session.OpenURL(m_strURL);
session.Close();
delete pFile;
}

m_strURL can be "http://mail.google.com" or any other URL you like.
This code works - pFile will be not NULL.
If you will follow the steps listed here: http://msdn.microsoft.com/en-us/library/8yh4zs9e.aspx
and you will check yourself with the gmail api source code, you will make something like the attached code.

#include <afxinet.h>
 
void CInternetTestDlg::OnBnClickedButtonPost()
{
	UpdateData();
	if (m_strURL.IsEmpty()) 
		return;
 
	CInternetSession session(_T("Internet Demo"),
		0,
		INTERNET_OPEN_TYPE_PRECONFIG,
		NULL,
		NULL,
		INTERNET_FLAG_DONT_CACHE);
 
	CHttpConnection* pServer = NULL;
	CHttpFile* pFile = NULL;
	CString strHtml = _T("");
	CString strRequest = _T("name=123&pwd=321\r\n");
	CString strHeaders = _T("Accept: */*\r\nReferer: http://mail.my_site.com/\r\nAccept-Language: zh-cn\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322; .NET CLR 2.0.50727)");
	INTERNET_PORT nPort;
	nPort = 80;
	pServer = session.GetHttpConnection(m_strURL, nPort);
	pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST, _T("/"));
	pFile->AddRequestHeaders(strHeaders);
	pFile->SendRequestEx(strRequest.GetLength());
	pFile->WriteString(strRequest);
	pFile->EndRequest();
	DWORD dwRet;
	pFile->QueryInfoStatusCode(dwRet);
	DWORD nRead = 0;
	if (dwRet == HTTP_STATUS_OK)
	{
		CString strLine;
		while ((nRead = pFile->ReadString(strLine))>0)
		{
			strHtml += strLine;
		}
 
	}     
	delete pFile;
	delete pServer;
}

Open in new window

Author

Commented:
Thanks

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial