Question about IsGenuine() method

First, let me thank you for a so far useful product and service!

Just have a little problem/question about the IsGenuine method:

I suppose that when the user has successfully activated his product key, it will be stored locally. So if we never call IsGenuine to check if it is still valid, the product is activated even if the product key has been revoked on the server.

So, as recommended in the help, I have added a function that for an already activated user,. calls the IsGenuine method every 60th day.

In this case, I've used Delphi code like the following:

function ValidatedUser : boolean;// validate an already activated uservar Turbo : TurboActivate; VerGuid : PWideChar; NeedsReactivate : boolean;begin Result := false;

try GetMem(VerGuid, sizeof(WideChar)*Succ(Length(sMyVersionGuid)));

try StringToWideChar(sMyVersionGuid, VerGuid, Succ(Length(sMyVersionGuid))); Turbo.VersionGUID := VerGuid; if not Turbo.IsActivated then // not activated, we must still be in grace period Exit;

NeedsReactivate := false;

if not Turbo.IsGenuine(NeedsReactivate) then begin Application.MessageBox(PChar('Your key is not valid'), 'Message', mb_IconStop+mb_OK); Halt; end else begin if NeedsReactivate then Turbo.Activate;

Result := true; end;

finally FreeMem(VerGuid); end; except // just swallow end;end;

As a note, we swallow the exception here, so if the user is not connected to the internet, nothing happens. Of course it should be dealt with, if we cannot call the server to validate the key. But that is not the point of this question.

My problem is that, that as a test I have deactivated this product key on the server, so that the number of possible activations is 1, and used activations is 0.

Then the IsGenuine call above returns true because the product key is still valid and not revoked. This is in line with what I have expected.

But the NeedsReactivate boolean is returned as FALSE. I would expect it to return TRUE in this case, because the product is not activated on the server. Or am I missing something?!

And otherwise, does my code above make sense, or could it be done better?

Thanks for any help!

//Chris

First, let me thank you for a so far useful product and service!

It's our pleasure.

As a note, we swallow the exception here, so if the user is not connected to the internet, nothing happens. Of course it should be dealt with, if we cannot call the server to validate the key. But that is not the point of this question.

You probably already know this, but you should warn the user subtly. Then retry the next time the user runs your app. After 5 or so consecutive failed IsGenuine() checks give the user an error and prevent them from continuing to use your app until they connect and validate with the LimeLM servers.

This will prevent a certain types of "dumb hacks" like preventing your app from connecting to the internet using firewall software or redirecting the LimeLM servers to localhost in the "hosts" file.

My problem is that, that as a test I have deactivated this product key on the server, so that the number of possible activations is 1, and used activations is 0.

Then the IsGenuine call above returns true because the product key is still valid and not revoked.

Actually it should return false. (I.e. the response should be non-zero, not TA_OK). It will also deactivate the license, but it will leave the product key installed.

Can you step through your "IsGenuine" function and see if the result is non-zero?

HiI've reriun and checked my account again. There is only one versionGUID and I have one product key created so far. This product key has Used/Activations as 0/1.

When reaching your code in TurboActivateUnit.pas:

/// <summary>/// Checks whether the computer is genuinely activated by verifying with the LimeLM servers./// </summary>/// <param name="needsReactivate">Whether this product needs to be reactivated by calling Activate()</param>/// <returns>True if this product is genuine, false otherwise.</returns>class function TurboActivate.IsGenuine(var needsReactivate : boolean): boolean;var ret : LongInt;begin ret := TurboActivateUnit.IsActivated(TurboActivate_VersionGUID);

case ret of 3: // TA_E_ACTIVATE raise ENotActivatedException.Create(); 4: // TA_E_INET raise EInternetException.Create(); 7: // TA_E_GUID raise EGUIDMismatchException.Create(); 8: // TA_E_PDETS raise EProductDetailsException.Create(); 10: begin needsReactivate := True; Result := True; exit; end; 11: // TA_E_COM raise ECOMException.Create(); 0: // successful begin needsReactivate := False; Result := True; exit; end; end;

Result := False;end;

.. When stepping through the code in the debugger, I see that the value of ret is 0 after the call, so it reaches the last branch in the case-statement. This means that the needsReactivate paramater is set to False, and Result is set to True.

To recapitulate, the number of used activations is 0, which I can see when I login to my account.This means that the product is not activated, so I expected it to return True (because it is a valid product key, not revoked), but with NeedsReactivate set to True (because it is deactivated, and thus needs reactivating).

//Chris

It looks like we made a typo. I'm sorry about about the trouble. The IsGenuine function in TurboActivateUnit.pas should read as follows:

/// <summary>/// Checks whether the computer is genuinely activated by verifying with the LimeLM servers./// </summary>/// <param name="needsReactivate">Whether this product needs to be reactivated by calling Activate()</param>/// <returns>True if this product is genuine, false otherwise.</returns>class function TurboActivate.IsGenuine(var needsReactivate : boolean): boolean;var  ret : LongInt;begin  ret := TurboActivateUnit.IsGenuine(TurboActivate_VersionGUID);


  case ret of    3: // TA_E_ACTIVATE      raise ENotActivatedException.Create();    4: // TA_E_INET      raise EInternetException.Create();    7: // TA_E_GUID      raise EGUIDMismatchException.Create();    8: // TA_E_PDETS      raise EProductDetailsException.Create();    10:    begin      needsReactivate := True;      Result := True;      exit;    end;    11: // TA_E_COM      raise ECOMException.Create();    0: // successful    begin      needsReactivate := False;      Result := True;      exit;    end;  end;


  Result := False;end;

Note that the correct line is

ret := TurboActivateUnit.IsGenuine(TurboActivate_VersionGUID);

and not:

ret := TurboActivateUnit.IsActivated(TurboActivate_VersionGUID);

I apologize. We'll have the corrected version as part of the TurboActivate 2.4 release. But for now you can just change the file.

Now the IsGenuine function will return false (as expected).

Hi againThanks for your great support!

I'll make the change in the .pas file for now. Glad that it seems I've got the meaning of the functions right, and use them in the right way.

Now knowing what the error was, I should probably have found it myself, having thought more about it...

//Chris