bits com链路记录
前言:bits com链路记录
参考文章:https://lolbas-project.github.io/lolbas/Binaries/Bitsadmin/
参考文章:https://learn.microsoft.com/en-us/windows/win32/api/bits/nn-bits-ibackgroundcopycallback
参考文章:https://learn.microsoft.com/en-us/windows/win32/api/bits/nf-bits-ibackgroundcopymanager-createjob
参考文章:https://learn.microsoft.com/en-us/windows/win32/api/bits1_5/nf-bits1_5-ibackgroundcopyjob2-setnotifycmdline
bits com下载文件
#include <iostream>
#include <windows.h>
#include <Bits.h>
#pragma comment(lib, "bits")
int wmain(int argc, wchar_t* argv[])
{
if (argc != 3) {
std::wcerr << L"Usage: BITSCOMClient.exe <source_url> <destination_path>\n";
return 1;
}
if (FAILED(CoInitialize(nullptr))) return 1;
IBackgroundCopyManager* pMgr;
if (FAILED(CoCreateInstance(CLSID_BackgroundCopyManager, nullptr, CLSCTX_ALL,
IID_IBackgroundCopyManager, reinterpret_cast<void**>(&pMgr))))
{
CoUninitialize();
return 1;
}
IBackgroundCopyJob* pJob;
GUID jobId;
if (SUCCEEDED(pMgr->CreateJob(L"Sample job", BG_JOB_TYPE_DOWNLOAD, &jobId, &pJob)))
{
pJob->AddFile(argv[1], argv[2]);
pJob->Resume();
BG_JOB_STATE state;
do {
pJob->GetState(&state);
Sleep(200);
} while (state != BG_JOB_STATE_ERROR && state != BG_JOB_STATE_TRANSFERRED);
if (state == BG_JOB_STATE_ERROR) {
IBackgroundCopyError* pError;
if (SUCCEEDED(pJob->GetError(&pError))) {
PWSTR desc;
pError->GetErrorDescription(LANG_USER_DEFAULT, &desc);
std::wcout << desc << std::endl;
CoTaskMemFree(desc);
pError->Release();
}
}
else {
pJob->Complete();
std::wcout << L"Download success!\n";
}
pJob->Release();
}
pMgr->Release();
CoUninitialize();
return 0;
}
bits com计划任务断链
#include <iostream>
#include <windows.h>
#include <Bits.h>
#include <objbase.h>
#pragma comment(lib, "bits")
#define TWO_GB 2147483648 // 2GB
class CNotifyInterface : public IBackgroundCopyCallback
{
LONG m_lRefCount;
public:
//Constructor, Destructor
CNotifyInterface() { m_lRefCount = 1; };
~CNotifyInterface() {};
//IUnknown
HRESULT __stdcall QueryInterface(REFIID riid, LPVOID* ppvObj);
ULONG __stdcall AddRef();
ULONG __stdcall Release();
//IBackgroundCopyCallback methods
HRESULT __stdcall JobTransferred(IBackgroundCopyJob* pJob);
HRESULT __stdcall JobError(IBackgroundCopyJob* pJob, IBackgroundCopyError* pError);
HRESULT __stdcall JobModification(IBackgroundCopyJob* pJob, DWORD dwReserved);
};
HRESULT CNotifyInterface::QueryInterface(REFIID riid, LPVOID* ppvObj)
{
if (riid == __uuidof(IUnknown) || riid == __uuidof(IBackgroundCopyCallback))
{
*ppvObj = this;
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
AddRef();
return NOERROR;
}
ULONG CNotifyInterface::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
ULONG CNotifyInterface::Release()
{
ULONG ulCount = InterlockedDecrement(&m_lRefCount);
if (0 == ulCount)
{
delete this;
}
return ulCount;
}
HRESULT CNotifyInterface::JobTransferred(IBackgroundCopyJob* pJob)
{
HRESULT hr;
//Add logic that will not block the callback thread. If you need to perform
//extensive logic at this time, consider creating a separate thread to perform
//the work.
//Execute
ShellExecuteA(NULL, "open", "calc.exe", NULL, NULL, SW_SHOWNORMAL);
hr = pJob->Complete();
if (FAILED(hr))
{
//Handle error. BITS probably was unable to rename one or more of the
//temporary files. See the Remarks section of the IBackgroundCopyJob::Complete
//method for more details.
}
//If you do not return S_OK, BITS continues to call this callback.
return S_OK;
}
HRESULT CNotifyInterface::JobError(IBackgroundCopyJob* pJob, IBackgroundCopyError* pError)
{
HRESULT hr;
BG_FILE_PROGRESS Progress;
BG_ERROR_CONTEXT Context;
HRESULT ErrorCode = S_OK;
WCHAR* pszJobName = NULL;
WCHAR* pszErrorDescription = NULL;
BOOL IsError = TRUE;
//Use pJob and pError to retrieve information of interest. For example,
//if the job is an upload reply, call the IBackgroundCopyError::GetError method
//to determine the context in which the job failed. If the context is
//BG_JOB_CONTEXT_REMOTE_APPLICATION, the server application that received the
//upload file failed.
hr = pError->GetError(&Context, &ErrorCode);
//If the proxy or server does not support the Content-Range header or if
//antivirus software removes the range requests, BITS returns BG_E_INSUFFICIENT_RANGE_SUPPORT.
//This implementation tries to switch the job to foreground priority, so
//the content has a better chance of being successfully downloaded.
if (BG_E_INSUFFICIENT_RANGE_SUPPORT == ErrorCode)
{
// hr = pError->GetFile(&pFile);
// hr = pFile->GetProgress(&Progress);
// if (BG_SIZE_UNKNOWN == Progress.BytesTotal)
// {
//The content is dynamic, do not change priority. Handle as an error.
// }
// else if (Progress.BytesTotal > TWO_GB)
// {
// BITS requires range requests support if the content is larger than 2 GB.
// For these scenarios, BITS uses 2 GB ranges to download the file,
// so switching to foreground priority will not help.
// }
// else
// {
hr = pJob->SetPriority(BG_JOB_PRIORITY_FOREGROUND);
hr = pJob->Resume();
IsError = FALSE;
//}
// pFile->Release();
}
if (TRUE == IsError)
{
hr = pJob->GetDisplayName(&pszJobName);
hr = pError->GetErrorDescription(LANGIDFROMLCID(GetThreadLocale()), &pszErrorDescription);
if (pszJobName && pszErrorDescription)
{
//Do something with the job name and description.
}
CoTaskMemFree(pszJobName);
CoTaskMemFree(pszErrorDescription);
}
//If you do not return S_OK, BITS continues to call this callback.
return S_OK;
}
HRESULT CNotifyInterface::JobModification(IBackgroundCopyJob* pJob, DWORD dwReserved)
{
HRESULT hr;
WCHAR* pszJobName = NULL;
BG_JOB_PROGRESS Progress;
BG_JOB_STATE State;
hr = pJob->GetDisplayName(&pszJobName);
if (SUCCEEDED(hr))
{
hr = pJob->GetProgress(&Progress);
if (SUCCEEDED(hr))
{
hr = pJob->GetState(&State);
if (SUCCEEDED(hr))
{
//Do something with the progress and state information.
//BITS generates a high volume of modification
//callbacks. Use this callback with discretion. Consider creating a timer and
//polling for state and progress information.
}
}
CoTaskMemFree(pszJobName);
}
return S_OK;
}
int wmain(int argc, wchar_t* argv[])
{
if (FAILED(CoInitialize(nullptr))) return 1;
IBackgroundCopyManager* pManager;
if (FAILED(CoCreateInstance(CLSID_BackgroundCopyManager, nullptr, CLSCTX_ALL,
IID_IBackgroundCopyManager, reinterpret_cast<void**>(&pManager))))
{
CoUninitialize();
return 1;
}
IBackgroundCopyJob* pJob;
CNotifyInterface* pNotify = new CNotifyInterface();
GUID jobId;
HRESULT hr;
if (SUCCEEDED(pManager->CreateJob(L"Sample job", BG_JOB_TYPE_DOWNLOAD, &jobId, &pJob)))
{
pJob->AddFile(argv[1], argv[2]);
hr = pJob->SetNotifyInterface(pNotify);
if (SUCCEEDED(hr))
{
hr = pJob->SetNotifyFlags(BG_NOTIFY_JOB_TRANSFERRED | BG_NOTIFY_JOB_ERROR);
}
//pNotify->Release();
//pNotify = NULL;
pJob->Resume();
BG_JOB_STATE state;
do {
pJob->GetState(&state);
Sleep(200);
} while (state != BG_JOB_STATE_ERROR && state != BG_JOB_STATE_TRANSFERRED);
if (state == BG_JOB_STATE_ERROR) {
IBackgroundCopyError* pError;
if (SUCCEEDED(pJob->GetError(&pError))) {
PWSTR desc;
pError->GetErrorDescription(LANG_USER_DEFAULT, &desc);
std::wcout << desc << std::endl;
CoTaskMemFree(desc);
pError->Release();
}
}
else {
pJob->Complete();
std::wcout << L"Download success!\n";
}
pJob->Release();
}
pManager->Release();
CoUninitialize();
return 0;
}


浙公网安备 33010602011771号