/// <summary>
        /// Click handler for the 'ResetPin' button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void ResetPin_Click(object sender, RoutedEventArgs e)
        {
            if (!rootPage.ValidateTPMSmartCard())
            {
                rootPage.NotifyUser("Use Scenario One to create a TPM virtual smart card.", NotifyType.ErrorMessage);
                return;
            }

            Button b = sender as Button;

            b.IsEnabled = false;

            try
            {
                SmartCard card = await rootPage.GetSmartCard();

                SmartCardProvisioning provisioning = await SmartCardProvisioning.FromSmartCardAsync(card);

                rootPage.NotifyUser("Resetting smart card PIN...", NotifyType.StatusMessage);

                // When requesting a PIN reset, a SmartCardPinResetHandler must be
                // provided as an argument.  This handler must use the challenge
                // it receives and the card's admin key to calculate and set the
                // response.
                bool result = await provisioning.RequestPinResetAsync(
                    (pinResetSender, request) =>
                {
                    SmartCardPinResetDeferral deferral = request.GetDeferral();

                    try
                    {
                        IBuffer response = ChallengeResponseAlgorithm.CalculateResponse(request.Challenge, rootPage.AdminKey);
                        request.SetResponse(response);
                    }
                    finally
                    {
                        deferral.Complete();
                    }
                });

                if (result)
                {
                    rootPage.NotifyUser("Smart card PIN reset operation completed.", NotifyType.StatusMessage);
                }
                else
                {
                    rootPage.NotifyUser("Smart card PIN reset operation was canceled by the user.", NotifyType.StatusMessage);
                }
            }
            catch (Exception ex)
            {
                rootPage.NotifyUser("Resetting smart card PIN failed with exception: " + ex.ToString(), NotifyType.ErrorMessage);
            }
            finally
            {
                b.IsEnabled = true;
            }
        }
        /// <summary>
        /// Click handler for the 'ChangeAdminKey' button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void ChangeAdminKey_Click(object sender, RoutedEventArgs e)
        {
            if (!rootPage.ValidateTPMSmartCard())
            {
                rootPage.NotifyUser("Use Scenario One to create a TPM virtual smart card.", NotifyType.ErrorMessage);
                return;
            }

            Button b = sender as Button;

            b.IsEnabled = false;

            try
            {
                IBuffer newadminkey = CryptographicBuffer.GenerateRandom(MainPage.ADMIN_KEY_LENGTH_IN_BYTES);

                SmartCard card = await rootPage.GetSmartCard();

                SmartCardProvisioning provisioning = await SmartCardProvisioning.FromSmartCardAsync(card);

                rootPage.NotifyUser("Changing smart card admin key...", NotifyType.StatusMessage);

                using (SmartCardChallengeContext context = await provisioning.GetChallengeContextAsync())
                {
                    IBuffer response = ChallengeResponseAlgorithm.CalculateResponse(context.Challenge, rootPage.AdminKey);

                    await context.ChangeAdministrativeKeyAsync(response, newadminkey);

                    rootPage.AdminKey = newadminkey;
                }

                rootPage.NotifyUser("Smart card change admin key operation completed.", NotifyType.StatusMessage);
            }
            catch (Exception ex)
            {
                rootPage.NotifyUser("Changing smart card admin key operation failed with exception: " + ex.ToString(), NotifyType.ErrorMessage);
            }
            finally
            {
                b.IsEnabled = true;
            }
        }
        /// <summary>
        /// Click handler for the 'VerifyResponse' button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void VerifyResponse_Click(object sender, RoutedEventArgs e)
        {
            if (!rootPage.ValidateTPMSmartCard())
            {
                rootPage.NotifyUser("Use Scenario One to create a TPM virtual smart card.", NotifyType.ErrorMessage);
                return;
            }

            Button b = sender as Button;

            b.IsEnabled = false;

            try
            {
                bool      verifyResult = false;
                SmartCard card         = await rootPage.GetSmartCard();

                SmartCardProvisioning provisioning = await SmartCardProvisioning.FromSmartCardAsync(card);

                rootPage.NotifyUser("Verifying smart card response...", NotifyType.StatusMessage);

                using (SmartCardChallengeContext context = await provisioning.GetChallengeContextAsync())
                {
                    IBuffer response = ChallengeResponseAlgorithm.CalculateResponse(context.Challenge, rootPage.AdminKey);
                    verifyResult = await context.VerifyResponseAsync(response);
                }

                rootPage.NotifyUser("Smart card response verification completed. Result: " + verifyResult.ToString(), NotifyType.StatusMessage);
            }
            catch (Exception ex)
            {
                rootPage.NotifyUser("Verifying smart card response operation failed with exception: " + ex.ToString(), NotifyType.ErrorMessage);
            }
            finally
            {
                b.IsEnabled = true;
            }
        }
        /// <summary>
        /// Click handler for the 'create' button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void Create_Click(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;

            b.IsEnabled = false;
            rootPage.NotifyUser("Creating TPM virtual smart card...", NotifyType.StatusMessage);

            try
            {
                SmartCardPinPolicy pinPolicy = ParsePinPolicy();

                IBuffer adminkey = CryptographicBuffer.GenerateRandom(MainPage.ADMIN_KEY_LENGTH_IN_BYTES);

                SmartCardProvisioning provisioning = await SmartCardProvisioning.RequestVirtualSmartCardCreationAsync(FriendlyName.Text, adminkey, pinPolicy);

                // If card creation is cancelled by the user,
                // RequestVirtualSmartCard will return null instead of a
                // SmartCardProvisioning object.
                if (null == provisioning)
                {
                    rootPage.NotifyUser("TPM virtual smart card creation was canceled by the user.", NotifyType.StatusMessage);
                    b.IsEnabled = true;
                    return;
                }

                // The following two lines are not directly related to TPM virtual
                // smart card creation, but are used to demonstrate how to handle
                // CardAdded events by registering an event handler with a
                // SmartCardReader object.  Since we are using a TPM virtual smart
                // card in this case, the card cannot actually be added to or
                // removed from the reader, but a CardAdded event will fire as
                // soon as the event handler is added, since the card is already
                // inserted.
                //
                // We must retain a reference to the SmartCardReader object to
                // which we are adding the event handler.  Hence we assign the
                // reader object associated with the SmartCardProvisioning we
                // received from RequestVirtualSmartCardCreationAsync to the
                // class's "reader" member.  Then, we use += to add the
                // HandleCardAdded method as an event handler.  The function
                // will be automatically boxed in a TypedEventHandler, but
                // the function signature match the template arguments for
                // the specific event - in this case,
                // <SmartCardReader, CardAddedEventArgs>
                reader            = provisioning.SmartCard.Reader;
                reader.CardAdded += HandleCardAdded;

                // Store the reader's device ID and admin key to enable the
                // following scenarios in the sample.
                rootPage.SmartCardReaderDeviceId = provisioning.SmartCard.Reader.DeviceId;
                rootPage.AdminKey = adminkey;

                // Once RequestVirtualSmartCardCreationAsync has returned, the card
                // is already provisioned and ready to use.  Therefore, the steps
                // in this using block are not actually necessary at this point.
                // However, should you want to re-provision the card in the future,
                // you would follow this sequence: acquire a challenge context,
                // calculate a response, and then call ProvisionAsync on the
                // challenge context with the calculated response.
                using (var context = await provisioning.GetChallengeContextAsync())
                {
                    IBuffer response = ChallengeResponseAlgorithm.CalculateResponse(context.Challenge, adminkey);
                    await context.ProvisionAsync(response, true);
                }

                rootPage.NotifyUser("TPM virtual smart card is provisioned and ready for use.", NotifyType.StatusMessage);
            }
            catch (Exception ex)
            {
                // Two potentially common error scenarios when creating a TPM
                // virtual smart card are that the user's machine may not have
                // a TPM, or the TPM may not be ready for use.  It is important
                // to explicitly check for these scenarios by checking the
                // HResult of any exceptions thrown by
                // RequestVirtualSmartCardCreationAsync and gracefully
                // providing a suitable message to the user.
                if (NTE_DEVICE_NOT_FOUND == ex.HResult)
                {
                    rootPage.NotifyUser("We were unable to find a Trusted Platform Module on your machine. A TPM is required to use a TPM Virtual Smart Card.", NotifyType.ErrorMessage);
                }
                else if (NTE_DEVICE_NOT_READY == ex.HResult)
                {
                    rootPage.NotifyUser("Your Trusted Platform Module is not ready for use. Please contact your administrator for assistance with initializing your TPM.", NotifyType.ErrorMessage);
                }
                else
                {
                    rootPage.NotifyUser("TPM virtual smart card creation failed with exception: " + ex.ToString(), NotifyType.ErrorMessage);
                }
            }
            finally
            {
                b.IsEnabled = true;
            }
        }