UINT HeaderThread(LPVOID pParam)
{
// a bit dated and not up to date, but you'll get the idea
CHeaderThreadInfo* pThreadInfo = (CHeaderThreadInfo*)pParam;
HWND hView = pThreadInfo->m_hView;
HANDLE hIsRetrieving = pThreadInfo->m_hIsRetrieving;
CString strNewsgroup = pThreadInfo->m_strNewsgroup;
CAccount* pAccount = pThreadInfo->m_pAccount;
CPreferences* pPreferences = pThreadInfo->m_pPreferences;
delete pThreadInfo;
char strPassword[64];
char strUsername[64];
DWORD dwAccessType;
CString strProxyAddress = "";
LPCTSTR pstrProxyAddress = NULL;
pPreferences->m_cs.Lock();
if (pPreferences->m_bUseProxy){
if (pPreferences->m_nProxySetting == 0){
dwAccessType = INTERNET_OPEN_TYPE_PRECONFIG;
}
else{
dwAccessType = INTERNET_OPEN_TYPE_PROXY;
strProxyAddress.Format("%s:%d", pPreferences->m_strProxyAddress,
pPreferences->m_nProxyPort);
pstrProxyAddress = strProxyAddress;
}
if (pPreferences->m_bProxyAuthentication){
strcpy(strUsername, pPreferences->m_strProxyUsername);
strcpy(strPassword, pPreferences->m_strProxyPassword);
}
else{
pAccount->m_cs.Lock();
strcpy(strUsername, pAccount->m_strNPUsername);
strcpy(strPassword, pAccount->m_strNPPassword);
pAccount->m_cs.Unlock();
}
}
else{
dwAccessType = INTERNET_OPEN_TYPE_DIRECT;
pAccount->m_cs.Lock();
strcpy(strUsername, pAccount->m_strNPUsername);
strcpy(strPassword, pAccount->m_strNPPassword);
pAccount->m_cs.Unlock();
}
pPreferences->m_cs.Unlock();
CString strURL, strDomain, strNewsProvider, strDRNDir;
pAccount->m_cs.Lock();
CString strRetrieveBy;
switch(pAccount->m_nRetrieveBy){
case SORTAUTHOR:
strRetrieveBy = "b";
break;
case SORTOLDEST:
strRetrieveBy = "f";
break;
case SORTCURRENT:
strRetrieveBy = "g";
break;
case SORTSUBJECT:
strRetrieveBy = "z";
break;
default:
strRetrieveBy = "z";
break;
}
switch(pAccount->m_nNewsProvider){
case NEWSGUY:
strNewsProvider = "NewsGuy";
strDomain = "drn.newsguy.com";
strNewsgroup = "news-bin/wwwnews?-s" + strRetrieveBy + ",b1,n100000,B+" + strNewsgroup;
break;
case NEWSGUYEXTRA:
strNewsProvider = "NewsGuy Extra";
strDomain = "edrn.newsguy.com";
strNewsgroup = "news-bin/wwwnews?-s" + strRetrieveBy + ",b1,n100000,B+" + strNewsgroup;
break;
case WEBUSENET:
strNewsProvider = "WebUseNet";
strDomain = "www.webusenet.com";
strNewsgroup = "drn-bin/wwwnews?-s" + strRetrieveBy + ",b1,n100000,B+" + strNewsgroup;
break;
case WEBUSENETMEMBER:
strNewsProvider = "WebUseNet";
strDomain = "members.webusenet.com";
strNewsgroup = "drn-bin/wwwnews?-s" + strRetrieveBy + ",b1,n100000,B+" + strNewsgroup;
break;
default:
strNewsProvider = "NewsGuy Extra";
strDomain = "edrn.newsguy.com";
strNewsgroup = "news-bin/wwwnews?-s" + strRetrieveBy + ",b1,n100000,B+" + strNewsgroup;
break;
}
pAccount->m_cs.Unlock();
LPCTSTR strProgress = "Retreiving Headers...";
::PostMessage(hView, WM_DOWNLOAD_PROGRESS, 0, (LPARAM)strProgress);
DWORD dwFlags = INTERNET_FLAG_DONT_CACHE;
CInternetSession session(NULL, 1, dwAccessType, pstrProxyAddress, NULL, dwFlags);
CHttpConnection* pConnection = NULL;
CHttpFile* pHttpFile = NULL;
strProgress = "Open InternetSession...";
::PostMessage(hView, WM_DOWNLOAD_PROGRESS, 0, (LPARAM)strProgress);
try {
pAccount->m_cs.Lock();
pConnection = session.GetHttpConnection(strDomain,
INTERNET_INVALID_PORT_NUMBER,
pAccount->m_strNPUsername,
pAccount->m_strNPPassword);
pAccount->m_cs.Unlock();
pHttpFile = pConnection->OpenRequest(1,strNewsgroup, NULL, 1, NULL, NULL, INTERNET_FLAG_RELOAD |
INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_KEEP_CONNECTION);
strProgress = "Open Request...";
::PostMessage(hView, WM_DOWNLOAD_PROGRESS, 0, (LPARAM)strProgress);
DWORD dwStatus;
resend:
pHttpFile->SendRequest();
pHttpFile->QueryInfoStatusCode(dwStatus);
switch (dwStatus)
{
case HTTP_STATUS_PROXY_AUTH_REQ: //Proxy Authentication Required
strProgress = "Sending Proxy Password...";
::PostMessage(hView, WM_DOWNLOAD_PROGRESS, 0, (LPARAM)strProgress);
pPreferences->m_cs.Lock();
strcpy(strUsername, pPreferences->m_strProxyUsername);
strcpy(strPassword, pPreferences->m_strProxyPassword);
pPreferences->m_cs.Unlock();
pConnection->SetOption(INTERNET_OPTION_PROXY_USERNAME,
strUsername, strlen(strUsername)+1);
pConnection->SetOption(INTERNET_OPTION_PROXY_PASSWORD,
strPassword, strlen(strPassword)+1);
//AfxMessageBox("ProxyAuthentication\r\n" + strProxyUsername + "\r\n" + strProxyPassword);
goto resend;
break;
case HTTP_STATUS_DENIED: //Server Authentication Required
strProgress = "Sending " + strNewsProvider + " Password...";
::PostMessage(hView, WM_DOWNLOAD_PROGRESS, 0, (LPARAM)strProgress);
pAccount->m_cs.Lock();
strcpy(strUsername, pAccount->m_strNPUsername);
strcpy(strPassword, pAccount->m_strNPPassword);
pAccount->m_cs.Unlock();
pConnection->SetOption(INTERNET_OPTION_USERNAME,
strUsername, strlen(strUsername)+1);
pConnection->SetOption(INTERNET_OPTION_PASSWORD,
strPassword, strlen(strPassword)+1);
// AfxMessageBox("NewsGuyAuthentication\r\n" + strNGUsername + "\r\n" + strNGPassword);
goto resend;
break;
}
CString strQueryInfo;
BOOL bQueryInfo = pHttpFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strQueryInfo);
strProgress = strQueryInfo;
::PostMessage(hView, WM_DOWNLOAD_PROGRESS, 0, (LPARAM)strProgress);
CString strLine;
CArticle* pArticle;
int nTag, nStart, nEnd;
BOOL bComplete, bPart;
while(::WaitForSingleObject(hIsRetrieving,0) == WAIT_OBJECT_0) {
//retrieve one line at a time
if(pHttpFile->ReadString(strLine) == FALSE) //retrieve one line at a time
break; //break if no more lines left
//if (strLine.Find("/news-bin/wwwdecode?") != -1){//is this a 'messageheader' or a comment line?
//if ((strLine.Find("/icons/drncheck.gif") != -1) || (strLine.Find("/icons/drnblank.gif") != -1)) {
if (strLine.Find("-bin/wwwdecode?") != -1){//is this a 'messageheader' or a comment line?
//if ((strLine.Find("/drncheck.gif") != -1) || (strLine.Find("/drnblank.gif") != -1)
// || strLine.Find() {
bComplete = (strLine.Find("/drncheck.gif") != -1) || (strLine.Find("/drnblank.gif") != -1);
bPart = (strLine.Find("/drnpart.gif"));
if ((bComplete) || (bPart)){
try {
pArticle = new CArticle;
}
catch(CMemoryException* me) {
me->Delete();
return FALSE;
}
if (bComplete){
pArticle->m_nStatus = ARTICLE_NOTQUEUED;
}
else{
pArticle->m_nStatus = ARTICLE_INCOMPLETE;
}
pArticle->m_nCanBeDeleted = LISTCTRLARTICLES;
pArticle->m_nAttempts = 0;
pArticle->m_strPath = "";
pArticle->m_nNewsProvider = pAccount->m_nNewsProvider;
//Date
pArticle->m_strDate = strLine.Left(5);
//Author
nTag = strLine.Find('<');
pArticle->m_strAuthor = strLine.Mid(5, (nTag - 5));
pArticle->m_strAuthor.TrimLeft(); pArticle->m_strAuthor.TrimRight();
//URL
nStart = strLine.Find('?',nTag) + 1; //0 based index, hence add 1
nEnd = strLine.Find('"',nStart);
pArticle->m_strURL = strLine.Mid(nStart, (nEnd - nStart));
//Size
nStart = strLine.Find('>', nEnd) + 1;
nEnd = strLine.Find('<', nStart);
CString strTemp = strLine.Mid(nStart, (nEnd - nStart));
int nIndex;
int nMultiplier = 1;
CString strBegin, strEnd;
if (strTemp.Find("K") != -1){
nMultiplier = 100;
}
if (strTemp.Find("M") != -1){
nMultiplier = 100000;
}
strTemp = strTemp.SpanExcluding("BKM");
nIndex = strTemp.Find('.');
int nSize;
if (nIndex != -1){
strBegin = strTemp.Left(nIndex);
strEnd = strTemp.Right(strTemp.GetLength() - nIndex - 1);
strTemp = strBegin + strEnd;
nSize = atoi(strTemp);
pArticle->m_nSize = nSize * nMultiplier;
//pArticle->m_strSize.Format("%d", nSize);
}
else //pArticle->m_strSize = strTemp;
pArticle->m_nSize = nSize;
//pArticle->m_strSize = strLine.Mid(nStart, (nEnd - nStart));
//Subject
nStart = strLine.ReverseFind('"')+2; //Description start after ">
nEnd = strLine.ReverseFind('<');
pArticle->m_strSubject = strLine.Mid(nStart, (nEnd - nStart));
//Clean-up HTML code
pArticle->m_strAuthor.Replace("&","&");
pArticle->m_strAuthor.Replace("<","<");
pArticle->m_strSubject.Replace("&","&");
pArticle->m_strSubject.Replace("<","<");
nStart = pArticle->m_strSubject.ReverseFind('-');
if (nStart != -1){
pArticle->m_strPossibleFilename = pArticle->m_strSubject.Mid(nStart+1);
pArticle->m_strPossibleFilename.TrimLeft();
}
::PostMessage(hView, WM_HEADER_DL_COMPLETE, 0, (LPARAM)pArticle);
}
}
}
}
catch(CInternetException* e) {
e->Delete();
}
if (pHttpFile != NULL){
pHttpFile->Close();
delete pHttpFile; // closes the file -- prints a warning
}
ResetEvent(hIsRetrieving);
::PostMessage(hView, WM_HEADER_DL_COMPLETE, 1, 0);
return 0;
}
UINT EasyNewsHeaderThread(LPVOID pParam)
{
CHeaderThreadInfo* pThreadInfo = (CHeaderThreadInfo*)pParam;
HWND hView = pThreadInfo->m_hView;
HANDLE hIsRetrieving = pThreadInfo->m_hIsRetrieving;
CString strNewsgroup = "group.cgi?group=" + pThreadInfo->m_strNewsgroup;
CAccount* pAccount = pThreadInfo->m_pAccount;
CPreferences* pPreferences = pThreadInfo->m_pPreferences;
BOOL bUsePort81 = pThreadInfo->m_bUsePort81;
delete pThreadInfo;
char strPassword[64];
char strUsername[64];
DWORD dwAccessType;
CString strProxyAddress = "";
LPCTSTR pstrProxyAddress = NULL;
pPreferences->m_cs.Lock();
if (pPreferences->m_bUseProxy){
if (pPreferences->m_nProxySetting == 0){
dwAccessType = INTERNET_OPEN_TYPE_PRECONFIG;
}
else{
dwAccessType = INTERNET_OPEN_TYPE_PROXY;
strProxyAddress.Format("%s:%d", pPreferences->m_strProxyAddress,
pPreferences->m_nProxyPort);
pstrProxyAddress = strProxyAddress;
}
if (pPreferences->m_bProxyAuthentication){
strcpy(strUsername, pPreferences->m_strProxyUsername);
strcpy(strPassword, pPreferences->m_strProxyPassword);
}
else{
pAccount->m_cs.Lock();
strcpy(strUsername, pAccount->m_strNPUsername);
strcpy(strPassword, pAccount->m_strNPPassword);
pAccount->m_cs.Unlock();
}
}
else{
dwAccessType = INTERNET_OPEN_TYPE_DIRECT;
pAccount->m_cs.Lock();
strcpy(strUsername, pAccount->m_strNPUsername);
strcpy(strPassword, pAccount->m_strNPPassword);
pAccount->m_cs.Unlock();
}
pPreferences->m_cs.Unlock();
CString strURL, strDRNDir;
CString strNewsProvider = "EasyNews";
CString strDomain = "members.easynews.com";
//TCHAR cDay = '0';
int nDay = 0;
LPCTSTR strProgress = "Retreiving Headers...";
::PostMessage(hView, WM_DOWNLOAD_PROGRESS, 0, (LPARAM)strProgress);
DWORD dwFlags = INTERNET_FLAG_DONT_CACHE;
start:
CInternetSession session(NULL, 1, dwAccessType, pstrProxyAddress, NULL, dwFlags);
CHttpConnection* pConnection = NULL;
CHttpFile* pHttpFile = NULL;
strProgress = "Open InternetSession...";
::PostMessage(hView, WM_DOWNLOAD_PROGRESS, 0, (LPARAM)strProgress);
try {
pAccount->m_cs.Lock();
if (bUsePort81)
pConnection = session.GetHttpConnection(strDomain,
(INTERNET_PORT)81 ,
pAccount->m_strNPUsername,
pAccount->m_strNPPassword);
else
pConnection = session.GetHttpConnection(strDomain,
INTERNET_INVALID_PORT_NUMBER,
pAccount->m_strNPUsername,
pAccount->m_strNPPassword);
pAccount->m_cs.Unlock();
pHttpFile = pConnection->OpenRequest(1,strNewsgroup, NULL, 1, NULL, NULL, INTERNET_FLAG_RELOAD |
INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_KEEP_CONNECTION);
strProgress = "Open Request...";
::PostMessage(hView, WM_DOWNLOAD_PROGRESS, 0, (LPARAM)strProgress);
DWORD dwStatus;
resend:
pHttpFile->SendRequest();
pHttpFile->QueryInfoStatusCode(dwStatus);
switch (dwStatus)
{
case HTTP_STATUS_PROXY_AUTH_REQ: //Proxy Authentication Required
strProgress = "Sending Proxy Password...";
::PostMessage(hView, WM_DOWNLOAD_PROGRESS, 0, (LPARAM)strProgress);
pPreferences->m_cs.Lock();
strcpy(strUsername, pPreferences->m_strProxyUsername);
strcpy(strPassword, pPreferences->m_strProxyPassword);
pPreferences->m_cs.Unlock();
pConnection->SetOption(INTERNET_OPTION_PROXY_USERNAME,
strUsername, strlen(strUsername)+1);
pConnection->SetOption(INTERNET_OPTION_PROXY_PASSWORD,
strPassword, strlen(strPassword)+1);
//AfxMessageBox("ProxyAuthentication\r\n" + strProxyUsername + "\r\n" + strProxyPassword);
goto resend;
break;
case HTTP_STATUS_DENIED: //Server Authentication Required
strProgress = "Sending " + strNewsProvider + " Password...";
::PostMessage(hView, WM_DOWNLOAD_PROGRESS, 0, (LPARAM)strProgress);
pAccount->m_cs.Lock();
strcpy(strUsername, pAccount->m_strNPUsername);
strcpy(strPassword, pAccount->m_strNPPassword);
pAccount->m_cs.Unlock();
pConnection->SetOption(INTERNET_OPTION_USERNAME,
strUsername, strlen(strUsername)+1);
pConnection->SetOption(INTERNET_OPTION_PASSWORD,
strPassword, strlen(strPassword)+1);
// AfxMessageBox("NewsGuyAuthentication\r\n" + strNGUsername + "\r\n" + strNGPassword);
goto resend;
break;
case 404:
ResetEvent(hIsRetrieving);
break;
}
CString strQueryInfo;
BOOL bQueryInfo = pHttpFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strQueryInfo);
strProgress = strQueryInfo;
::PostMessage(hView, WM_DOWNLOAD_PROGRESS, 0, (LPARAM)strProgress);
bQueryInfo = pHttpFile->QueryOption(INTERNET_OPTION_URL, strNewsgroup);
if (bUsePort81) strNewsgroup = strNewsgroup.Right(strNewsgroup.GetLength() - 30);
else strNewsgroup = strNewsgroup.Right(strNewsgroup.GetLength() - 27); //strip http://members.easynews.com
CString strTemp, strLine, strAuthor = "";
CArticle* pArticle;
int nTag, nStart, nEnd;
while(::WaitForSingleObject(hIsRetrieving,0) == WAIT_OBJECT_0) {
//retrieve one line at a time
if(pHttpFile->ReadString(strLine) == FALSE) //retrieve one line at a time
break; //break if no more lines left
if ((strLine.Find("<input type") != -1) && (strLine.Find("checkbox") != -1)){//is this a 'messageheader' or a comment line?
try {
pArticle = new CArticle;
}
catch(CMemoryException* me) {
me->Delete();
return FALSE;
}
pArticle->m_nCanBeDeleted = LISTCTRLARTICLES;
pArticle->m_nStatus = ARTICLE_NOTQUEUED;
pArticle->m_nAttempts = 0;
pArticle->m_strPath = "";
pArticle->m_nNewsProvider = EASYNEWS;
//Date
pArticle->m_strDate.Format("%d", nDay);
//URL
nTag = strLine.Find("<a href=", strLine.Find("<input type"));
int nAuthor = strLine.Find("<br>");
if (nAuthor != -1){
if (nAuthor < nTag)
strAuthor = strLine.Left(nAuthor);
}
pArticle->m_strAuthor = strAuthor;
nStart = nTag + 9;
nEnd = strLine.Find(">", nStart) - 1;
pArticle->m_strURL = strLine.Mid(nStart, (nEnd-nStart));
nStart = nEnd + 2;
nEnd = strLine.Find('<', nStart);
strTemp = strLine.Mid(nStart, (nEnd-nStart));
pArticle->m_strSubject = strTemp;
nStart = strTemp.ReverseFind('-');
nEnd = strTemp.GetLength() - 2;
strTemp = strTemp.Right(nEnd - nStart);
int nIndex;
int nMultiplier = 1;
CString strBegin, strEnd;
if (strTemp.Find("K") != -1){
nMultiplier = 1000;
}
if (strTemp.Find("M") != -1){
nMultiplier = 100000;
}
pArticle->m_strPossibleFilename = strTemp;
strTemp = strTemp.SpanExcluding("BKM");
nIndex = strTemp.Find('.');
int nSize;
if (nIndex != -1){
strBegin = strTemp.Left(nIndex);
strEnd = strTemp.Right(strTemp.GetLength() - nIndex - 1);
strTemp = strBegin + strEnd;
nSize = atoi(strTemp);
pArticle->m_nSize = nSize * nMultiplier;
}
else{
nSize = atoi(strTemp);
if (nSize == 0) nSize = 1;
pArticle->m_nSize = nSize * nMultiplier;
}
pArticle->m_strSubject = pArticle->m_strSubject.Left(pArticle->m_strSubject.ReverseFind('-'));
nStart = pArticle->m_strSubject.ReverseFind('-');
nEnd = pArticle->m_strSubject.GetLength() - 1;
if (nStart != -1){
pArticle->m_strPossibleFilename = pArticle->m_strSubject.Right(nEnd - nStart);
pArticle->m_strPossibleFilename.TrimLeft();
pArticle->m_strPossibleFilename.TrimRight();
}
//Clean-up HTML code
pArticle->m_strAuthor.Replace("&","&");
pArticle->m_strAuthor.Replace("<","<");
pArticle->m_strSubject.Replace("&","&");
pArticle->m_strSubject.Replace("<","<");
::PostMessage(hView, WM_HEADER_DL_COMPLETE, 0, (LPARAM)pArticle);
}
}
}
catch(CInternetException* e) {
e->Delete();
}
if (pHttpFile != NULL){
pHttpFile->Close();
delete pHttpFile; // closes the file -- prints a warning
}
nDay++;
if (::WaitForSingleObject(hIsRetrieving,0) == WAIT_OBJECT_0){
CString strStart, strEnd, strTemp;
int nStart, nEnd, nDash;
nStart = strNewsgroup.ReverseFind('/') + 1; // include the slash
nDash = strNewsgroup.ReverseFind('-') - 1; // include the dash
if (nStart > nDash) nDash = nStart;
nEnd = strNewsgroup.GetLength() - 1;
strStart = strNewsgroup.Left(nStart);
strEnd = strNewsgroup.Right(nEnd - nDash);
strNewsgroup.Format("%s%d%s", strStart, nDay, strEnd);
goto start;
}
ResetEvent(hIsRetrieving);
::PostMessage(hView, WM_HEADER_DL_COMPLETE, 1, 0);
return 0;
}