Download a file using URLDownloadToFile C function

Discussion in 'C' started by Scripting, Jul 13, 2012.

  1. Scripting

    Scripting John Hoder

    Joined:
    Jun 29, 2010
    Messages:
    421
    Likes Received:
    57
    Trophy Points:
    0
    Occupation:
    School for life
    Location:
    /root

    Using URLDownloadToFile function



    In this article I would want to show you how to download a file from internet using URLDownloadToFile function in C language. I think everybody has ever experienced the downloading a file with Internet Explorer. IE is using directly this function, but It uses some callback and GUI stuff too, I will show you how to download a file without any comlex callbacks nor GUI, it's gonna be pure download performing code.

    So here we go.

    Stuff needed:

    1. Internet Explorer 3.0 (or just urlmon.dll library)
    2. Internet connection (to make sure it works)
    3. C Compiler (I used Dev-C++ but code is optimized to work with every compiler)
    The syntax of the function is following:
    Code:
    HRESULT URLDownloadToFile(
      LPUNKNOWN pCaller,
      LPCTSTR szURL,
      LPCTSTR szFileName,
      _Reserved_  DWORD dwReserved,
      LPBINDSTATUSCALLBACK lpfnCB
    );
    
    • pCaller - This argument has to do something with ActiveX component, but I won't cover this in the tutorial, thus it will be always NULL unless we want to use ActiveX.
    • szURL - A pointer to a string value that contains the URL to download. Cannot be set to NULL. If the URL is invalid, INET_E_DOWNLOAD_FAILURE is returned.
    • szFileName - A pointer to a string value containing the name or full path of the file to create for the download. If szFileName includes a path, the target directory must already exist.
    • dwReserved - Even I don't know exactly what's that good for, but we will always use 0 for this...
    • lpfnCBv - this param is used to receive download status, but his really another level :D, will be always NULL for our basic purposes

    Ok, so what can this function return?

    • S_OK - The S_OK return value just indicates that the download has started properly. Not that it has finished downloading, (for that information you will have to use the LPBINDSTATUSCALLBACK lpfnCB parameter to get a status callback). Note that it returns S_OK even if the file download succeeds but the file creation fails (e.g. because you specified a non-existent folder, drive, etc). Hence, you should ensure the file exists before attempting to operate on it.
    • E_OUTOFMEMORY - This is returned when the buffer length is invalid, or there is insufficient memory to complete the operation.

    These two were the most common return codes, but as you may think, it's far not everything.

    I won't describe another return codes, as they are very rare and not used commonly.
    But here is shor list of them (still not all :D)

    INET_E_INVALID_URL (800C000)
    INET_E_NO_SESSION (800C0003)
    INET_E_CANNOT_CONNECT (800C0004)
    INET_E_RESOURCE_NOT_FOUND (800C0005)
    INET_E_OBJECT_NOT_FOUND (800C0006)
    INET_E_DATA_NOT_AVAILABLE (800C0007)
    INET_E_DOWNLOAD_FAILURE (800C0008)
    INET_E_AUTHENTICATION_REQUIRED (800C0009)
    INET_E_NO_VALID_MEDIA (800C000A)
    INET_E_CONNECTION_TIMEOUT (800C000B)
    INET_E_INVALID_REQUEST (800C000C)
    INET_E_UNKNOWN_PROTOCOL (800C000D)
    INET_E_SECURITY_PROBLEM (800C000E)
    INET_E_CANNOT_LOAD_DATA (800C000F)
    INET_E_CANNOT_INSTANTIATE_OBJECT (800C0010)
    INET_E_INVALID_CERTIFICATE (800C0019)
    INET_E_REDIRECT_FAILED (800C0014)
    INET_E_REDIRECT_TO_DIR (800C0015)
    INET_E_CANNOT_LOCK_REQUEST (800C0016)
    INET_E_USE_EXTEND_BINDING (800C0017)
    INET_E_TERMINATED_BIND (800C0018)
    INET_E_ERROR_FIRST (800C0002)
    INET_E_CODE_DOWNLOAD_DECLINED (800C0100)
    INET_E_RESULT_DISPATCHED (800C0200)
    INET_E_CANNOT_REPLACE_SFP_FILE (800C0300)
    INET_E_CODE_INSTALL_SUPPRESSED (800C0400)
    INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY (800C0500)


    Complete Code



    Code:
    #include <windows.h>
    #include <stdio.h>
    
    #define MAX_LINE 512
    
    int main()
    {
        char url[MAX_LINE] = "http://www.earthcalendar.net/index.php";
        char destination[MAX_LINE] = "index.php";
        char buffer[MAX_LINE];
    
        HRESULT    dl;
        
        typedef HRESULT (WINAPI * URLDownloadToFileA_t)(LPUNKNOWN pCaller, LPCSTR szURL, LPCSTR szFileName, DWORD dwReserved, void * lpfnCB);
        URLDownloadToFileA_t xURLDownloadToFileA;
        xURLDownloadToFileA = (URLDownloadToFileA_t)GetProcAddress(LoadLibraryA("urlmon"), "URLDownloadToFileA");
    
        dl = xURLDownloadToFileA(NULL, url, destination, 0, NULL);
    
        sprintf( buffer, "Downloading File From: %s, To: %s", url, destination);
        
        if(dl == S_OK) 
        {
            sprintf(buffer, "File Successfully Downloaded To: %s", destination);
            printf(buffer);
        } 
        else if(dl == E_OUTOFMEMORY) 
        {
            sprintf(buffer, "Failed To Download File Reason: Insufficient Memory");
            printf(buffer);
            return 0;
        } 
        else 
        {
            sprintf( buffer, "Failed To Download File Reason: Unknown");
            printf(buffer);
            return 0;
        }
    }
    
    
    The only 2 hearders needed for this code are stdio and windows.h. into variable "url" is assigned the url address of the file we want to download, I chose some index.php from a random site. The variable destination represents the name of file, the file after download will have this name.

    I used typdef and loading a function from library becau e some older compilers (ie. Dev-C++) may not work with classic declaration URLDownloadToFile, since it's outdated compiler. I wanted to make the code as compatible with all compilers as I could.
    Then the return codes are checked and proper message is displayed.

    I think everything else should be clear.

    Conclusion



    There are also some other ways (APIs) to download a file from internet, maybe I will write some more articles about other ways to achieve it :) Stay tuned!

    Hope it was not that difficult to understand.

    Some info taken from MSDN :)
     
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
  3. Scripting

    Scripting John Hoder

    Joined:
    Jun 29, 2010
    Messages:
    421
    Likes Received:
    57
    Trophy Points:
    0
    Occupation:
    School for life
    Location:
    /root
    Haha, I know, nevertheless it's one of the requirements :D
     
  4. Naresh Twanabasu

    Naresh Twanabasu New Member

    Joined:
    Oct 12, 2011
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    Occupation:
    student
    Location:
    Bhaktapur, Nepal
    can it help to download file with *.pwd and *.swf ?
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice