What to do after I get "deactivation request" file?Answered

Hi again 😀

I've got offline activation working within my app, but now I'm working towards offline deactivation.

For the activation leg, I first call ActivationRequestToFile() and then use ActivateFromFile() to finish the offline activation. Everything works great.

For the deactivation leg, I call DeactivationRequestToFile() but what do I do with that file? There is no DeactivateFromFile() method in the C++ TurboActivate API. What do I do with that file once the user has it saved to disk?

Thanks for your time and help!

Arie

Hi. 🙂

What do I do with that file once the user has it saved to disk?

You just simply submit it to the manual activation/deactivate form or web API in LimeLM.

When you call DeactivationRequestToFile() it deactivates the customer's computer immediately locally, but when you submit the file to LimeLM is when the deactivation happens on the servers.

Does that make sense?

Okay, got it, makes sense. Thanks for clarifying.

Arie

Quick follow up question to this. Once it's deactivated locally after using the ActivationRequestToFile() method, can the user re-activate using either the online method or offline method? Or, must the generated deactivation request file be first delivered to the LimeLM servers?

Thanks,Arie

Yes, they can re-activate using the same offline activation file. The way to prevent this is to disallow deactivations for the product key, or only allow activations after the offline activation file has "expired" (default 1-week from when it was requested).

Does that make sense?

Yes. Makes sense, I will likely just disallow deactivation for products keys used in offline environments, but how do we "allow activations after the offline activation file has 'expired' "? How do we do that in the source code of our apps?

Thanks,Arie

It would be done on your servers. So, if you add a form like described here you would modify it so that it accepts a product key as well as the deactivation request file. And then, in the code, check when the activation was done and disallow deactivations conditionally.

Hmmmm... I think we should make this easier. We'll think about this problem.

If you're processing offline activation / deactivations manually then you can just look at the product key the deactivation is for.

Hi Wyatt,

I'm picking up this thread again as I'm troubleshooting issues related to offline activation.  I've got it working, but as you mention in this thread a user can successfully activate a product using the same activation response file anytime before it expires.  I've tested this and it indeed appears to be the case on the machine, locally.  However, I've noticed that LimeLM does not get updated with any activation information (OS, IP, Extra Data, Date, etc.) in this case.

Here is what I'm doing to quickly test:

  1. Generate offline activation file.
  2. Send offline activation file to API to download a response activation file
  3. Submit response file to product and activate it successfully.
  4. Verify that LimeLM has received activation data — it has.
  5. Deactivate the product online to ensure both the product is deactivated and LimeLM “realizes” the product is deactivated.  This works.
  6. Submit the same response file to activate the product once more.  TA_ActivateFromFile() return success.
  7. No data is sent to, or displayed, in LimeLM regarding the second-time activation.

Is there something I'm doing wrong?  I'm okay if the user wants to re-activate in the period before the activation response file expires, but why doesn't the data show up in LimeLM?   I want to clarify for deactivation I keep the product key locally — that is I use 0 for the eraseKey parameter.

Thanks,

Arie

I'm picking up this thread again as I'm troubleshooting issues related to offline activation.  I've got it working, but as you mention in this thread a user can successfully activate a product using the same activation response file anytime before it expires.  I've tested this and it indeed appears to be the case on the machine, locally.  However, I've noticed that LimeLM does not get updated with any activation information (OS, IP, Extra Data, Date, etc.) in this case.

Correct. It's offline activations. So… it doesn't do anything online.

The data is *only* updated on the servers when the activation request is sent to the servers and a success activations response is returned. That’s it.

I'm not sure what the question is.

, edited

Yes, this makes sense since it's totally offline.  

The question is: why can the activation response file can be used more than once?

Another question:  if the activation response file is sent to a different machine than the one it was created on, will it activate that other machine?

To avoid any re-use of the file, I've decided that the application will delete the activation response file upon successful offline activation.

Thanks,
Arie

Answer

The question is: why can the activation response file can be used more than once?

Because the it's completely disconnected from any server-side verification. Hence, us recommending *always* use online activation (with re-verification every X days) rather than offline activation.

Another question:  if the activation response file is sent to a different machine than the one it was created on, will it activate that other machine?

No, it's node-locked.

To avoid any re-use of the file, I've decided that the application will delete the activation response file upon successful offline activation.

Ok, the user will still likely have a copy from wherever they got the file from. But, you can do that if you want. It's not an actual solution to any problem (and it adds flaky code).

Just require online activation. Or if they need offline activation don't allow them to deactivate.

Thanks again for the answers.

I've got offline activation working fine on the macOS side, but on Windows, the TA_ActivateFromFile() function will not return anything but TA_FAIL (1).  I am NOT using static libraries for TurboActivate on macOS or on Windows, so the DLL I am build is loading into the host app because I have verified other functions are fine.

Here is the code I have to support both macOS and Windows for activating from the file.  Note that the data coming in from the host app is of type string, and I have no control over that data type, so I have to do some type conversion on the string that represents the file path:

 HRESULT hr;
 
 string fileLoc(argv[0].data.string);
     
 #if _WIN32
     CA2W fileLoc_W(file.c_str());
     wstring fileLocation = fileLoc_W;
     hr = TA_ActivateFromFile(taHandle, fileLocation.c_str());
 #else
     hr = TA_ActivateFromFile(taHandle, fileLoc.c_str());
 #endif
       
 retval->data.intval = hr;

I have verified this works in macOS perfectly, but on the Windows side, even though my debugger output is showing the correct file path to the activation response, the TA_ActivateFromFile() function is always failing.  To be more specific, when I look at the watched variables when I break the program execution, the fileLocation variable is set to L"C:\\Users\\me\\Downloads\\ActivationResponse.xml" which was downloaded from LimeLM, not our own Web API that calls LimeLM.

I do see multiple “Access is denied” messages coming from the debug output window that reads:

onecore\com\combase\dcomrem\resolver.cxx(2299)\combase.dll!00007FFA11BC206D: (caller: 00007FFA11BC4F4E) ReturnHr(2) tid(2bcc) 80070005 Access is denied

I verified that the ActivationResponse.xml file has read, write, and execute permissions for all users just to be sure.  I've tried multiple different things here, but am at a loss for this one.  Any suggestions or thoughts as to why it would fail on Windows but not on macOS given the code?

, edited

Just pass that string in as a literal, rather than converting back and forth between a few different magic string classes.

Then work backwards from there.

I'll do that, and let you know the result.  just Curious if you think it is a permissions issus with the DLL that we build that this code exists in.  This error does not come up when we use the static libs of TA.  I'm wondering if there is something we need to do to force elevated privileges in the code Before calling TA_ActivateFromFile.

Using a string literal does not work.  I have double and triple checked that the string matches the exact path of the activation response file.

I did this:

hr = TA_ActivateFromFile(taHandle, L"C:\\Users\\me\\Downloads\\ActivationResponse.xml");

Same error TA_FAIL (S_FALSE, 1).  The same debugger output about access denied also appears.

I also started the host app as an Administrator but that still did not work.

, edited

Or the activation response is invalid. Try again from the beginning:

1. check and save pkey

2. Generate activation request

3. use activation response.

I just retried it and verified that TA_CheckAndSavePKey() was called with the product key to generate the XML request file.  I inspected the XML request file and it looked fine.  I went to the Manual Activation form on LimeLM, and I retrieved the file ActivationResponse.xml and then I verified that the product key was actually activated on the server - the extra data is passed correctly, too (according to the ExtraData column in the activation listing for the product key).

Then, when I went back to the app (in Windows), and pointed it to the ActivationResponse.xml and verified that the path was correct in the debugger when I stepped through.

I'm at a loss here, and keep thinking it's a permissions thing, but even running as an administrator it returns a fail.  I've tried adjusting the line endings in the XML file to Unix instead of CRLF, and no dice there.  I verified that the generated file uses UTF-8 character encoding, too.

This is really annoying since it works perfectly on macOS.  Windows wants to be a party pooper :)

OMG I think I found the cause!  I decided to send NULL for the extra data in the TA_ActivateFromFile() call.  And, went through the entire process again, and it worked!

Here is the string that is sent with the ExtraData, please know that this DOES get stored with the activation on LimeLM servers:

[Win 10.0.19042], [me@MYMACHINE-WIN10], [HST 22.0.1x2], [APP 3.0.0 (14025 DBG)]

Are there any characters that are NOT allowed in the extra data string?  Maybe its the strange “x”?  Maybe the way the XML response file is encoded is causing issue on Windows when using the response file?

…. edit

Okay, I found a bug in my case.

On Windows only, if the extra data string contains a newline character (\n) when calling TA_ActivationRequestToFile(), then TA_ActivateFromFile() will not work because it cannot interpret the XML response file correctly.  When I removed the newline (\n) character from the extra data string, then TA_ActivateFromFile() was able to interpret the XML file correctly.  

, edited