Hi Wyatt,
Sure, I've included an example code below. When running this smaller code I have not duplicated the crash on calls to TF_RequestLease. But the program does hang on exit fairly consistently. In debug sessions I see this exception reported:
First-chance exception at 0x000000013F2CA21E in tftest.exe: 0xC0000096: Privileged instruction.
The call stack in my previous post is the main reason I suspected a problem in the crypto++ library. It died at a call to memcpy. The revised Put2 routine does not call memcpy:
// filters.cpp - written and placed in the public domain by Wei Daisize_t ArraySink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking){ CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking);
// Avoid passing NULL pointer to memcpy. Using memmove due to // Valgrind finding on overlapping buffers. size_t copied = 0; if (m_buf && begin) { copied = STDMIN(length, SaturatingSubtract(m_size, m_total)); memmove(m_buf+m_total, begin, copied); } m_total += copied; return length - copied;}
For reference, my TF libraries have a build date of 1/31/2017. My windows dev environment is MSVS Professional 2013.
Here is my example code. It mimics the floating license function of my larger application, but replaces error logging with messages to stdout.
[code=c++]#include <string>#include <iostream>
#define TURBOFLOAT_STATIC#include "TurboFloat.h"
//Product detail header#include "pdets.h"//This header defines://#define TurboActivate_GUID "GUID string"//unsigned char TurboActivate_dat[] //unsigned int TurboActivate_dat_len
#ifdef _WIN32#include <tchar.h>#define MBSTRJOIN(x,y) x##y#define TA_GUID(x) MBSTRJOIN(L,x)#else#define TA_GUID(x) x#endif
void TF_CC FloatingLeaseCallback( uint32_t status ){
}
int main( int argc, char* argv[] ){ std::string server_hostname = "localhost"; unsigned short server_port = 20013;
//Used to store TurboFloat responses. HRESULT hr;
// Load the product details from pdets.h hr = TF_PDetsFromByteArray( TurboActivate_dat, TurboActivate_dat_len );
if ( hr == TF_E_PDETS ) { //This should not fail. The product data must be malformed std::cout << "Product details failed to load."; return -1; //no need to continue } //Get the handle that will be used for TurboFloat function calls. unsigned int license_handle = TF_GetHandle( TA_GUID( TurboActivate_GUID ) );
//Set the callback function for the license monitor hr = TF_SetLeaseCallback( license_handle, FloatingLeaseCallback );
hr = TF_HasLease( license_handle ); if ( hr != TF_OK ) hr = TF_RequestLease( license_handle );
if ( hr != TF_OK ) { //We don't have a lease. //Save the server address, then make the request again.#ifdef _WIN32 const size_t servlen = server_hostname.size( ) + 1; size_t csz = 0; STRTYPE server_name = new wchar_t[servlen]; mbstowcs_s( &csz, server_name, servlen, server_hostname.c_str( ), server_hostname.size( ) );#else STRTYPE server_name = new char[hostname.size( ) + 1]; memcpy( server_name, hostname.c_str( ), hostname.size( ) ); server_name[hostname.size( )] = 0;#endif
hr = TF_SaveServer( license_handle, server_name, server_port, TF_SYSTEM ); if ( hr == TF_E_PERMISSION ) hr = TF_SaveServer( license_handle, server_name, server_port, TF_USER );
if ( hr != TF_OK ) { std::cout << "Failed store the floating license server: " << server_hostname << " : " << server_port << std::endl; } else { //try to get a lease again hr = TF_RequestLease( license_handle ); } delete[] server_name; } if ( hr == TF_OK || hr == TF_E_LEASE_EXISTS ) std::cout << "Floating license acquired." << std::endl; else std::cout << "Failed to acquire a floating license: " << hr << std::endl; //cleanup if ( TF_HasLease( license_handle ) == TF_OK && TF_DropLease( license_handle ) != TF_OK ) std::cout << "Error dropping TF lease."; if ( TF_Cleanup( ) != TF_OK ) std::cout << "Error on TF cleanup";
return 0;}
#if defined(_WIN32)#ifdef TURBOFLOAT_STATIC#ifdef _DEBUG#ifdef _DLL#pragma comment(lib, "TurboFloat-MDd.lib")#else#pragma comment(lib, "TurboFloat-MTd.lib")#endif#else#ifdef _DLL#pragma comment(lib, "TurboFloat-MD.lib")#else#pragma comment(lib, "TurboFloat-MT.lib")#endif#endif#else#pragma comment (lib, "TurboFloat.lib")#endif#endif[/code]