Retrieving the Reply from an Upload-Reply Job

A BITS Upload-Reply job, in addition to uploading a file to a server, will also examine a reply URL sent as part of the server reply and then automatically follow the reply URL and download a response from it. See the Ack for Fragment documentation for more details about the BITS-Reply-URL header value.

Set the job type as BG_JOB_TYPE_UPLOAD_REPLY to create an Upload-Reply type job. The reply data is available to the client after the job enters the BG_JOB_STATE_TRANSFERRED state. To retrieve the reply, call one of the following methods:

Call these methods in your IBackgroundCopyCallback::JobTransferred method only if the reply is small and can be processed quickly so as to not block the callback thread. If you use command line notification instead of the callback, pass the job identifier to the executable file. The executable file uses the job identifier to call the Complete method to make the reply file available.

The following examples show how to use each method to retrieve the reply data.

Using GetReplyData

The following example shows how to retrieve the reply data using the IBackgroundCopyJob2::GetReplyData method. The example assumes the IBackgroundCopyJob interface pointer is valid, the type of the job is upload-reply, and the state of the job is BG_JOB_STATE_TRANSFERRED.

HRESULT hr;
IBackgroundCopyJob* pJob;
IBackgroundCopyJob2* pJob2 = NULL;
BYTE* pReply = NULL;
UINT64 ReplySize;

//Need to query the IBackgroundCopyJob interface for an IBackgroundCopyJob2
//interface pointer. The IBackgroundCopyJob2 interface contains the GetReplyData method.
hr = pJob->QueryInterface(__uuidof(IBackgroundCopyJob2), (void**)&pJob2);
if (SUCCEEDED(hr))
{
    hr = pJob2->GetReplyData(&pReply, &ReplySize);
    if (S_OK == hr))
    {
        if (pReply)
        {
            //Do something with the data.
            CoTaskMemFree(pReply);
        }
        else
        {
            //The server application did not return a reply.
        }
    }
    else if (BG_E_TOO_LARGE == hr)
    {
        //The reply exceeds 1 MB. To retrieve the reply, get the reply file name,
        //complete the job, open the reply file, and read the reply.
    }
    else
    {
        //Handle the error
    }

    pJob2->Release(); //When done, release the interface.
}
else
{
    //Handle error. QueryInterface will return E_NOINTERFACE if the version of BITS
    //running on the computer is less than BITS 1.5.
}

Using GetReplyFileName

The following example shows how to retrieve the reply data using the IBackgroundCopyJob2::GetReplyFileName method. The example assumes the IBackgroundCopyJob interface pointer is valid, the type of job is upload-reply, and the state of the job is BG_JOB_STATE_TRANSFERRED.

HRESULT hr;
IBackgroundCopyJob* pJob;
IBackgroundCopyJob2* pJob2 = NULL;
WCHAR* pszFileName = NULL;

//Need to query the IBackgroundCopyJob interface for an IBackgroundCopyJob2
//interface pointer. The IBackgroundCopyJob2 interface contains the GetReplyFileName method.
hr = pJob->QueryInterface(__uuidof(IBackgroundCopyJob2), (void**)&pJob2);
if (SUCCEEDED(hr))
{
    hr = pJob2->GetReplyFileName(&pszFileName);
    if (SUCCEEDED(hr))
    {
        //Calling the Complete method removes the job from the queue, 
        //so make sure you maintain an interface pointer to this job 
        //or retrieve any job related information that you require 
        //when processing the reply.
        hr = pJob->Complete();

        //Open, read the file, and do something with the data.
        CoTaskMemFree(pszFileName);
    }

    pJob2->Release(); //When done, release the interface.
}
else
{
    //Handle error. QueryInterface will return E_NOINTERFACE if the version of BITS
    //running on the computer is less than BITS 1.5.
}