Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Zadanie transferu usługi inteligentnego transferu w tle (BITS) można skonfigurować przy użyciu dodatkowego tokenu zabezpieczającego. Zadanie transferu usługi BITS używa tego tokenu pomocniczego do uwierzytelniania i uzyskiwania dostępu do zasobów.
Aby uzyskać więcej informacji, zobacz tokeny pomocnika dla zadań transferu usługi BITS.
Poniższa procedura tworzy zadanie transferu usługi BITS w kontekście użytkownika lokalnego, pobiera poświadczenia drugiego użytkownika, tworzy token pomocnika z tymi poświadczeniami, a następnie ustawia token pomocnika w zadaniu transferu usługi BITS.
W tym przykładzie użyto nagłówka i implementacji zdefiniowanej w Przykład: Typowe klasy.
Aby dodać token pomocnika do zadania transferu usługi BITS
Zainicjuj parametry MODELU COM, wywołując funkcję CCoInitializer. Aby uzyskać więcej informacji na temat funkcji CCoInitializer, zobacz Example: Common Classes.
Pobierz wskaźnik do interfejsu IBackgroundCopyJob. W tym przykładzie użyto klasy CComPtr do zarządzania wskaźnikami interfejsu COM.
Inicjowanie zabezpieczeń procesu COM przez wywołanie CoInitializeSecurity. Usługa BITS wymaga co najmniej poziomu personifikacji personifikacji. Usługa BITS kończy się niepowodzeniem z E_ACCESSDENIED, jeśli nie ustawiono poprawnego poziomu personifikacji.
Pobierz wskaźnik do interfejsu IBackgroundCopyManager i uzyskaj początkowy lokalizator do usługi BITS, wywołując funkcję CoCreateInstance.
Utwórz zadanie transferu usługi BITS, wywołując metodę IBackgroundCopyManager::CreateJob.
Pobierz wskaźnik do interfejsu wywołania zwrotnego CNotifyInterface i wywołaj metodę IBackgroundCopyJob::SetNotifyInterface metodę, aby otrzymywać powiadomienia o zdarzeniach związanych z zadaniem. Aby uzyskać więcej informacji na temat CNotifyInterface, zobacz Example: Common Classes.
Wywołaj metodę IBackgroundCopyJob::SetNotifyFlags, aby ustawić typy powiadomień do odbierania. W tym przykładzie ustawiono flagi BG_NOTIFY_JOB_TRANSFERRED i BG_NOTIFY_JOB_ERROR.
Pobierz wskaźnik do interfejsu IBitsTokenOptions, wywołując metodę IBackgroundCopyJob::QueryInterface z odpowiednim identyfikatorem interfejsu.
Spróbuj zalogować użytkownika tokenu pomocnika. Utwórz uchwyt personifikacji i wywołaj funkcję LogonUser, aby wypełnić uchwyt personifikacji. W przypadku pomyślnego wywołania funkcji impersonateLoggedOnUser . W przypadku niepowodzenia przykład wywołuje funkcję RevertToSelf, aby zakończyć personifikację zalogowanego użytkownika, zostanie zgłoszony błąd, a dojście zostanie zamknięte.
Wywołaj metodę IBitsTokenOptions::SetHelperToken, aby personifikować token zalogowanego użytkownika. Jeśli ta metoda nie powiedzie się, przykład wywołuje funkcję RevertToSelf, aby zakończyć personifikację zalogowanego użytkownika, zostanie zgłoszony błąd i uchwyt zostanie zamknięty.
Nuta
W obsługiwanych wersjach systemu Windows przed systemem Windows 10 w wersji 1607 właściciel zadania musi mieć poświadczenia administracyjne, aby wywołać metodę IBitsTokenOptions::SetHelperToken.
Począwszy od systemu Windows 10 w wersji 1607, właściciele zadań innych niż administratorzy mogą ustawiać tokeny pomocnika nieadministratora na własnych zadaniach usługi BITS. Właściciele zadań muszą nadal mieć poświadczenia administracyjne, aby ustawić tokeny pomocnika z uprawnieniami administratora.
Wywołaj metodę IBitsTokenOptions::SetHelperTokenFlags, aby określić, do których zasobów mają uzyskać dostęp przy użyciu kontekstu zabezpieczeń tokenu pomocniczego.
Po zakończeniu personifikacji przykład wywołuje funkcję RevertToSelf, aby zakończyć personifikację zalogowanego użytkownika, a dojście zostało zamknięte.
Dodaj pliki do zadania transferu usługi BITS, wywołując IBackgroundCopyJob::AddFile.
Po dodaniu pliku wywołaj IBackgroundCopyJob::Resume, aby wznowić zadanie.
Skonfiguruj pętlę czasową, aby poczekać na komunikat zakończenia z interfejsu wywołania zwrotnego podczas przesyłania zadania. Pętla while używa funkcji GetTickCount w celu pobrania liczby milisekund, które upłynęły od rozpoczęcia przenoszenia zadania.
Po zakończeniu zadania transferu usługi BITS usuń zadanie z kolejki, wywołując IBackgroundCopyJob::Complete.
Poniższy przykład kodu dodaje token pomocnika do zadania transferu usługi BITS.
#include <bits.h>
#include <bits4_0.h>
#include <stdio.h>
#include <tchar.h>
#include <lm.h>
#include <iostream>
#include <exception>
#include <string>
#include <atlbase.h>
#include <memory>
#include <new>
#include "CommonCode.h"
void HelperToken(const LPWSTR &remoteFile, const LPWSTR &localFile, const LPWSTR &domain, const LPWSTR &username, const LPWSTR &password)
{
// If CoInitializeEx fails, the exception is unhandled and the program terminates
CCoInitializer coInitializer(COINIT_APARTMENTTHREADED);
CComPtr<IBackgroundCopyJob> pJob;
try
{
//The impersonation level must be at least RPC_C_IMP_LEVEL_IMPERSONATE.
HRESULT hr = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_CONNECT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_DYNAMIC_CLOAKING,
0
);
if (FAILED(hr))
{
throw MyException(hr, L"CoInitializeSecurity");
}
// Connect to BITS.
CComPtr<IBackgroundCopyManager> pQueueMgr;
hr = CoCreateInstance(__uuidof(BackgroundCopyManager), NULL,
CLSCTX_LOCAL_SERVER,
__uuidof(IBackgroundCopyManager),
(void **)&pQueueMgr);
if (FAILED(hr))
{
// Failed to connect.
throw MyException(hr, L"CoCreateInstance");
}
// Create a job.
wprintf(L"Creating Job...\n");
GUID guidJob;
hr = pQueueMgr->CreateJob(L"HelperTokenSample",
BG_JOB_TYPE_DOWNLOAD,
&guidJob,
&pJob);
if(FAILED(hr))
{
// Failed to create job.
throw MyException(hr, L"CreateJob");
}
// Set the File Completed call.
CComPtr<CNotifyInterface> pNotify;
pNotify = new CNotifyInterface();
hr = pJob->SetNotifyInterface(pNotify);
if (FAILED(hr))
{
// Failed to SetNotifyInterface.
throw MyException(hr, L"SetNotifyInterface");
}
hr = pJob->SetNotifyFlags(BG_NOTIFY_JOB_TRANSFERRED |
BG_NOTIFY_JOB_ERROR);
if (FAILED(hr))
{
// Failed to SetNotifyFlags.
throw MyException(hr, L"SetNotifyFlags");
}
//Retrieve the IBitsTokenOptions interface pointer from the BITS transfer job.
CComPtr<IBitsTokenOptions> pTokenOptions;
hr = pJob->QueryInterface(__uuidof(IBitsTokenOptions), (void** ) &pTokenOptions);
if (FAILED(hr))
{
// Failed to QueryInterface.
throw MyException(hr, L"QueryInterface");
}
// Log on user of the helper token.
wprintf(L"Credentials for helper token %s\\%s %s\n", domain, username, password);
HANDLE hImpersonation = INVALID_HANDLE_VALUE;
if(LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hImpersonation))
{
// Impersonate the logged-on user.
if(ImpersonateLoggedOnUser(hImpersonation))
{
// Configure the impersonated logged-on user's token as the helper token.
hr = pTokenOptions->SetHelperToken();
if (FAILED(hr))
{
//Failed to set helper token.
CloseHandle(hImpersonation);
RevertToSelf();
throw MyException(hr, L"SetHelperToken");
}
hr = pTokenOptions->SetHelperTokenFlags(BG_TOKEN_LOCAL_FILE);
if (FAILED(hr))
{
//Failed to set helper token flags.
CloseHandle(hImpersonation);
RevertToSelf();
throw MyException(hr, L"SetHelperTokenFlags");
}
RevertToSelf();
}
CloseHandle(hImpersonation);
}
// Add a file.
// Replace parameters with variables that contain valid paths.
wprintf(L"Adding File to Job\n");
hr = pJob->AddFile(remoteFile,localFile);
if(FAILED(hr))
{
//Failed to add file to job.
throw MyException(hr, L"AddFile");
}
//Resume the job.
wprintf(L"Resuming Job...\n");
hr = pJob->Resume();
if (FAILED(hr))
{
// Resume failed.
throw MyException(hr, L"Resume");
}
}
catch(const std::bad_alloc &)
{
wprintf(L"Memory allocation failed");
if (pJob)
{
pJob->Cancel();
}
return;
}
catch(const MyException &ex)
{
wprintf(L"Error 0x%x occurred during operation", ex.Error);
if (pJob)
{
pJob->Cancel();
}
return;
}
wprintf(L"Transferring file and waiting for callback.\n");
// Wait for QuitMessage from CallBack
DWORD dwLimit = GetTickCount() + (15 * 60 * 1000); // set 15 minute limit
while (dwLimit > GetTickCount())
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// If it is a quit message, exit.
if (msg.message == WM_QUIT)
{
return;
}
// Otherwise, dispatch the message.
DispatchMessage(&msg);
} // End of PeekMessage while loop
}
pJob->Cancel();
return;
}
void _cdecl _tmain(int argc, LPWSTR* argv)
{
if (argc != 6)
{
wprintf(L"Usage:");
wprintf(L"%s ", argv[0]);
wprintf(L"[remote name] [local name] [helpertoken domain] [helpertoken userrname] [helpertoken password]\n");
return;
}
HelperToken(argv[1],argv[2],argv[3],argv[4],argv[5]);
}
Tematy pokrewne