windows-nt/Source/XPSP1/NT/ds/security/csps/cryptoflex/slbiop/iop.cpp
2020-09-26 16:20:57 +08:00

762 lines
23 KiB
C++

// iop.cpp -- Definition of CIOP
// (c) Copyright Schlumberger Technology Corp., unpublished work, created
// 2000. This computer program includes Confidential, Proprietary
// Information and is a Trade Secret of Schlumberger Technology Corp. All
// use, disclosure, and/or reproduction is prohibited unless authorized
// in writing. All Rights Reserved.
#include <tchar.h>
#include <string>
#include <scuOsExc.h>
#include <scuOsVersion.h>
#include <scuArrayP.h>
#include "iop.h"
#include <aclapi.h>
#include "LockWrap.h"
using namespace std;
namespace
{
char g_szSLBRegistryPath[] = "SOFTWARE\\Schlumberger";
char g_szTerminalsName[] = "Smart Cards and Terminals";
char g_szCardName[] = "Smart Cards";
char g_szCrypto4KName[] = "Cryptoflex 4K";
char g_szOldCrypto8KName[] = "Cryptoflex 8K (no RSA key generation)";
char g_szNewCrypto8KName[] = "Cryptoflex 8K (with RSA key generation)";
char g_szCrypto8KV2Name[] = "Cryptoflex 8K (V2)";
char g_szAccessName[] = "Cyberflex Access 16K";
char g_sze_gateName[] = "Schlumberger Cryptoflex e-gate";
char g_szCrypto16KName[] = "Cryptoflex 16K";
char g_szAccessCampus[] = "Schlumberger Cyberflex Access Campus";
char g_szCryptoActivCard[] = "Schlumberger Cryptoflex ActivCard";
string
CardPath()
{
static string sPath = string(g_szSLBRegistryPath) +
string("\\") + string(g_szTerminalsName) + string("\\") +
string(g_szCardName);
return sPath;
}
#if defined(SLBIOP_WAIT_FOR_RM_STARTUP)
HANDLE GetSCResourceManagerStartedEvent(void)
{
typedef HANDLE (*LPCALAISACCESSEVENT)(void);
HANDLE hReturn = NULL;
try
{
HMODULE hWinScard = GetModuleHandle(TEXT("WINSCARD.DLL"));
if (NULL != hWinScard)
{
LPCALAISACCESSEVENT pfCalais =
(LPCALAISACCESSEVENT)GetProcAddress(hWinScard,
"SCardAccessStartedEvent");
if (NULL != pfCalais)
{
hReturn = (*pfCalais)();
}
}
}
catch (...)
{
hReturn = NULL;
}
return hReturn;
}
#endif // defined(SLBIOP_WAIT_FOR_RM_STARTUP)
}
namespace iop
{
CIOP::CIOP()
: m_hContext(NULL)
{
// Ensure that resorce manager is running, then Establish context
if (!CIOP::WaitForSCManager())
throw Exception(ccResourceManagerDisabled);
HRESULT hResult = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &m_hContext);
if (SCARD_S_SUCCESS != hResult)
throw scu::OsException(hResult);
}
CIOP::~CIOP()
{
SCardReleaseContext(m_hContext);
}
CSmartCard *
CIOP::Connect(const char* szReaderName,
bool fExclusiveMode)
{
HRESULT hResult = NOERROR;
DWORD dwShare = (fExclusiveMode ? SCARD_SHARE_EXCLUSIVE : SCARD_SHARE_SHARED);
DWORD dwProtocol;
SCARDHANDLE hCard;
// Grab our Mutex. This is a hack around an RM bug.
CIOPLock TempLock(szReaderName); // This is ok as long as one do not try to do SCard locking
CIOPMutex tempMutex(&TempLock);
// Connect to the reader
hResult = SCardConnect(m_hContext, szReaderName, dwShare,
SCARD_PROTOCOL_T0, &hCard, &dwProtocol);
if (hResult != SCARD_S_SUCCESS)
throw scu::OsException(hResult);
// Get the ATR and determine card type
DWORD dwBufferLen = 0;
DWORD dwState;
BYTE bATR[CSmartCard::cMaxAtrLength];
DWORD dwATRLen = sizeof bATR / sizeof *bATR;
hResult = SCardStatus(hCard,NULL, &dwBufferLen, &dwState,
&dwProtocol, bATR, &dwATRLen);
if (hResult != SCARD_S_SUCCESS)
throw scu::OsException(hResult);
// Create a SmartCard of the right type.
CSmartCard *psc = CreateCard(bATR, dwATRLen, hCard, szReaderName, dwShare);
return psc;
}
// This function creates a smart card of the appropriate type
CSmartCard * CIOP::CreateCard(const BYTE* bATR,
const DWORD dwLength,
const SCARDHANDLE hCard,
const char* szReaderName,
const DWORD dwShareMode)
{
////////////////////////////////////
// Open path to registered keys //
////////////////////////////////////
HKEY hkCardKey;
HKEY hkTestKey;
RegOpenKeyEx(HKEY_LOCAL_MACHINE, CardPath().c_str(), NULL,
KEY_READ, &hkCardKey);
//////////////////////////////////////////////
// Enumerate subkeys to find an ATR match //
//////////////////////////////////////////////
FILETIME fileTime;
char szATR[] = "ATR";
char szMask[] = "ATR Mask";
char szCardType[] = "Card Type";
char sBuffer[MAX_PATH + 1];
BYTE bATRtest[CSmartCard::cMaxAtrLength];
BYTE bMask[CSmartCard::cMaxAtrLength];
BYTE type;
char szCardName[MAX_PATH + 1];
DWORD dwBufferSize = sizeof(sBuffer);
DWORD dwATRSize = sizeof bATRtest / sizeof *bATRtest;
DWORD dwMaskSize = sizeof bMask / sizeof *bMask;
DWORD dwTypeSize = 1;
DWORD index = 0;
LONG iRetVal = RegEnumKeyEx(hkCardKey, index, sBuffer,
&dwBufferSize, NULL, NULL, NULL,
&fileTime);
while (iRetVal == ERROR_SUCCESS)
{
strcpy(szCardName, sBuffer);
RegOpenKeyEx(hkCardKey, sBuffer, NULL, KEY_READ, &hkTestKey);
RegQueryValueEx(hkTestKey, szATR, NULL, NULL, bATRtest, &dwATRSize);
RegQueryValueEx(hkTestKey, szMask, NULL, NULL, bMask, &dwMaskSize);
RegQueryValueEx(hkTestKey, szCardType, NULL, NULL, &type, &dwTypeSize);
if (dwATRSize == dwLength)
{
scu::AutoArrayPtr<BYTE> aabMaskedATR(new BYTE[dwATRSize]);
for (DWORD count = 0; count < dwATRSize; count++)
aabMaskedATR[count] = bATR[count] & bMask[count];
if (!memcmp(aabMaskedATR.Get(), bATRtest, dwATRSize))
break;
}
index++;
dwBufferSize = sizeof(sBuffer);
dwATRSize = sizeof bATRtest / sizeof *bATRtest;
dwMaskSize = sizeof bMask / sizeof *bMask;
RegCloseKey(hkTestKey);
iRetVal = RegEnumKeyEx(hkCardKey, index, sBuffer, &dwBufferSize, NULL, NULL, NULL, &fileTime);
}
// if loop was broken, iRetVal is still ERROR_SUCCESS, and type holds correct card to use
CSmartCard *retVal = NULL;
if (iRetVal == ERROR_SUCCESS)
{
switch (type)
{
case CRYPTO_CARD: retVal = new CCryptoCard(hCard,
szReaderName,
m_hContext,
dwShareMode);
break;
case ACCESS_CARD: retVal = new CAccessCard(hCard,
szReaderName,
m_hContext,
dwShareMode);
break;
default: throw Exception(ccUnknownCard);
break;
}
}
// loop wasn't broken, i.e., ATR not found. Try to make an Access Card.
else
retVal = new CAccessCard(hCard, szReaderName, m_hContext,
dwShareMode);
retVal->setCardName(szCardName);
return retVal;
}
void
CIOP::ListReaders(char* szReadersList, int &iSizeOfList)
{
DWORD dwSize = static_cast<DWORD>(iSizeOfList);
LONG lRet;
lRet = SCardListReaders(m_hContext, NULL, szReadersList, &dwSize);
iSizeOfList = static_cast<int>(dwSize);
if (SCARD_S_SUCCESS != lRet)
throw scu::OsException(lRet);
}
void
CIOP::ListKnownCards(char* szCardList, int& iSizeOfList)
{
////////////////////////////////////
// Open path to registered keys //
////////////////////////////////////
LONG rv;
HKEY hkCardKey;
rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, CardPath().c_str(), NULL,
KEY_READ, &hkCardKey);
if(ERROR_SUCCESS != rv)
throw scu::OsException(rv);
///////////////////////////////////////////
// Enumerate subkeys to get card names //
///////////////////////////////////////////
FILETIME fileTime;
char sBuffer[1024];
DWORD dwBufferSize = sizeof sBuffer / sizeof *sBuffer;
int iTotalSize = 0;
int index = 0;
memset(sBuffer, 0, dwBufferSize);
scu::AutoArrayPtr<char> aaszCardListBuffer(new char[iSizeOfList]);
memset(aaszCardListBuffer.Get(), 0, iSizeOfList);
rv = RegEnumKeyEx(hkCardKey, index++, sBuffer, &dwBufferSize,
NULL, NULL, NULL, &fileTime);
while (rv == ERROR_SUCCESS)
{
if (iTotalSize + dwBufferSize <= iSizeOfList - 2) // spare two chars for trailing nulls
{
strcpy((aaszCardListBuffer.Get() + iTotalSize), sBuffer);
iTotalSize += dwBufferSize;
aaszCardListBuffer[iTotalSize++] = 0;
}
else
{
iTotalSize += dwBufferSize + 1;
}
dwBufferSize = sizeof sBuffer / sizeof *sBuffer;
memset(sBuffer, 0, dwBufferSize);
rv = RegEnumKeyEx(hkCardKey, index++, sBuffer, &dwBufferSize,
NULL, NULL, NULL, &fileTime);
}
bool fRetVal = (iTotalSize <= iSizeOfList - 1); // spare byte for final null terminator
if (fRetVal)
{
aaszCardListBuffer[iTotalSize++] = 0;
memcpy(szCardList, aaszCardListBuffer.Get(), iTotalSize);
}
else
iTotalSize++; // spare byte for final null terminator
iSizeOfList = iTotalSize;
rv = RegCloseKey(hkCardKey);
if (ERROR_SUCCESS != rv)
throw scu::OsException(rv);
}
void
CIOP::RegisterCard(const char* szCardName,
const BYTE* bATR,
BYTE bATRLength,
const BYTE* bATRMask,
BYTE bATRMaskLength,
const BYTE* bProperties,
cardType type)
{
HKEY hkCardKey;
DWORD dwCreateFlag;
BYTE bCardType = (BYTE)type;
char szATR[] = "ATR";
char szATRMask[] = "ATR Mask";
char szCardType[] = "Card Type";
char szProperties[] = "Properties";
string sCardRegPath(CardPath());
sCardRegPath.append("\\");
sCardRegPath.append(szCardName);
LONG rv = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
sCardRegPath.c_str(), NULL, NULL, NULL,
KEY_ALL_ACCESS, NULL, &hkCardKey, &dwCreateFlag);
if(ERROR_SUCCESS!=rv)
throw scu::OsException(rv);
if (dwCreateFlag == REG_CREATED_NEW_KEY)
{
rv = RegSetValueEx(hkCardKey, szATR, NULL, REG_BINARY, bATR,
bATRLength);
if (ERROR_SUCCESS==rv)
{
rv = RegSetValueEx(hkCardKey, szATRMask, NULL,
REG_BINARY, bATRMask,
bATRMaskLength);
if (ERROR_SUCCESS==rv)
{
rv = RegSetValueEx(hkCardKey, szCardType, NULL,
REG_BINARY, &bCardType, 1);
if (ERROR_SUCCESS==rv)
rv = RegSetValueEx(hkCardKey, szProperties, NULL,
REG_BINARY, bProperties, 512);
}
}
}
LONG rv2 = RegCloseKey(hkCardKey);
if (ERROR_SUCCESS!=rv) // an error occured earlier
throw scu::OsException(rv);
if (ERROR_SUCCESS != rv2)
throw scu::OsException(rv2);
// return (dwCreateFlag == REG_CREATED_NEW_KEY);
}
void
CIOP::RegisterDefaultCards()
{
BYTE bMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
BYTE bAccessMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 };
BYTE bCMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
BYTE bMaskLength = 9;
BYTE bATRLength = 9;
BYTE bProperties[512];
memset(bProperties, 0, sizeof(bProperties));
// Register Cryptoflex 16K
BYTE b16KCryptoATR[] = { 0x3B, 0x95, 0x15, 0x40, 0xFF, 0x63,
0x01, 0x01, 0x00, 0x00 };
BYTE b16KCryptoMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0x00 };
RegisterCard(g_szCrypto16KName, b16KCryptoATR,
sizeof b16KCryptoATR / sizeof *b16KCryptoATR, b16KCryptoMask,
sizeof b16KCryptoMask / sizeof *b16KCryptoMask,
bProperties, CRYPTO_CARD);
// Register e-gate
BYTE be_gateATR[] = { 0x3B, 0x95, 0x00, 0x40, 0xFF, 0x62,
0x01, 0x01, 0x00, 0x00 };
BYTE be_gateMask[] = { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0x00 };
RegisterCard(g_sze_gateName, be_gateATR,
sizeof be_gateATR / sizeof *be_gateATR, be_gateMask,
sizeof be_gateMask / sizeof *be_gateMask,
bProperties, CRYPTO_CARD);
// Register Cyberflex Access card
BYTE bAccessATR[] = { 0x3B, 0x16, 0x94, 0x81, 0x10, 0x06, 0x01, 0x00, 0x00 };
RegisterCard(g_szAccessName, bAccessATR, bATRLength, bAccessMask,
bMaskLength, bProperties, ACCESS_CARD);
// Register old Cryptoflex 8K card
BYTE bOldCryptoATR[] = { 0x3B, 0x85, 0x40, 0x20, 0x68, 0x01, 0x01, 0x00, 0x00 };
RegisterCard(g_szOldCrypto8KName, bOldCryptoATR, bATRLength, bMask,
bMaskLength, bProperties, CRYPTO_CARD);
// Register new Cryptoflex 8K card
BYTE bNewCryptoATR[] = { 0x3B, 0x85, 0x40, 0x20, 0x68, 0x01, 0x01, 0x05, 0x01 };
RegisterCard(g_szNewCrypto8KName, bNewCryptoATR, bATRLength, bMask,
bMaskLength, bProperties, CRYPTO_CARD);
// Register another new Cryptoflex 8K card
BYTE bCrypto8KV2ATR[] = { 0x3B, 0x95, 0x15, 0x40, 0x00, 0x68, 0x01, 0x02, 0x00, 0x00 };
BYTE bCrypto8KV2Mask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00 };
RegisterCard(g_szCrypto8KV2Name, bCrypto8KV2ATR, sizeof(bCrypto8KV2ATR), bCrypto8KV2Mask,
sizeof(bCrypto8KV2Mask), bProperties, CRYPTO_CARD);
// Register Cryptoflex 4K card
BYTE b4KCryptoATR[] = { 0x3B, 0xE2, 0x00, 0x00, 0x40, 0x20, 0x49, 0x00 };
bATRLength = 8;
bMaskLength = 8;
RegisterCard(g_szCrypto4KName, b4KCryptoATR, bATRLength, bCMask,
bMaskLength, bProperties, CRYPTO_CARD);
// Register Cyberflex Access Campus
BYTE be_AccessCampusATR[] = { 0x3B, 0x23, 0x00, 0x35, 0x13, 0x80 };
BYTE be_AccessCampusMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
RegisterCard(g_szAccessCampus, be_AccessCampusATR,
sizeof be_AccessCampusATR / sizeof *be_AccessCampusATR,
be_AccessCampusMask,
sizeof be_AccessCampusMask / sizeof *be_AccessCampusMask,
bProperties, ACCESS_CARD);
// Register Cryptoflex ActivCard
BYTE bCryptoActivCardATR[] = { 0x3B, 0x05, 0x68, 0x01, 0x01,
0x02, 0x05 };
BYTE bCryptoActivCardMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF };
RegisterCard(g_szCryptoActivCard, bCryptoActivCardATR,
sizeof(bCryptoActivCardATR), bCryptoActivCardMask,
sizeof(bCryptoActivCardMask), bProperties, CRYPTO_CARD);
}
#if defined(SLBIOP_USE_SECURITY_ATTRIBUTES)
void
CIOP::InitIOPSecurityAttrs(CSecurityAttributes *psa)
{
DWORD dwRes;
PSID pEveryoneSID = NULL, pAdminSID = NULL;
PACL pACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
bool fErrorFound = false;
// Create a well-known SID for the Everyone group.
if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0, &pEveryoneSID))
throw scu::OsException(GetLastError());
// Initialize an EXPLICIT_ACCESS structure for an ACE.
// The ACE will allow Everyone read access to the key.
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
ea.grfAccessMode = SET_ACCESS;
ea.grfInheritance= NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea.Trustee.ptstrName = (LPTSTR) pEveryoneSID;
#if 0
// Create a SID for the BUILTIN\Administrators group.
if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0,
0, 0, &pAdminSID))
throw scu::OsException(GetLastError());
// Initialize an EXPLICIT_ACCESS structure for an ACE.
// The ACE will allow the Administrators group full access to the key.
ea.grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
ea.grfAccessMode = SET_ACCESS;
ea.grfInheritance= NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
ea.Trustee.ptstrName = (LPTSTR) pAdminSID;
#endif // 0
// Create a new ACL that contains the new ACEs.
dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL);
if (ERROR_SUCCESS != dwRes)
{
fErrorFound = true;
}
else
{
// Initialize a security descriptor.
pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
if (pSD == NULL)
{
fErrorFound = true;
}
else if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
{
fErrorFound = true;
}
// Add the ACL to the security descriptor.
else if (!SetSecurityDescriptorDacl(pSD,
TRUE, // fDaclPresent flag
pACL,
FALSE)) // not a default DACL
{
fErrorFound = true;
}
else
{
if (!IsValidSecurityDescriptor(pSD))
{
fErrorFound = true;
}
else
{
// Initialize a security attributes structure.
psa->sa.nLength = sizeof(SECURITY_ATTRIBUTES);
psa->sa.lpSecurityDescriptor = pSD;
psa->sa.bInheritHandle = FALSE;
psa->pEveryoneSID = pEveryoneSID;
psa->pACL = pACL;
}
}
}
DWORD dwLastError = GetLastError();
if (true == fErrorFound)
{
if (NULL != pACL)
{
LocalFree(pACL);
pACL = NULL;
}
if (NULL != pSD)
{
LocalFree(pSD);
pSD = NULL;
}
if (NULL != pEveryoneSID)
{
FreeSid(pEveryoneSID);
pEveryoneSID = NULL;
}
throw scu::OsException(dwLastError);
}
#if 0
// Create a new ACL that contains the new ACEs.
dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL);
if (ERROR_SUCCESS != dwRes)
throw scu::OsException(GetLastError());
// Initialize a security descriptor.
pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
if (pSD == NULL)
throw scu::OsException(GetLastError());
if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
throw scu::OsException(GetLastError());
// Add the ACL to the security descriptor.
if (!SetSecurityDescriptorDacl(pSD,
TRUE, // fDaclPresent flag
pACL,
FALSE)) // not a default DACL
throw scu::OsException(GetLastError());
// Initialize a security attributes structure.
psa->nLength = sizeof(SECURITY_ATTRIBUTES);
psa->lpSecurityDescriptor = pSD;
psa->bInheritHandle = FALSE;
if (!IsValidSecurityDescriptor(pSD))
throw scu::OsException(GetLastError());
#endif
}
#endif // defined(SLBIOP_USE_SECURITY_ATTRIBUTES)
bool CIOP::WaitForSCManager()
{
#if defined(SLBIOP_WAIT_FOR_RM_STARTUP)
// Wait for the SCManager to start, time out at dwTimeout seconds.
HANDLE hStarted = GetSCResourceManagerStartedEvent();
if (hStarted)
{
if (WaitForSingleObject(hStarted, 60 * 1000) == WAIT_OBJECT_0)
return true;
}
return false;
#else // defined(SLBIOP_WAIT_FOR_RM_STARTUP)
return true;
#endif // defined(SLBIOP_WAIT_FOR_RM_STARTUP)
}
} // namespace iop
STDAPI DllGetVersion(DLLVERSIONINFO *dvi)
{
dvi->dwBuildNumber = 0;
dvi->dwMajorVersion = 0;
dvi->dwMinorVersion = 9;
return 0;
}
STDAPI DllRegisterServer()
{
// Ensure default cards are registered to the system
HRESULT hResult = ERROR_SUCCESS;
try
{
iop::CIOP::RegisterDefaultCards();
}
catch (scu::OsException const &rExc)
{
hResult = rExc.Cause();
}
return hResult;
}
STDAPI DllUnregisterServer()
{
HRESULT hResult = NOERROR;
LONG rv;
HKEY hkSLBKey;
HKEY hkTerminalsKey;
HKEY hkCardsKey;
bool bSLBKey = false, bTerminalsKey = false, bCardsKey = false;
try
{
rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szSLBRegistryPath, NULL, KEY_ALL_ACCESS, &hkSLBKey);
if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
bSLBKey = true;
RegOpenKeyEx(hkSLBKey, g_szTerminalsName, NULL, KEY_ALL_ACCESS, &hkTerminalsKey);
if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
bTerminalsKey = true;
RegOpenKeyEx(hkTerminalsKey, g_szCardName, NULL, KEY_ALL_ACCESS, &hkCardsKey);
if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
bCardsKey = true;
rv = RegDeleteKey(hkCardsKey, g_szCrypto4KName);
if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
rv = RegDeleteKey(hkCardsKey, g_szOldCrypto8KName);
if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
rv = RegDeleteKey(hkCardsKey, g_szNewCrypto8KName);
if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
rv = RegDeleteKey(hkCardsKey, g_szCrypto8KV2Name);
if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
rv = RegDeleteKey(hkCardsKey, g_szAccessName);
if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
rv = RegDeleteKey(hkCardsKey, g_sze_gateName);
if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
rv = RegDeleteKey(hkCardsKey, g_szCrypto16KName);
if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
rv = RegDeleteKey(hkCardsKey, g_szAccessCampus);
if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
rv = RegDeleteKey(hkCardsKey, g_szCryptoActivCard);
if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
rv = RegCloseKey (hkCardsKey);
if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
bCardsKey = false;
rv = RegDeleteKey(hkTerminalsKey, g_szCardName);
if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
bCardsKey = false;
rv = RegCloseKey (hkTerminalsKey);
if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
bTerminalsKey = false;
rv = RegDeleteKey(hkSLBKey, g_szTerminalsName);
if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
bCardsKey = false;
rv = RegCloseKey(hkSLBKey);
if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
bSLBKey = false;
}
catch(...)
{
hResult = E_UNEXPECTED;
}
if(bCardsKey) RegCloseKey (hkCardsKey);
if(bTerminalsKey) RegCloseKey (hkTerminalsKey);
if(bSLBKey) RegCloseKey (hkSLBKey);
return hResult;
}