Fog Creek Software
g
Discussion Board




Weird COM problem - works in VBS but not in ASP?

I've inherited an undocumented COM object which our shop uses to generate machine-tied licenses for our product. 

Although it works fine on it's production box, I've been wrasslin' with getting the thing to work under a fresh machine and am having some strange results.

I wrote 2 test scripts - nearly identical VBS and ASP.  The

VBS works perfectly -
A134-VB43C

but the ASP returns a whole bunch of
HHHH-HHHH

My C++ detectives tell me these are bad characters - but I cannot see any difference in the scripts - aside from createobject vs. server.createobject and msgBox(result) vs response.write(result)

Anyone have any good testing ideas, or perhaps something obvious I'm missing?  the author and source appear to have disappeared, alas.

Thanks in advance to anyone who replies.

Ted
Saturday, January 10, 2004

Not enough information!

Joel Spolsky
Saturday, January 10, 2004

Sorry- here's some more I've scraped up.

The COM object appears to just call another DLL which actually contains the algorthm to generate the keys themselves.

I think these lines may be the culprit:


STDMETHODIMP KeyGenerator::getNewKey {

..call the DLL that makes the key...

BSTR keyResult = _com_util::ConvertStringToBSTR(pstrLicenseString);
   
*Key =     keyResult;
    
SysFreeString(*Key);

return S_OK;
}

Ted
Saturday, January 10, 2004

My two thoughts are:
1) Permissions issue
2) Regional encoding from IIS

Codewhore
Saturday, January 10, 2004

More code!

The SysFreeString is suspicious.

Joel Spolsky
Saturday, January 10, 2004

I gave full control permissions to Everyone and the IUSR on the DLL's that didn't seem to help.  Looking into the regional settings.

Joel, here's the complete method that's called by the VB hope the formatting is OK -

STDMETHODIMP CKeyGenerator::getNewKey(BSTR machineId, long licensetype, long eval, long *array, long *lSerial, BSTR *Key)
{
                array[0]=0;
    array[1]=0;
    array[1]=0;
    array[2]=0;
    array[3]=0;
    array[4]=0;
    array[5]=0;
    array[6]=0;
    array[7]=0;
    array[8]=0;
    array[9]=0;
    array[10]=0;
    array[11]=0;
    array[12]=0;
    array[13]=0;
    array[14]=0;
    array[15]=0;
    array[16]=0;
    array[17]=0;
    array[18]=0;

    char acMachineId[1024] = "";

    char string[1024]="";
    char *pstrMachineId = &acMachineId[0];
    char *pstrLicenseString= &string[0];
    licensetype=0;
    eval=0;
    
    long aSerial=0;
    *lSerial = aSerial;
    long NumberOfValues=(sizeof(array)/sizeof(long));

        pstrMachineId = _com_util::ConvertBSTRToString(machineId);
        SysFreeString(machineId);
        
    LicenseGenCreate(NULL, &pstrLicenseString, lSerial, licensetype, eval, pstrMachineId, NumberOfValues, array);    
    


    BSTR keyResult = _com_util::ConvertStringToBSTR(pstrLicenseString);
   
    *Key =     keyResult;
    
     SysFreeString(*Key);

    return S_OK;
}


I am going to run to the office for a few hours - thanks a lot for your help, guys

Ted
Saturday, January 10, 2004

Also should note that it's returning TTTTTTT-TTT-TTT, not HHHH-HHHH-HHHH, if that matters.

Ted
Saturday, January 10, 2004

*Key =    keyResult;
SysFreeString(*Key);


As Joel said, once you free the *Key you will get undetermined results. In an optimistic case the *Key won’t be de-allocated right away so you will get by chance a valid key. If you use this method in an inter-process or inter-apartment call (the IIS for instance), the marshaller won’t reconstitute the string on the other side and you will get just a raw patch of memory. 

coresi
Saturday, January 10, 2004

Thanks much guys.  I commented out the SysFreeString, recompiled, but still no dice.  I'll keep diggin'

Ted
Sunday, January 11, 2004

The issue turned out to be that the DLL's needed to be separately registered using Component Services!  Thanks for your help.

Ted
Sunday, January 11, 2004

Ted, as coresi and Joel said, the SysFreeString is in the wrong place - if you free the string before returning then when the calling function uses it it may not contain your string any more.  Even though it's working at the moment it will fail later on and if the caller is freeing the memory like it normally should then you may get other more serious problems like heap corruption instead.

r1ch
Sunday, January 11, 2004

*  Recent Topics

*  Fog Creek Home