MultiotpProvider::~MultiotpProvider()
{
	/*
    if (_pCredential != nullptr)
    {
        _pCredential->Release();
        _pCredential = nullptr;
    }
	*/
    _ReleaseEnumeratedCredentials();
    if (_pCredProviderUserArray != nullptr)
    {
        _pCredProviderUserArray->Release();
        _pCredProviderUserArray = nullptr;
    }
	if (DEVELOP_MODE) PrintLn("========== MultiotpProvider destroyed ==========");
    DllRelease();
}
CSampleProvider::~CSampleProvider()
{
    _ReleaseEnumeratedCredentials();
    DllRelease();
}
// Sets pdwCount to the number of tiles that we wish to show at this time.
// Sets pdwDefault to the index of the tile which should be used as the default.
// The default tile is the tile which will be shown in the zoomed view by default. If
// more than one provider specifies a default the last used cred prov gets to pick
// the default. If *pbAutoLogonWithDefault is TRUE, LogonUI will immediately call
// GetSerialization on the credential you've specified as the default and will submit
// that credential for authentication without showing any further UI.
HRESULT MultiotpProvider::GetCredentialCount(
    _Out_ DWORD *pdwCount,
    _Out_ DWORD *pdwDefault,
    _Out_ BOOL *pbAutoLogonWithDefault)
{
	if (DEVELOP_MODE) PrintLn("MultiotpProvider::GetCredentialCount");

    *pdwDefault = CREDENTIAL_PROVIDER_NO_DEFAULT;
    *pbAutoLogonWithDefault = FALSE;

    if (_fRecreateEnumeratedCredentials)
    {
        _fRecreateEnumeratedCredentials = false;
        _ReleaseEnumeratedCredentials();
        _CreateEnumeratedCredentials();
    }
	DWORD dwUserCount = 1;
	HRESULT hr;

	if (_pCredProviderUserArray != nullptr) {
		hr = _pCredProviderUserArray->GetCount(&dwUserCount);
		if (hr == 0) {
			if (DEVELOP_MODE) PrintLn("MultiotpProvider::UserArrayCount:(%d)", dwUserCount);
		}
		else {
			if (DEVELOP_MODE) PrintLn("MultiotpProvider::UserArray.GetCount Error");
			dwUserCount = 1;
		}
	}
	else {
		if (DEVELOP_MODE) PrintLn("MultiotpProvider::Unassigned UserArray");
		dwUserCount = 1;
	}

	if ((dwUserCount == 0) || (IsOS(OS_DOMAINMEMBER) == 1)) {
		dwUserCount += 1;//display additional empty tile
		if (DEVELOP_MODE) PrintLn("MultiotpProvider::Count +1 (empty tile)");
	}

	if (DEVELOP_MODE) PrintLn("MultiotpProvider::User count:(%d)", dwUserCount);

	if (IsRemoteSession()) {
		if (DEVELOP_MODE) PrintLn("MultiotpProvider::GetCredentialCount: RDP connection");

		*pdwCount = dwUserCount;//1
		
		//get RDP port from registry
		int RDPPort = 3389;//default RDPPort
//		HRESULT hr;

		RDPPort = readRegistryValueInteger(CONF_RDP_PORT, RDPPort);
		if (DEVELOP_MODE) PrintLn("MultiotpProvider::RDP connection on port: %d", RDPPort);
	}

	else {
		if (DEVELOP_MODE) PrintLn("MultiotpProvider::Local connection");
		//logfile << "Local connection\n";

		if (readRegistryValueInteger(CONF_RDP_ONLY, 0)) {
			if (DEVELOP_MODE) PrintLn("MultiotpProvider::Only RDP is OTP protected!!!");
			*pdwCount = 0;//no filtering no OTP tile
		}
		else {
			if (DEVELOP_MODE) PrintLn("MultiotpProvider::RDP and Local OTP protection");
			*pdwCount = dwUserCount;//show OTP tile
		}

		if (DEVELOP_MODE) {
			PrintLn("MultiotpProvider::OTP tile always visible");
			*pdwCount = dwUserCount;//development - don't force but allow OTP in all scenarios
		}
	}

    return S_OK;
}
// Sets pdwCount to the number of tiles that we wish to show at this time.
// Sets pdwDefault to the index of the tile which should be used as the default.
// The default tile is the tile which will be shown in the zoomed view by default. If 
// more than one provider specifies a default tile the behavior is the last cred prov
// get to specify the default tile.
// If *pbAutoLogonWithDefault is TRUE, LogonUI will immediately call GetSerialization
// on the credential you've specified as the default and will submit that credential
// for authentication without showing any further UI.
HRESULT CSampleProvider::GetCredentialCount(
    DWORD* pdwCount,
    DWORD* pdwDefault,
    BOOL* pbAutoLogonWithDefault
    )
{
    HRESULT hr = E_FAIL;
    if (_bRecreateEnumeratedCredentials)
    {
        _ReleaseEnumeratedCredentials();
        hr = _CreateEnumeratedCredentials();
        _bRecreateEnumeratedCredentials = false;
    }

    *pdwCount = 0;
    *pdwDefault = (_bDefaultToFirstCredential && _rgpCredentials[0]) ? 0 : CREDENTIAL_PROVIDER_NO_DEFAULT;
    *pbAutoLogonWithDefault = FALSE;

    if (SUCCEEDED(hr))
    {
        // TODO: it would probably be nicer to keep a count of the number of creds
        DWORD dwNumCreds = 0;
        for (int i = 0; i < MAX_CREDENTIALS; i++)
        {
            if (_rgpCredentials[i] != NULL)
            {
                dwNumCreds++;
            }
        }
		
        switch(_cpus)
        {
        case CPUS_LOGON:
            if (_bAutoSubmitSetSerializationCred)
            {
                *pdwCount = 1;
                *pbAutoLogonWithDefault = TRUE;
            }
            else
            {

                *pdwCount = dwNumCreds;
                // since we have more than one tile and don't keep track of who logged on last, we don't really have a default in this case
            }
            hr = S_OK;
            break;

        case CPUS_UNLOCK_WORKSTATION:
            // in the unlock case, you likely would want to only enumerate tiles for the logged on user (that could be used to unlock)
            // but that's a bit complicated for a sample, so we'll just use our normal tiles
            // that we already set up in the logon case.  The default out params set up at the top work for this case.
            *pdwCount = dwNumCreds;
            hr = S_OK;
            break;

        case CPUS_CREDUI:
            {
                *pdwCount = dwNumCreds;
                hr = S_OK;
            }
            break;

        default:
            hr = E_INVALIDARG;
            break;
        }
    }

    return hr;
}