IsGenuineEx returns an eror while is IsActivated doesn't

Hello,

I've run into the following problem:1)My application asks the user to enter the registration key (because IsActivated returns false)2)After entering the key IsActivated re-checks and return OK3)Now there is a call to IsGenuineEx which I've added recently and that one returns an error and deactivates the license

This only happens rarely, specifically on Macs running Parallels.Any guesses why it happens? Should I just use IsGenuineEx (including first activation) and stop using IsActivated at all?

Thanks for your help!

Any guesses why it happens?

Well, it depends on a lot of things. Starting with...

  1. What are the error codes for IsGenuineEx?
  2. What parameters are you passing to IsGenuineEx()? Are you using something bad like small values for the daysBetweenChecks and/or the gracePeriod? Note that IsGenuineEx() will say that the customer is not activated if IsGenuineEx() couldn't reverify with the servers in daysBetweenChecks + gracePeriod days.
Should I just use IsGenuineEx (including first activation) and stop using IsActivated at all?

Yes.

Ok, so what I am passing to it is this:

static GENUINE_OPTIONS license_settings = { .nLength = sizeof(GENUINE_OPTIONS), .flags = 0u, .nDaysBetweenChecks = 14, .nGraceDaysOnInetErr = 7,};

and the way I am calling it is this:

hr_genuine = IsGenuineEx(guid, &license_settings);

The error code is 15 (in hexa-decimal) so the docs tell me it's about Internet connection. I should've checked that earlier, thanks for pointing this out.Is there any way a user can recheck instantly after disabling firewall/anti-virus without waiting for 5 hours though?

You should handle TA_E_INET as a warning. From the documentation (and the example app):

Returns: TA_OK or TA_E_FEATURES_CHANGED on success. Handle TA_E_INET and TA_E_INET_DELAYED as warnings that you should let the end user know about.

Handle all other return codes as failures.

Possible return codes: TA_OK, TA_FAIL, TA_E_ACTIVATE, TA_E_INET, TA_E_INVALID_HANDLE, TA_E_COM, TA_E_EXPIRED, TA_E_REVOKED, TA_E_INVALID_ARGS, TA_E_INVALID_FLAGS, TA_E_IN_VM, TA_E_INET_DELAYED, TA_E_FEATURES_CHANGED, TA_E_ANDROID_NOT_INIT

Ok, thank you very much, that explains a lot. I missed that in the docs that I should treat some error codes as warnings.Just to make sure I understand it well:

1)returning INET flag turns on the grace period2)after grace period is over and the software still can't connect the license is going to be deactivated3)if the license is not active and connection to LimeLM servers is not possible there is no 5hours period and the user will be able to activate straight away after they disable firewall or w/e else is blocking it

I am especially interested in confirming the point number 3.

Thank you for your help!

1)returning INET flag turns on the grace period

No, after nDaysBetweenChecks it's in the grace period.

2)after grace period is over and the software still can't connect the license is going to be deactivated

It will say it's not activated. However you can then call IsActivated() to see if it's really not activated. And if IsActivated() return TA_OK, then you can tell the user to connect to the internet and then click a button to retry.

3)if the license is not active and connection to LimeLM servers is not possible there is no 5hours period and the user will be able to activate straight away after they disable firewall or w/e else is blocking it

In the dialog prompt you give to the user, have the button call IsGenuine(), which will recheck immediately. Note that you should only call IsGenuine() when a user clicks a button -- don't automate it.

>>No, after nDaysBetweenChecks it's in the grace period

But isn't the check only performed once every 2 weeks (or w/e the time between checks is defined to)?So that would mean that if the check return INET flag the grace period should be on because the end of re-check period is the only time the online check is performed or am I not getting something?

>>It will say it's not activated. However you can then call IsActivated() to see if it's really not activated.

I have problems with this. I thought the point of an online check is to deactivate the license if it's either not valid anymore or grace period is over and the connection is impossible. IsActivated() doesn't connect to the Internet so it can't do anything there. Can you explain in what circumstances I could get not activated from IsGenuineEx but TA_OK from IsActivated? It doesn't make much sense to me so I must be missing something.

>>In the dialog prompt you give to the user, have the button call IsGenuine(), which will recheck immediately. Note that you should only call IsGenuine() when a user clicks a button -- don't automate it.

I don't have buttons in my program (it's a text interface which at least for now either asked for the key or refused to start without valid license). I still don't understand how it works though, so can you clarify the following:

Scenario 1:1)I call IsGenuineEX when the user start the program for the first time2)INET flag is returned3)The user kills his firewall and restarts the program which calls isGenuineEx again (it would do it every time when starting)

Scenario 2:1)The user managed to activate the license2)after 14 days IsGenuineEx performs an online-check and is unable to connect to the internet3)point 2 continues for another 7 days which is a grace period4)after that IsGenuineEx is going to return an error flag (so not INET one but say error code 1)5)the user now disables the firewal land starts the program again

Is it going to work from users perspective or are they going to be forced to wait 5hours to use the program in scenarios 1 and 2?

Thanks!

But isn't the check only performed once every 2 weeks (or w/e the time between checks is defined to)?

It depends on what you set.

So that would mean that if the check return INET flag the grace period should be on because the end of re-check period is the only time the online check is performed or am I not getting something?

The grace period starts immediately after nDaysBetweenChecks. If there's no internet connection then they can continue to use your app for the gracePeriod. Once the grace period has expired, IsGenuineEx() will continue to try to contact the servers, however it will say TA_FAIL if it can't reverify the activations.

I have problems with this. I thought the point of an online check is to deactivate the license if it's either not valid anymore or grace period is over and the connection is impossible.

It says it's deactivated. And if you use IsGenuineEx(), then for all intents and purposes it is deactivated (because your app won't know otherwise). However, TurboActivate doesn't remove the activation files. This allows you to handle cases where the customer is "deactivated" because they failed to allow internet connections to the activation servers.

How? Like I said. Call IsActivated(), if it returns TA_OK, then you know that the "deactivation" was a result of IsGenuineEx() not being able to reverify with the activation servers (because you should only be calling IsActivated() in the case where IsGenuineEx() returns TA_FAIL).

IsActivated() doesn't connect to the Internet so it can't do anything there.

I don't understand the question. IsActivated doesn't connect to the internet. That's correct. It verifies the cryptographic signature of the activation data locally.

Don't use IsActivated and then IsGenuineEx(). Just use IsActivated() in the case where IsGenuineEx() returns TA_FAIL, and then you're only using it to see whether the failure is because the user is not activated (or was never activated) or if the failure is because the user never connected to the internet and/or actively blocks the activation servers.

I don't have buttons in my program (it's a text interface which at least for now either asked for the key or refused to start without valid license).

OK, then do it through text.

Is it going to work from users perspective or are they going to be forced to wait 5hours to use the program in scenarios 1 and 2?

It depends. That's why you should show a prompt to the user (whether it's a dialog box or a text prompt, it doesn't matter). Then, in that prompt give the user and option to recheck immediately. How? Again, like I said, call IsGenuine().

>>It says it's deactivated. And if you use IsGenuineEx(), then for all intents and purposes it is deactivated (because your app won't know otherwise). However, TurboActivate doesn't remove the activation files. This allows you to handle cases where the customer is "deactivated" because they failed to allow internet connections to the activation servers.

But there is a problem with this. Say I revoke the key or deactivate one of the activations. IsGenuineEx is going to return TA_FAIL then but if it doesn't remove license files it means that the user can continue to use it if there is a button (or w/e) which only calls IsActivated.

That's why I thought (and still hope as it makes little sense otherwise) that IsGenuineEx deactivates the license after returning TA_FAIL. If it doesn't I can't expose a call to IsActivated because that would defeat the purpose of the online check, wouldn't it?

Ok I just need to know if a call to IsGenuineEx deactivates the license on a computer after returning TA_FAIL so subsequent call (if made) to IsActivated returns TA_FAIL as well.If that's the case I can handle all the use cases.

Ok I just need to know if a call to IsGenuineEx deactivates the license on a computer after returning TA_FAIL so subsequent call (if made) to IsActivated returns TA_FAIL as well.

No, like I've been saying: it doesn't, and that's by design and a good thing.

We're improving our examples to show how to actually use these functions. The next version of TurboActivate will include these updated examples. Here's code that will explain how to do it:

#include "TurboActivate.h"


/* The handle used for TurboActivate function calls. */uint32_t taHandle;


int main(int argc, char** argv){    /* Used to store TurboActivate responses. */    HRESULT hr;    GENUINE_OPTIONS opts;    opts.nLength = sizeof(GENUINE_OPTIONS);


    // How often to verify with the LimeLM servers (90 days)    opts.nDaysBetweenChecks = 90;


    // The grace period if TurboActivate couldn't connect to the servers.    // after the grace period is over IsGenuinEx() will return TA_FAIL instead of    // TA_E_INET or TA_E_INET_DELAYED    opts.nGraceDaysOnInetErr = 14;


    // In this example we won't show an error if the activation    // was done offline by passing the TA_SKIP_OFFLINE flag    opts.flags = TA_SKIP_OFFLINE;


    /* Get the handle that will be used for TurboFloat function calls.


       TODO: paste your Version GUID here.    */    taHandle = TA_GetHandle(_T("18324776654b3946fc44a5f3.49025204"));


    hr = TA_IsGenuineEx(taHandle, &opts);


    if (hr == TA_OK || hr == TA_E_FEATURES_CHANGED || hr == TA_E_INET || hr == TA_E_INET_DELAYED)    {        TCHAR * featureValue;


        printf("YourApp is activated and genuine! Enable any app features now.\n");


        if (hr == TA_E_INET || hr == TA_E_INET_DELAYED)        {            // TODO: show a warning to your user that this time (or the last time)            // the IsGenuineEx() failed to connect to the LimeLM servers.            printf("YourApp is activated, but it failed to verify the activation with the LimeLM servers. You can still use the app for the duration of the grace period.\n");        }


    }    else // not activated or genuine    {        uint32_t trialDays = 0;


        // Look in TurboActivate.h for what the error codes mean.        printf("Not activated: hr = 0x%x\n", hr);


        // now check if the failure was a result of the customer not being activated        // or if the failure was a result the customer not being able to re-verify with        // the activations servers.        if (TA_IsActivated(taHandle) == TA_OK)        {            // There is still activation data on the computer, and it's valid.


            // This means that IsGenuineEx() is saying "not activated" (a.k.a. TA_FAIL)            // because the customer blocked connections to the activation servers (intentionally or not)            // for nDaysBetweenChecks + nGraceDaysOnInetErr days.


            // So, what you should do now is prompt the user telling them before they can use your app that they need            // to reverify with the activation servers.


            char userResp = 0;


            printf("You must reverify with the activation servers before you can use this app. Type R and then press enter to retry after you've ensured that you're connected to the internet. Or to exit the app press X.\n");


            while ((userResp = getchar()) != 'X' && userResp != 'x')            {                if (userResp == 'R' || userResp == 'r')                {                    // Now we're using TA_IsGenuine() to retry immediately. Note that we're not using                    // TA_IsGenuineEx() because TA_IsGenuineEx() waits 5 hours after an internet failure                    // before retrying to contact the servers. TA_IsGenuine() retries immediately.                    hr = TA_IsGenuine(taHandle);


                    if (hr == TA_OK || hr == TA_E_FEATURES_CHANGED)                    {                        printf("Successfully reverified with the servers! You can now continue to use the app!\n");                        break;                    }                    else                    {                        printf("Failed to reverify with the servers. Make sure you're connected to the internet and that you're not blocking access to the activation servers. Then press R to retry again.: Error code = 0x%x\n", hr);                        //Note: actually show a human readable error code to the customer!                        // hr = 0xNN is not a useful error code. Look in TurboActivate.h for a                        // full list of error codes and what they mean.                    }                }                else                {                    printf("Invalid input. Press R to try to reverify with the servers. Press X to exit the app.\n");                }            }


            // exit the app            if (userResp == 'X' || userResp == 'x')                return 1;        }        else        {            // The customer was never activated or deactivated (or got deactivated).        }




        // Start or re-validate the trial if it has already started.        // This need to be called at least once before you can use        // any other trial functions.        hr = TA_UseTrial(taHandle, TA_SYSTEM);


        if (hr == TA_OK)        {            // Get the number of trial days remaining.            hr = TA_TrialDaysRemaining(taHandle, &trialDays);


            if (hr == TA_OK)                printf("Trial days remaining: 0x%x\n", trialDays);            else                printf("Failed to get the trial days remaining: hr = 0x%x\n", hr);        }        else            printf("Failed to UseTrial: hr = 0x%x\n", hr);




        //TODO: prompt for a product key (if it's not present)        //Note: here we're just hard-coding the product key to show how you        //      save the product key and try to activation


        // Also note we're using the TA_SYSTEM flag. This means the activation will be system-wide.        // However calling using the TA_SYSTEM flag (the first time only) requires system-admin privileges.        // If your app will never have system admin privileges then you can use the TA_USER flag.        hr = TA_CheckAndSavePKey(taHandle, _T("Insert product key"), TA_SYSTEM);        if (hr == TA_OK)        {            printf("Product key saved successfully.\n");


            // try to activate            hr = TA_Activate(taHandle, NULL);


            if (hr == TA_OK)                printf("Activated successfully\n");            else                printf("Activation failed: hr = 0x%x\n", hr);        }        else            printf("Product key failed to save: hr = 0x%x\n", hr);    }


    printf("Hello world.");    return 0;}

Notice how IsActivated() is never exposed to the user -- it's just used to check whether they're "really deactivated" or "just deactivated because they blocked the activation servers". And it give the user a specific action to take to fix the problem without contacting you.

Make sense?

>>Make sense?

Yes, this is perfect.Last question: when I get TA_E_REVOKED flag, do I need to call Deactivate myself or is does IsGenuineEx handle deactivating the license itself?

IsGenuineEx handle deactivating the license itself?

Yes, IsGenuineEx handles the deactivation of the license data itself.

Ok, thank you very much. You guys are very helpful!