/*************************************************************************
* Rutoken                                                                *
* Copyright (c) 2003-2017, CJSC Aktiv-Soft. All rights reserved.         *
* Подробная информация:  http://www.rutoken.ru                           *
*------------------------------------------------------------------------*
* Пример работы Рутокен с криптопровайдером КриптоПро CSP                *
* с использованием интерфейса CryptoAPI на языке C                       *
*------------------------------------------------------------------------*
* Удаление ключевого контейнера КриптоПро CSP с носителя Рутокен:        *
*  - проверка наличия криптопровайдера КриптоПро CSP в системе;          *
*  - инициализация криптопровайдера и удаление контейнера;               *
*  - освобождение контекста криптопровайдера.                            *
*------------------------------------------------------------------------*
* Пример использует объекты, созданные в памяти Рутокен примером         *
* CreateContainer.                                                       *
*************************************************************************/

#include "Common.h"

int main(void)
{
	LPCWSTR szProvNameW = CRYPTOPRO_PROV_W; // Имя криптопровайдера заменить на CRYPTOPRO_FKN_PROV_W для ФКН
	DWORD dwProvType = CRYPTOPRO_PROV_TYPE; // Тип криптопровайдера
	HCRYPTPROV hProv = 0;                   // Дескриптор криптопровайдера

	for (;; ) {
		/**********************************************************************
		* Шаг 1. Проверка наличия выбранного криптопровайдера в системе       *
		**********************************************************************/
		wprintf(L"Checking whether %s provider exists", szProvNameW);
		if (!CryptAcquireContextW(
		                          &hProv,                 // Указатель на дескриптор криптопровайдера
		                          NULL,                   // Имя ключевого контейнера
		                          szProvNameW,            // Имя криптопровайдера
		                          dwProvType,             // Тип криптопровайдера
		                          CRYPT_VERIFYCONTEXT)) { // Флаг операции, не требующей работы с контейнером
			if (GetLastError() == NTE_KEYSET_NOT_DEF) {
				wprintf(L" -> FAILED \nProvider has not been installed\n\n");
			} else {
				wprintf(L" -> FAILED, error number: 0x%0.8x\n\n", GetLastError());
			}
			break;
		}
		wprintf(L" -> OK\n");

		/**********************************************************************
		* Освобождение контекста криптопровайдера                             *
		**********************************************************************/
		CryptReleaseContext(hProv, 0);

		/**********************************************************************
		* Шаг 2. Удаление ключевого контейнера                                *
		**********************************************************************/
		wprintf(L"Deleting key container with name \"%s\"", CONT_NAME_W);
		if (!CryptAcquireContextW(
		                          &hProv,                // Дескриптор криптопровайдера
		                          CONT_NAME_W,           // Имя ключевого контейнера
		                          szProvNameW,           // Имя криптопровайдера
		                          dwProvType,            // Тип криптопровайдера
		                          CRYPT_DELETEKEYSET)) { // Флаг удаления контейнера
			wprintf(L" -> FAILED, error number: 0x%0.8x\n\n", GetLastError());
			break;
		}
		wprintf(L" -> OK\n");
		wprintf(L"\nContainer \"%s\" has been destroyed.\n\n", CONT_NAME_W);
		break;
	}

	/**********************************************************************
	* Шаг 3. Освобождение контекста криптопровайдера                      *
	**********************************************************************/
	if (!GetLastError()) {
		wprintf(L"Test has been completed successfully.");
	} else {
		wprintf(L"Test has failed. Error number: 0x%0.8x.", GetLastError());
	}
	return 0;
}
