InternetManager Class Reference

Webster connection/download manager. It is responsible for schedulling downloads for execution according to the priority declared by the client on registration, ensuring that no more than a preset number of connections are open at any one time (important for users with limited bandwidth), and otherwise keeping track of their fate. The sheduling sheme is as follows: More...

#include <camnet.h>

Inheritance diagram for InternetManager:

CCObject SimpleCCObject List of all members.

Static Public Member Functions

static void Initialize ()
 
  • initialization function

static void OnExitInstance ()
 
  • close-down function

static BOOL AttemptConnection ()
static INT32 RegisterDownload (LPDOWNLOADINFO pDownloadInfo)
 register a new file download. The download will be started immediately if nothing else is pending; otherwise, it will just be queued up NOTES 1. Client objects are not directly notified of the outcome of the downloads they have registered. Callback functions called through pointers are not a very safe way to go as the pointer might not be valid anymore by the time the download is over. Instead, the client should poll the InternetManager for the result of the download, using the handle return by RegisterDownload(). Usually the client object will be derived from Operation so the polling could be done on IdleEvent() . 2. If the queue with the given priority is locked, the download is registered and you get a valid handle but it will immediatelly flagged as ABORTED. The queues are locked in response to a user cancel.
static BOOL UnregisterDownload (INT32 hDownload)
 unregisters a previously registered download. It behaves like the following:
  • if the download has already finished, the function will fail
  • if the download is in progress, it will be aborted on the next call from the callback object, and the AsynchDownload object deleted as soon as this call returns
  • if the download is still queued up, it will be removed from the queue and deleted

static AsynchDownload::State GetDownloadState (INT32 handle)
 Test the current state of a registered download - usually used in a loop polling for completion, either successful or failed.
static void CancelAllDownloads ()
 Aborts any downloads in progress and flushes both queues. Any download thus removed will be flagged as ABORTED. Should be called either if the user chooses to abort all downloads or we detect some severe network error that makes it pointless to continue.
static void Suspend ()
static void Resume ()
 Resumes normal downloading previously stopped by a call to Suspend().
static INT32 GetPercentageDownloaded (INT32 hDownload)
 monitor the percentage downloaded on a handle
static BOOL IsSuspended ()
static void SetConnectionType (ConnectionType type)
 
  • allows the altering of the default connection type (CONNECTION_SLOWMODEM) Setting this parameter accurately should result in improved download speed.

static ConnectionType GetConnectionType ()
 
  • retrieves the connection type the InternetManager is configured for. The connection type is inferred from the maximum number of connections that can be opened simultaneously

static bool GetProxyServer (SERVENT *pProxyEntry, bool *pbProxyEnabled)
static BOOL HasDownloadsPending ()

Static Public Attributes

static UINT32 g_ConnectionType = CONNECTION_SLOWMODEM
static UINT32 g_CacheSize = 5000

Private Member Functions

 CC_DECLARE_MEMDUMP (InternetManager)

Static Private Member Functions

static void OnDownloadComplete (AsynchDownload *pDownload)
 Callback function notifying the download manager the an object has completed downloading Used internally only.
static INT32 GetOpenConnections (AsynchDownload::Priority priority)
 used in scheduling downloads
static AsynchDownloadGetPendingDownload (const String_256 &strFileName)
 get a pointer to a download object knowing the the local file it's downloading to
static AsynchDownloadGetPendingDownload (INT32 handle)
 get a pointer to a download object knowing the download's handle
static AsynchDownloadGetDownload (INT32 handle)
 get a pointer to a download object knowing the download's handle
static AsynchDownloadGetCurrentNormalPriorityDownload ()
 provides access to thumbnail & catalog downloading (monitor/abort it, etc)
static void SetState (INT32 hDownload, AsynchDownload::State state)
 
  • Set the status of this download and inform the client of the change


Static Private Attributes

static INT32 m_NextHandle = 1L
static BOOL m_bIsSuspended = FALSE
static INT32 rgConnections [4] = {4, 8, 20, 64}
static INT32 nMaxConnections = 32
static CTypedPtrArray< CPtrArray,
AsynchDownload * > 
m_CurrentDownloads
static String_256 strTempFileURL
static DownloadQueue m_NormalPriorityQueue
static DownloadQueue m_HighPriorityQueue
static AsynchDownload::State m_StateTable [1000]

Friends

class AsynchDownload
class AsynchDownload::AsynchBindStatusCallback
class DownloadQueue

Detailed Description

Webster connection/download manager. It is responsible for schedulling downloads for execution according to the priority declared by the client on registration, ensuring that no more than a preset number of connections are open at any one time (important for users with limited bandwidth), and otherwise keeping track of their fate. The sheduling sheme is as follows:

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/12/96
In the present system thumbnail downloads should be registered with PRIORITY_NORMAL, clipart and catalog files should use PRIORITY_HIGH. Maybe types should be used instead of priorities, things might be a bit clearer if TYPE_THUMB and TYPE_CLIPART - for instance - were used instead of priorities. However, this is supposed to be a general purpose class not limited to downloading clipart. Comment: The interface is static so it can be accessed from anywhere in the program with the scope resolution operator ::

Definition at line 600 of file camnet.h.


Member Function Documentation

static BOOL InternetManager::AttemptConnection  )  [inline, static]
 

Definition at line 612 of file camnet.h.

00612 { return (InternetAttemptConnect(NULL) == ERROR_SUCCESS);}

void InternetManager::CancelAllDownloads  )  [static]
 

Aborts any downloads in progress and flushes both queues. Any download thus removed will be flagged as ABORTED. Should be called either if the user chooses to abort all downloads or we detect some severe network error that makes it pointless to continue.

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
none [INPUTS]
Returns:
none

Definition at line 2531 of file camnet.cpp.

02532 {
02533     // First empty the queues
02534     while (!m_HighPriorityQueue.IsEmpty())
02535     {
02536         AsynchDownload* pDownload = m_HighPriorityQueue.GetNextDownload();
02537         if (pDownload)
02538             UnregisterDownload(pDownload->GetHandle());
02539     }
02540     while (!m_NormalPriorityQueue.IsEmpty())
02541     {
02542         AsynchDownload* pDownload = m_NormalPriorityQueue.GetNextDownload();
02543         if (pDownload)
02544             UnregisterDownload(pDownload->GetHandle());
02545     }
02546     // Abort the downloads in progress if any
02547     // Note that we don't delete it straight away as we might leek resources if we did so - instead,
02548     // the object will be deleted when AbortDownload() (which is asynchronous) completes
02549     for (INT32 i = 0; i < m_CurrentDownloads.GetSize(); i++) 
02550     {
02551         HRESULT result = m_CurrentDownloads[i]->AbortDownload();
02552         ERROR3IF(result == E_FAIL , "Could not abort download");
02553     }
02554 }

InternetManager::CC_DECLARE_MEMDUMP InternetManager   )  [private]
 

ConnectionType InternetManager::GetConnectionType  )  [static]
 

  • retrieves the connection type the InternetManager is configured for. The connection type is inferred from the maximum number of connections that can be opened simultaneously

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
- [INPUTS]
Returns:
- one of CONNECTION_SLOWMODEM, CONNECTION_FASTMODEM, CONNECTION_X2, CONNECTION_ISDN

Definition at line 2709 of file camnet.cpp.

02710 {
02711     for (INT32 type = (INT32) CONNECTION_SLOWMODEM; type <= (INT32) CONNECTION_ISDN; type++)
02712     {
02713         if (rgConnections[type] == nMaxConnections) 
02714             break; 
02715     }
02716     return (ConnectionType) type;
02717 }

AsynchDownload * InternetManager::GetCurrentNormalPriorityDownload  )  [static, private]
 

provides access to thumbnail & catalog downloading (monitor/abort it, etc)

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
none [INPUTS]
Returns:
pointer to the currently executing normal priority download, NULL if none is found

Definition at line 2636 of file camnet.cpp.

02637 {
02638     AsynchDownload* pDownload = NULL;
02639     for (INT32 i = 0; i < m_CurrentDownloads.GetSize(); i++) 
02640     {
02641         if (m_CurrentDownloads[i]->GetPriority() == AsynchDownload::PRIORITY_NORMAL)
02642             pDownload = m_CurrentDownloads[i];
02643     }
02644     return pDownload;
02645 }

AsynchDownload * InternetManager::GetDownload INT32  hDownload  )  [static, private]
 

get a pointer to a download object knowing the download's handle

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
04/05/2004
Parameters:
hDownload [INPUTS]
Returns:
pointer to AsynchDownload object if found, NULL otherwise

Definition at line 2387 of file camnet.cpp.

02388 {
02389     AsynchDownload* pDownload = NULL;
02390 
02391     // Check the downloads currently executing
02392     for (INT32 i = 0; i < m_CurrentDownloads.GetSize(); i++) 
02393     {
02394         if (m_CurrentDownloads[i]->GetHandle() == hDownload)
02395             return m_CurrentDownloads[i];
02396     }
02397     // Check the download queues
02398     if (pDownload = m_NormalPriorityQueue.FindDownload(hDownload))
02399         return pDownload;
02400     pDownload = m_HighPriorityQueue.FindDownload(hDownload);
02401     return pDownload;
02402 }

AsynchDownload::State InternetManager::GetDownloadState INT32  hDownload  )  [static]
 

Test the current state of a registered download - usually used in a loop polling for completion, either successful or failed.

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
hDownload - handle of the download inquired on [INPUTS]
Returns:
a value of InternetManager::State type reflecting the state of the download: STATE_ERROR - the hDownload param is not valid or some other internal error occurred STATE_PENDING - download is still pending STATE_FAILED - download has failed through network or other "natural" errors STATE_SUCCEEDED - download has succeeded STATE_ABORTED - user cancel

Definition at line 2423 of file camnet.cpp.

02424 {
02425     // For quick access handles are used as indexes into the state table
02426     if ((hDownload < 1) || (hDownload >= MAX_HANDLE))
02427         return AsynchDownload::STATE_ERROR;
02428     else
02429         return m_StateTable[hDownload];
02430 }

INT32 InternetManager::GetOpenConnections AsynchDownload::Priority  priority  )  [static, private]
 

used in scheduling downloads

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
priority of the connections enquired about (enumerated type in AsynchDownload) [INPUTS]
Returns:
number of connections with the given priority which are currently open

Definition at line 2569 of file camnet.cpp.

02570 {
02571     INT32 nDownloads = 0;
02572     for (INT32 i = 0; i < m_CurrentDownloads.GetSize(); i++) 
02573     {
02574         if (m_CurrentDownloads[i]->GetPriority() == priority)
02575             nDownloads++;
02576     }
02577     return nDownloads;
02578 }

AsynchDownload * InternetManager::GetPendingDownload INT32  hDownload  )  [static, private]
 

get a pointer to a download object knowing the download's handle

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
hDownload [INPUTS]
Returns:
pointer to AsynchDownload object if found, NULL otherwise

Definition at line 2356 of file camnet.cpp.

02357 {
02358     AsynchDownload* pDownload = NULL;
02359     AsynchDownload::State downloadState = GetDownloadState(hDownload);
02360     if (downloadState != AsynchDownload::STATE_PENDING)
02361         return pDownload;
02362     // Check the downloads currently executing
02363     for (INT32 i = 0; i < m_CurrentDownloads.GetSize(); i++) 
02364     {
02365         if (m_CurrentDownloads[i]->GetHandle() == hDownload)
02366             return m_CurrentDownloads[i];
02367     }
02368     // Check the download queues
02369     if (pDownload = m_NormalPriorityQueue.FindDownload(hDownload))
02370         return pDownload;
02371     pDownload = m_HighPriorityQueue.FindDownload(hDownload);
02372     return pDownload;
02373 }

AsynchDownload * InternetManager::GetPendingDownload const String_256 strFileName  )  [static, private]
 

get a pointer to a download object knowing the the local file it's downloading to

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
strFileName [INPUTS]
Returns:
pointer to AsynchDownload object if found, NULL otherwise

Definition at line 2308 of file camnet.cpp.

02309 {
02310     AsynchDownload* pDownload = NULL;
02311     String_256 strLocalFileName(strFileName);
02312     // Check the downloads currently executing
02313     for (INT32 i = 0; i < m_CurrentDownloads.GetSize(); i++) 
02314         if (!strLocalFileName.CompareTo(m_CurrentDownloads[i]->GetLocalFileName(), FALSE))
02315             return m_CurrentDownloads[i];
02316     // Check the download queues
02317     if (pDownload = m_NormalPriorityQueue.FindDownload(strLocalFileName))
02318         return pDownload;
02319     pDownload = m_HighPriorityQueue.FindDownload(strLocalFileName);
02320     return pDownload;
02321 }

INT32 InternetManager::GetPercentageDownloaded INT32  hDownload  )  [static]
 

monitor the percentage downloaded on a handle

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
hDownload [INPUTS]
Returns:
an INT32 in the range of 0-100 if the handle is valid, -1 otherwise

Definition at line 2335 of file camnet.cpp.

02336 {
02337     AsynchDownload* pDownload = GetPendingDownload(hDownload);
02338     if (pDownload)
02339         return pDownload->GetPercentageDownloaded();
02340     else
02341         return -1;
02342 }

bool InternetManager::GetProxyServer SERVENT *  pProxyEntry,
bool *  pbProxyEnabled
[static]
 

Definition at line 2728 of file camnet.cpp.

02729 {
02730     // Get the current proxy settings
02731     TCHAR szProxy[_MAX_PATH];
02732     String_256 KeySectionName(TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"));
02733     HKEY hKey = OpenRegKey(HKEY_CURRENT_USER, KeySectionName);
02734     if (hKey)
02735     {
02736         String_256 ProxyServer;
02737         BOOL ok = GetRegString(hKey, TEXT("ProxyServer"), &ProxyServer);
02738         if (ok)
02739             camStrcpy(szProxy, (TCHAR*)ProxyServer);
02740         *pbProxyEnabled = GetRegBool(hKey, TEXT("ProxyEnable")) == TRUE;
02741         CloseRegKey(hKey);
02742     }
02743 
02744     // If the string is blank then the proxy must be off
02745     if (!camStrlen(szProxy))
02746     {
02747         *pbProxyEnabled = false;
02748         return true;
02749     }
02750 
02751     String_256 strHost, strPort;
02752     TCHAR tchBuff[_MAX_PATH];
02753     camStrcpy(tchBuff, szProxy);
02754     TCHAR* lpszTemp = NULL;
02755     lpszTemp = camStrstr(tchBuff, _T("http="));
02756     if (lpszTemp != NULL)
02757     {
02758         strHost = _tcstok((lpszTemp + 5), _T(":"));
02759         strPort = _tcstok(NULL, _T(";"));
02760     }
02761     else
02762     {
02763         strHost = _tcstok(tchBuff, _T(":"));
02764         strPort = _tcstok(NULL, _T(";"));
02765     }
02766     if (!camStrlen(strHost) || !camStrlen(strPort))
02767     {
02768         *pbProxyEnabled = false;
02769         return true;
02770     }
02771 
02772     camStrcpy(pProxyEntry->s_name, strHost);
02773     pProxyEntry->s_port = (unsigned short) atoi(strPort);
02774     return true;
02775 }

static BOOL InternetManager::HasDownloadsPending  )  [inline, static]
 

Definition at line 638 of file camnet.h.

void InternetManager::Initialize  )  [static]
 

  • initialization function

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
- [INPUTS]
Returns:
-

Definition at line 2036 of file camnet.cpp.

02037 {
02038     WORD wVersionRequested; // first initialize to socket library
02039     WSADATA wsaData; 
02040     wVersionRequested = MAKEWORD(1, 1); 
02041     if (::WSAStartup(wVersionRequested, &wsaData))
02042         InformError(_R(IDS_SOCKETNOTINITIALIZED));
02043     m_HighPriorityQueue.SetType(DownloadQueue::LIFO); // the high priority queue is LIFO by default
02044     String_256 strCachePath;
02045     GetAppCachePath(&strCachePath);
02046     DownloadCache::SetPath(strCachePath);
02047     /*if (!DownloadCache::m_CacheMonitor.Activate(strCachePath))
02048     {
02049         ERROR3("Cannot activate the cache monitor");
02050     }*/
02051 /*
02052     // This code is an abortion and unmaintainable. Why not use the preference system?
02053     HKEY arhKeys[6];
02054     DWORD dwConnectionType = 0L;
02055     UINT32 lCacheSize = 0L;
02056     DWORD dwSizeofDword = sizeof(DWORD), dwSizeofLong = sizeof(INT32);
02057     DWORD dwDisposition;
02058     memset(arhKeys, 0, sizeof(arhKeys));
02059     String_256 strProgramKey = GetProgramNameRegistryKey();
02060     BOOL bResult = ((RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &arhKeys[0]) == ERROR_SUCCESS) &&
02061         (RegCreateKeyEx(arhKeys[0], _tcstok(strProgramKey, _T("\\")),  0, NULL, REG_OPTION_NON_VOLATILE,  KEY_ALL_ACCESS, NULL, &arhKeys[1], &dwDisposition) == ERROR_SUCCESS) &&
02062         (RegCreateKeyEx(arhKeys[1], _tcstok(NULL, _T("\\")),  0, NULL, REG_OPTION_NON_VOLATILE,  KEY_ALL_ACCESS, NULL, &arhKeys[2], &dwDisposition) == ERROR_SUCCESS) &&
02063         (RegCreateKeyEx(arhKeys[2], _tcstok(NULL, _T("\\")),  0, NULL, REG_OPTION_NON_VOLATILE,  KEY_ALL_ACCESS, NULL, &arhKeys[3], &dwDisposition) == ERROR_SUCCESS) &&
02064         (RegCreateKeyEx(arhKeys[3], _T("Options"),  0, NULL, REG_OPTION_NON_VOLATILE,  KEY_ALL_ACCESS, NULL, &arhKeys[4], &dwDisposition) == ERROR_SUCCESS) &&
02065         (RegCreateKeyEx(arhKeys[4], _T("Internet"),  0, NULL, REG_OPTION_NON_VOLATILE,  KEY_ALL_ACCESS, NULL, &arhKeys[5], &dwDisposition) == ERROR_SUCCESS) &&
02066         (RegQueryValueEx(arhKeys[5], _T("Connection Type"), NULL, NULL, (LPBYTE) &dwConnectionType, &dwSizeofDword) == ERROR_SUCCESS) && 
02067         (RegQueryValueEx(arhKeys[5], _T("Cache Size"),  NULL, NULL, (LPBYTE) &lCacheSize, &dwSizeofLong) == ERROR_SUCCESS));
02068     for (INT32 i = 5; i >= 0; i--) RegCloseKey(arhKeys[i]);
02069     if (bResult)
02070     {
02071         nMaxConnections = rgConnections[dwConnectionType];
02072         DownloadCache::SetSize(lCacheSize);
02073     }
02074     else
02075         SetConnectionType(CONNECTION_SLOWMODEM); // we default to the most prudent setting 
02076 */
02077 
02078     if (Camelot.DeclareSection(TEXT("Internet"), 4))
02079     {
02080         Camelot.DeclarePref(NULL, TEXT("Connection Type"), &g_ConnectionType, 0, 3);
02081         Camelot.DeclarePref(NULL, TEXT("Cache Size"), &g_CacheSize, 64 * SIZEOFKILOBYTE);
02082     }
02083     nMaxConnections = rgConnections[g_ConnectionType];
02084     DownloadCache::SetSize(g_CacheSize);
02085 }

static BOOL InternetManager::IsSuspended  )  [inline, static]
 

Definition at line 630 of file camnet.h.

00630 {return m_bIsSuspended;}

void InternetManager::OnDownloadComplete AsynchDownload pDownload  )  [static, private]
 

Callback function notifying the download manager the an object has completed downloading Used internally only.

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
pDownload - pointer to object sending the notification [INPUTS]
Returns:
none

Definition at line 2446 of file camnet.cpp.

02447 {
02448     if (!pDownload)
02449     {
02450         ERROR3("Unexpected NULL pointer");
02451         return;
02452     }
02453     if (pDownload->HasSucceeded())
02454     {
02455 //      m_StateTable[pDownload->GetHandle()] = AsynchDownload::STATE_SUCCEEDED;
02456         DownloadCache::InsertFile(pDownload->GetLocalFileName());
02457         SetState(pDownload->GetHandle(), AsynchDownload::STATE_SUCCEEDED);
02458     }
02459     else
02460     {
02461         if (pDownload->WasAborted()) // user cancel
02462 //          m_StateTable[pDownload->GetHandle()] = AsynchDownload::STATE_ABORTED;   
02463             SetState(pDownload->GetHandle(), AsynchDownload::STATE_ABORTED);
02464         else // failed through network or other errors
02465 //          m_StateTable[pDownload->GetHandle()] = AsynchDownload::STATE_FAILED;
02466             SetState(pDownload->GetHandle(), AsynchDownload::STATE_FAILED);
02467     }
02468     
02469     // Remove the download from its slot 
02470     INT32 nSlot = -1;
02471     for (INT32 i = 0; i < m_CurrentDownloads.GetSize(); i++) 
02472     {
02473         if (m_CurrentDownloads[i] == pDownload)
02474             nSlot = i;
02475     }
02476     ERROR3IF(nSlot == -1, "Download terminated without being executed");
02477     if (nSlot != -1)
02478         m_CurrentDownloads.RemoveAt(nSlot);
02479     if (!strTempFileURL.IsEmpty())
02480     {
02481         UnlockUrlCacheEntryFile((TCHAR*) strTempFileURL, 0);
02482         DeleteUrlCacheEntry((TCHAR*) strTempFileURL); // nb: this call may fail if the file is still locked for some reason
02483     }
02484     strTempFileURL = pDownload->GetTargetURL(); // URL of temp file to be removed on the next call
02485     if (nSlot != -1)
02486         pDownload->Release();
02487     if (m_bIsSuspended) // if suspended simply return
02488         return;
02489     // Start the next download in the queues, if any - we should have at least one connection available
02490     while ((!m_HighPriorityQueue.IsEmpty() || !m_NormalPriorityQueue.IsEmpty()) && m_CurrentDownloads.GetSize() < nMaxConnections)
02491     {
02492         AsynchDownload* pNextDownload = m_HighPriorityQueue.GetNextDownload();
02493         if (!pNextDownload)
02494         {
02495             // the high priority queue is empty; we'll start a normal priority one if none is already executing or the queue is not
02496             // locked
02497             if  (!GetOpenConnections(AsynchDownload::PRIORITY_NORMAL))
02498                 pNextDownload = m_NormalPriorityQueue.GetNextDownload();
02499         }
02500         if (!pNextDownload) // both queues empty or locked
02501             return;
02502         if (!SUCCEEDED(pNextDownload->StartDownload()))
02503         {
02504 //          m_StateTable[pNextDownload->GetHandle()] = AsynchDownload::STATE_FAILED;
02505             SetState(pNextDownload->GetHandle(), AsynchDownload::STATE_FAILED);
02506             pNextDownload->Release();
02507         }
02508         else
02509         {
02510             // add it the array of executing downloads
02511             m_CurrentDownloads.Add(pNextDownload);
02512             TRACEUSER( "adrian", _T("Download fired up for %s\n"), (TCHAR*) String_256(pNextDownload->GetLocalFileName())); 
02513         }
02514     }
02515 }

void InternetManager::OnExitInstance  )  [static]
 

  • close-down function

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
- [INPUTS]
Returns:
-

Definition at line 2099 of file camnet.cpp.

02100 {
02101     ::WSACleanup();
02102     /*if (!DownloadCache::m_CacheMonitor.Deactivate())
02103     {
02104         ERROR3("Cannot deactivate the cache monitor - likely to leak on exit");
02105     }*/
02106 
02107     // ensure there are no downloads left behind
02108     if (HasDownloadsPending())
02109     {
02110         m_HighPriorityQueue.Flush();
02111         m_NormalPriorityQueue.Flush();
02112         for (INT32 i = 0; i < m_CurrentDownloads.GetSize(); i++) 
02113         {
02114             if (m_CurrentDownloads[i])
02115                 m_CurrentDownloads[i]->Release();
02116         }
02117     }
02118     // Remove the last downloaded file from the cache, if any
02119     if (!strTempFileURL.IsEmpty())
02120     {
02121         UnlockUrlCacheEntryFile((TCHAR*) strTempFileURL, 0);
02122         DeleteUrlCacheEntry((TCHAR*) strTempFileURL); // nb: this call may fail if the file is still locked for some reason
02123     }
02124 }

INT32 InternetManager::RegisterDownload LPDOWNLOADINFO  pDownloadInfo  )  [static]
 

register a new file download. The download will be started immediately if nothing else is pending; otherwise, it will just be queued up NOTES 1. Client objects are not directly notified of the outcome of the downloads they have registered. Callback functions called through pointers are not a very safe way to go as the pointer might not be valid anymore by the time the download is over. Instead, the client should poll the InternetManager for the result of the download, using the handle return by RegisterDownload(). Usually the client object will be derived from Operation so the polling could be done on IdleEvent() . 2. If the queue with the given priority is locked, the download is registered and you get a valid handle but it will immediatelly flagged as ABORTED. The queues are locked in response to a user cancel.

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
pDownloadInfo - pointer to DOWNLOADINFO struct [INPUTS]
Returns:
non-zero download handle if successful, 0 otherwise
SUBSEQUENT NOTES by Phil: 04/05/2004 Client objects CAN now be notified of the outcome of the downloads. (Idle polling of the download status was thought to be too tacky.) RegisterDownload now takes in a window handle parameter and token parameter. If the handle is valid and the token is non-zero then custom messages will be sent to that window containing the token. The handler of those messages can use the token to decide which object should receive the notification.

Definition at line 2158 of file camnet.cpp.

02159 {
02160     if (m_NextHandle == 1L) // first download, initialise the state table
02161         memset(m_StateTable, 0, sizeof(m_StateTable));
02162 
02163     // Check if the download has been previously registered - if so, return the same handle
02164     AsynchDownload* pPreviousDownload = GetPendingDownload(pDownloadInfo->strLocalFile);
02165     if (pPreviousDownload)
02166         return pPreviousDownload->GetHandle();
02167 
02168     DOWNLOAD_HANDLE handle = m_NextHandle;
02169     m_NextHandle++;
02170     if (camStrstr((TCHAR*) pDownloadInfo->strURL, _T("file://")))
02171     {
02172         PathNameEx(pDownloadInfo->strLocalFile).CreateLocation();
02173 #ifdef UNICODE
02174         WCHAR wchURL[INTERNET_MAX_PATH_LENGTH];
02175         MultiByteToWideChar(CP_ACP, 0,  (TCHAR*) pDownloadInfo->strURL, -1, wchURL, INTERNET_MAX_PATH_LENGTH);
02176         if (SUCCEEDED(::URLDownloadToFile(NULL, wchURL, (TCHAR*) pDownloadInfo->strLocalFile, 0, NULL)))
02177 #else
02178         if (SUCCEEDED(::URLDownloadToFile(NULL, (TCHAR*) pDownloadInfo->strURL, (TCHAR*) pDownloadInfo->strLocalFile, 0, NULL)))
02179 #endif
02180 //          m_StateTable[handle] = AsynchDownload::STATE_SUCCEEDED;
02181             SetState(handle, AsynchDownload::STATE_SUCCEEDED);
02182         else
02183 //          m_StateTable[handle] = AsynchDownload::STATE_FAILED;
02184             SetState(handle, AsynchDownload::STATE_FAILED);
02185         return handle;
02186     }
02187     AsynchDownload* pDownload = new AsynchDownload(handle, pDownloadInfo);
02188     if (!pDownload)
02189     {
02190         ERROR3("Memory allocation error");
02191         return (DOWNLOAD_HANDLE) INVALID_HANDLE_VALUE;
02192     }
02193 //  m_StateTable[handle] = AsynchDownload::STATE_PENDING;
02194     SetState(handle, AsynchDownload::STATE_PENDING);
02195     if (m_CurrentDownloads.GetSize() < nMaxConnections && !m_bIsSuspended) // can start it straight away
02196     {
02197         if (pDownloadInfo->nPriority == AsynchDownload::PRIORITY_NORMAL && GetOpenConnections(AsynchDownload::PRIORITY_NORMAL))
02198             goto QUEUE; // this is a normal pDownloadInfo->nPriority download and we already have one executing, so we just queue it up
02199         if (!SUCCEEDED(pDownload->StartDownload()))
02200         {
02201 //          m_StateTable[handle] = AsynchDownload::STATE_FAILED;
02202             SetState(handle, AsynchDownload::STATE_FAILED);
02203             pDownload->Release();
02204         }
02205         else
02206         {
02207             // add it to the array of executing downloads
02208             m_CurrentDownloads.Add(pDownload);
02209             if (pDownloadInfo->nPriority == AsynchDownload::PRIORITY_NORMAL)
02210             TRACEUSER( "adrian", _T("Download fired up for %s\n"), (TCHAR*) String_256(pDownload->GetLocalFileName())); 
02211         }
02212     }
02213     else
02214     {
02215 QUEUE:
02216         // queue the download, as we shouldn't exceed the allowed number of connections
02217         if (pDownloadInfo->nPriority == AsynchDownload::PRIORITY_NORMAL)
02218             m_NormalPriorityQueue.Queue(pDownload);
02219         else
02220         {
02221             // switch the high pDownloadInfo->nPriority queue to FIFO mode if this is a thumbnail
02222             if (pDownloadInfo->nFileType == TYPE_THUMBNAIL)
02223                 m_HighPriorityQueue.SetType(DownloadQueue::FIFO);
02224             m_HighPriorityQueue.Queue(pDownload);
02225             if (pDownloadInfo->nFileType == TYPE_THUMBNAIL)
02226                 m_HighPriorityQueue.SetType(DownloadQueue::LIFO); // back to default (LIFO) mode
02227         }
02228     }
02229     return handle;
02230 }

void InternetManager::Resume  )  [static]
 

Resumes normal downloading previously stopped by a call to Suspend().

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
none [INPUTS]
Returns:
none

Definition at line 2595 of file camnet.cpp.

02596 {
02597     m_bIsSuspended = FALSE;
02598     while ((!m_HighPriorityQueue.IsEmpty() || !m_NormalPriorityQueue.IsEmpty()) && m_CurrentDownloads.GetSize() < nMaxConnections)
02599     {
02600         AsynchDownload* pNextDownload = m_HighPriorityQueue.GetNextDownload();
02601         if (!pNextDownload)
02602         {
02603             // the high priority queue is empty; we'll start a normal priority one if none is already executing or the queue is not
02604             // locked
02605             if  (!GetOpenConnections(AsynchDownload::PRIORITY_NORMAL))
02606                 pNextDownload = m_NormalPriorityQueue.GetNextDownload();
02607         }
02608         if (!pNextDownload) // both queues empty or locked
02609             return;
02610         if (!SUCCEEDED(pNextDownload->StartDownload()))
02611         {
02612 //          m_StateTable[pNextDownload->GetHandle()] = AsynchDownload::STATE_FAILED;
02613             SetState(pNextDownload->GetHandle(), AsynchDownload::STATE_FAILED);
02614             pNextDownload->Release();
02615         }
02616         else
02617         {
02618             // add it the array of executing downloads
02619             m_CurrentDownloads.Add(pNextDownload);
02620             TRACEUSER( "adrian", _T("Download fired up for %s\n"), (TCHAR*) String_256(pNextDownload->GetLocalFileName())); 
02621         }
02622     }
02623 }

void InternetManager::SetConnectionType ConnectionType  type  )  [static]
 

  • allows the altering of the default connection type (CONNECTION_SLOWMODEM) Setting this parameter accurately should result in improved download speed.

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
type - one of CONNECTION_SLOWMODEM, CONNECTION_FASTMODEM, [INPUTS] CONNECTION_X2, CONNECTION_ISDN
Returns:
-

Definition at line 2662 of file camnet.cpp.

02663 {
02664     // Save away the type in our preference variable
02665     g_ConnectionType = type;
02666     // Now set the new number of maximum connections according to this
02667     nMaxConnections = rgConnections[type];
02668 
02669     // When the user sets their coannection speed explicitly, we should also
02670     // update the flag that the helkp and support download system uses
02671     if (type==CONNECTION_ISDN)
02672         HelpDownloadOp::HighBandwidth = TRUE;
02673     else
02674         HelpDownloadOp::HighBandwidth = FALSE;
02675 
02676 /*
02677     // This code is an abortion and unmaintainable. Why not use the preference system?
02678     HKEY arhKeys[6];
02679     DWORD dwConnectionType = (DWORD) type;
02680     DWORD dwDisposition;
02681     memset(arhKeys, 0, sizeof(arhKeys));
02682     String_256 strProgramKey = GetProgramNameRegistryKey();
02683     BOOL bResult = ((RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &arhKeys[0]) == ERROR_SUCCESS) &&
02684         (RegCreateKeyEx(arhKeys[0], _tcstok(strProgramKey, _T("\\")),  0, NULL, REG_OPTION_NON_VOLATILE,  KEY_ALL_ACCESS, NULL, &arhKeys[1], &dwDisposition) == ERROR_SUCCESS) &&
02685         (RegCreateKeyEx(arhKeys[1], _tcstok(NULL, _T("\\")),  0, NULL, REG_OPTION_NON_VOLATILE,  KEY_ALL_ACCESS, NULL, &arhKeys[2], &dwDisposition) == ERROR_SUCCESS) &&
02686         (RegCreateKeyEx(arhKeys[2], _tcstok(NULL, _T("\\")),  0, NULL, REG_OPTION_NON_VOLATILE,  KEY_ALL_ACCESS, NULL, &arhKeys[3], &dwDisposition) == ERROR_SUCCESS) &&
02687         (RegCreateKeyEx(arhKeys[3], _T("Options"),  0, NULL, REG_OPTION_NON_VOLATILE,  KEY_ALL_ACCESS, NULL, &arhKeys[4], &dwDisposition) == ERROR_SUCCESS) &&
02688         (RegCreateKeyEx(arhKeys[4], _T("Internet"),  0, NULL, REG_OPTION_NON_VOLATILE,  KEY_ALL_ACCESS, NULL, &arhKeys[5], &dwDisposition) == ERROR_SUCCESS) &&
02689         (RegSetValueEx(arhKeys[5], _T("Connection Type"),   NULL, REG_DWORD, (LPBYTE) &dwConnectionType,    sizeof(dwConnectionType)) == ERROR_SUCCESS));
02690     for (INT32 i = 5; i >= 0; i--) RegCloseKey(arhKeys[i]);
02691     ERROR3IF(!bResult, "Failed to save changes to registry");
02692 */
02693  }

void InternetManager::SetState INT32  hDownload,
AsynchDownload::State  state
[static, private]
 

  • Set the status of this download and inform the client of the change

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
04/05/2004
Parameters:
- [INPUTS]
Returns:
-

Definition at line 2788 of file camnet.cpp.

02789 {
02790     m_StateTable[hDownload] = state;
02791 
02792     // -------------------------------------
02793     // Find the download object
02794     AsynchDownload* pDownload = GetDownload(hDownload);
02795 
02796     // -------------------------------------
02797     // If we have it then see whether the client wants to be notified
02798     if (pDownload)
02799     {
02800         HWND hwndNotify = pDownload->GetNotifyHWND();
02801         INT32 lNotifyToken = pDownload->GetNotifyToken();
02802         if (hwndNotify && lNotifyToken)
02803         {
02804             // Send the message to the client without waiting
02805             ::PostMessage(hwndNotify, WM_USER_DOWNLOADSTATUS, state, lNotifyToken);
02806         }
02807     }
02808 }

static void InternetManager::Suspend  )  [inline, static]
 

Definition at line 624 of file camnet.h.

00624 {m_bIsSuspended = TRUE;}

BOOL InternetManager::UnregisterDownload INT32  hDownload  )  [static]
 

unregisters a previously registered download. It behaves like the following:

  • if the download has already finished, the function will fail
  • if the download is in progress, it will be aborted on the next call from the callback object, and the AsynchDownload object deleted as soon as this call returns
  • if the download is still queued up, it will be removed from the queue and deleted

Author:
Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/96
Parameters:
hDownload - handle of download as returned by a previous call to RegisterDownload() [INPUTS]
Returns:
TRUE if succeeds, FALSE

Definition at line 2250 of file camnet.cpp.

02251 {
02252     AsynchDownload::State downloadState = GetDownloadState(hDownload);
02253     if (downloadState == AsynchDownload::STATE_PENDING) // download is still pending, i.e. either happening now or queued up
02254     {
02255         AsynchDownload* pDownload = GetPendingDownload(hDownload);
02256         if (!pDownload)
02257         {
02258             ERROR3("Unexpected NULL pointer");
02259             return FALSE;
02260         }
02261         // We flag the download as aborted, although we may not be able to abort it immediately - it might even succeed in the mean time
02262         m_StateTable[pDownload->GetHandle()] = AsynchDownload::STATE_ABORTED; 
02263 // Call SetState???
02264         // Find out if the download is actually executing
02265         BOOL bIsExecuting = FALSE;
02266         for (INT32 i = 0; i < m_CurrentDownloads.GetSize(); i++) 
02267         {
02268             if (m_CurrentDownloads[i] == pDownload)
02269                 bIsExecuting = TRUE;
02270         }
02271         if (bIsExecuting) // download happening now
02272         {
02273             // Abort the download. Note that we don't delete it, doing so would result in a leak of socket resources.
02274             // AbortDownload() is asynchronous and returns immediately - the download will actually be aborted
02275             // when the server acknowedges the TCP_RESET message and closes the connection so Winsock.dll
02276             // can close its open socket.
02277             HRESULT result = pDownload->AbortDownload();
02278             ERROR3IF(result == E_FAIL, "Could not abort download");
02279         }
02280         else // download is still in one of the queues
02281         {
02282             if (m_NormalPriorityQueue.Remove(pDownload) || m_HighPriorityQueue.Remove(pDownload))
02283                 return TRUE;
02284             else
02285             {
02286                 ERROR3("Failed to unregister download");
02287                 return FALSE;
02288             }
02289         }
02290     }
02291     return TRUE;
02292 }


Friends And Related Function Documentation

friend class AsynchDownload [friend]
 

Definition at line 663 of file camnet.h.

friend class AsynchDownload::AsynchBindStatusCallback [friend]
 

Definition at line 664 of file camnet.h.

friend class DownloadQueue [friend]
 

Definition at line 665 of file camnet.h.


Member Data Documentation

UINT32 InternetManager::g_CacheSize = 5000 [static]
 

Definition at line 671 of file camnet.h.

UINT32 InternetManager::g_ConnectionType = CONNECTION_SLOWMODEM [static]
 

Definition at line 670 of file camnet.h.

BOOL InternetManager::m_bIsSuspended = FALSE [static, private]
 

Definition at line 644 of file camnet.h.

CTypedPtrArray< CPtrArray, AsynchDownload * > InternetManager::m_CurrentDownloads [static, private]
 

Definition at line 647 of file camnet.h.

DownloadQueue InternetManager::m_HighPriorityQueue [static, private]
 

Definition at line 650 of file camnet.h.

INT32 InternetManager::m_NextHandle = 1L [static, private]
 

Definition at line 643 of file camnet.h.

DownloadQueue InternetManager::m_NormalPriorityQueue [static, private]
 

Definition at line 649 of file camnet.h.

AsynchDownload::State InternetManager::m_StateTable [static, private]
 

Definition at line 651 of file camnet.h.

INT32 InternetManager::nMaxConnections = 32 [static, private]
 

Definition at line 646 of file camnet.h.

INT32 InternetManager::rgConnections = {4, 8, 20, 64} [static, private]
 

Definition at line 645 of file camnet.h.

String_256 InternetManager::strTempFileURL [static, private]
 

Definition at line 648 of file camnet.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:55:32 2007 for Camelot by  doxygen 1.4.4