having problems running a DLL/COM object from a simple php script on a Windows server

Hello...OK, here is the story: The DLL is part of a software security (anti-cracking) package I purchased about 9 years ago. It has since been discontinued by the creator, and I cannot find the creator (from Singapore). But I still use this package and it still works well. I have never used the DLL before until now (I have always only used the stand-alone EXE version right on my PC). Anyway, according to the documentation I have on how to run the DLL from PHP on a Windows Server with IIS (...whatever that means), the author gives this example code:

<?php $objKG = new COM("CodeLockKeyGen.KeyGen"); $result = $objKG->Get_RegistrationCode("12345678", "ED3E78BDB99C15A36DB6746B9966B6ECCFF62E8202EEB9956DC83B7F15C4AF00", "ChosenBytes", "RegFile - ChosenBytes.txt", True); echo $result; ?>

Open in new window

Please keep in mind I know next to nothing about PHP and COM, but this script looks simple enough. The DLL accepts a few strings and as output it generates an activation code. So I have made a very "bare-bones" php file with just that code to try this. When I run it, it returns with:

"The page cannot be displayed because an internal server error has occurred."

My first question, and probably a stupid one is: why isn't the name of my DLL file (Code-Lock Keygen.DLL) not declared anywhere in the PHP code? This is one thing I don't understand, and maybe it's part of the problem? I just don't understand how the PHP script can call this DLL, if it doesn't know the full name of the DLL file.
   Secondly, I don't understand about this line in the script:

$objKG = new COM("CodeLockKeyGen.KeyGen");

... I ran another software on the DLL that gives the name of the internal libraries within the DLL, and it said the library name is "CodeLockKeyGen". So why would this PHP command say : new COM("CodeLockKeyGen.KeyGen")   ? Why is there that extra ".KeyGen"?
   Now trying to get good answers from my webhost is just about impossible. I won't give their name, but they are incompetent.... they know nothing. i asked them several times "is everything ok on your end to run DLL's/COM objects". They said yes. Then after about an hour of wrangling with them, they finally cough up the tidbit that my DLL has to be in the BIN folder. I didn't know that... how was I to know that. There was no BIN folder, but there was a cgi-bin folder, so we moved my DLL file in there. Same result, same error.
   After more back and forth with no success... the whole time them saying it's the fault of my code, I discovered over google that maybe they were missing something else -->

" If you are seeing this in your error log:

Fatal error:  Class 'COM' not found

You require this in php.ini:


... so I asked them to put that in their php.ini. The tech support person didn't even know what a php.ini file was or where to find it. So after they got that set up, I tried to run it again, and still same error.

Can someone, SOME kind soul maybe take a look at the simple PHP script I outlined above and see where the code may be incorrect? Or what is lacking on the server side to do this?

This is just driving me nuts.

Thank You!
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

So first thing - a quick explanation. Think of a DLL file as a general-purpose kind of library. It can hold all sorts of different types of code, and not all of the kinds are COM objects.

Now, when you ask PHP to create a new instance of a COM object, it's not looking at the DLL file, it's asking Windows, "Hey, Windows, do you have a COM object named xyz?" Windows looks in a list of COM objects, which basically comes from "registering" a DLL file, and it looks for an object with that name.

Chances are that you haven't registered that DLL file yet, with Windows, which is a pretty easy fix. Basically, you go into the Command Prompt as an administrator (you may have to right-click on the Command Prompt icon and choose "Run as administrator"), and then go into the folder that has the DLL file and type:

regsvr32 "Code-Lock Keygen.DLL"

You should get a message indicating success or failure. If it's successful, then the COM object inside that DLL file is now registered in Windows under its internal name, which seems to be "CodeLockKeyGen.KeyGen".

At that point, you SHOULD be able to at least run this:
$objKG = new COM("CodeLockKeyGen.KeyGen");
echo "Hurray!";

...and see the "Hurray" message show up. If it doesn't, then it probably means that there's some other issue with the COM object extension, but at least give that registration a try first and see if it works.
shawn857Author Commented:
God bless you Gonzo! Nobody ever mentioned to me about registering it. Only thing now is, how do I get to the command prompt on that remote server to issue that command. I have FTP access to my files, and there is also a Plesk control panel... dut I don't see where to get to the command line from either of those....

Ah, if you don't have direct access, then you MIGHT not be able to do this - you may have to ask support to do it for you.

However, it's at least worth a shot to have PHP try and run the registration via a shell_exec() call:

$regsvr32 = "C:\\windows\\system32\\regsvr32.exe";
echo "Making sure PHP can see and run regsvr32...<br />\n";
if(file_exists($regsvr32)) { echo "ERROR: The regsvr32.exe executable does not exist!"; die(); }
echo "Looks good!<br />\n";

$dll = "C:\\www\\Code-Lock Keygen.DLL"; // Update this to reflect the full path to your DLL file.
echo "Making sure the DLL exists...<br />\n";
if(file_exists($dll) { echo "ERROR: {$dll} does not exist!"; die(); }
echo "Looks good!<br />\n";

echo "Trying to register {$dll}... <br />\n";
echo shell_exec("{$regsvr32} \"{$dll}\"");
echo "Finished the registration attempt!";

Open in new window

There's a pretty good chance it won't work this way, but you never know. Some providers might set up the server to let you have more permissions than usual.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
OWASP: Avoiding Hacker Tricks

Learn to build secure applications from the mindset of the hacker and avoid being exploited.

shawn857Author Commented:
Thank you Gonzo, I will try that php script of yours. I first have to find out the full path structure of my file.

Gonzo, does my DLL file need to be in any particular folder? Does it need to be in the cgi-bin folder or anything?

No, it does not need to be in any specific folder.
shawn857Author Commented:
OK, well I ran that script of yours Gonzo and it got the DLL registered. But still when I try to run it from my little PHP script, it fails. On my end it just shows:

"The page cannot be displayed because an internal server error has occurred."

I asked their chat support to try and run the script on their end and they told me it gave these errors:

Operator: Uncaught exception 'com_exception' with message 'Failed to create COM object `CodeLockKeyGen.KeyGen': Invalid syntax
Operator: ' in C:\Inetpub\vhosts\optimaloption.net\httpdocs\simplephptest.php:8
Operator: Stack trace:
Operator: #0 C:\Inetpub\vhosts\optimaloption.net\httpdocs\simplephptest.php(8): com->com('CodeLockKeyGen....')
Operator: #1 {main}
Operator: thrown in C:\Inetpub\vhosts\optimaloption.net\httpdocs\simplephptest.php on line 8

My PHP script calling the DLL looks like this Gonzo:

<title>test for dll</title>
<center><br> before dll call in php<br><br></center>
$objKG = new COM("CodeLockKeyGen.KeyGen"); 
$result = $objKG->Get_RegistrationCode("12345678", "ED3E78BDB99C15A36DB6746B9966B6ECCFF62E8202EEB9956DC83B7F15C4AF00", "ChosenBytes", "", True);
echo $result; 
<br><br> after dll call <br>

Open in new window

Line 8 would be:
$objKG = new COM("CodeLockKeyGen.KeyGen");

... do you see anything improper about that? Remember when I said in my opening message:

" I ran another software on the DLL that gives the name of the internal libraries within the DLL, and it said the library name is "CodeLockKeyGen". So why would this PHP command say : new COM("CodeLockKeyGen.KeyGen")   ? Why is there that extra ".KeyGen"?"

... could this have anything to do with it?

Thank You!
It's possible. You could always try just CodeLockKeyGen and see if that works. Typically, there's a package name and then a class name inside, so CodeLockKeyGen would be the package name and then KeyGen would be the class name, but there's no guarantee of that. It's really hard to guess at all of this without the author's support. :)
shawn857Author Commented:
Gonzo, if I was to send you the DLL, could you analyze it with one of those programs that show DLL contents, and maybe you can make sense of it? If so, do you have an emal address I could send it to... as I don't wish to attach it to a post and make it available to the world.

Shawn, send me a private message with the request and I can reply with an e-mail address. However, it all depends on the kind of DLL it is. Some kinds can be examined, some can't.
shawn857Author Commented:
OK, just messaged you Gonzo, thanks.

A few days ago I had used a program I found called "ActiveXplorer" to delve into that DLL. It seemed to work... here is what it found about it:

CodeLockKeyGen Interface definition

General information
Library: CodeLockKeyGen
File: C:\Code-lock\Copy of Code-Lock Keygen.DLL
Version: 3.0
File size (bytes): 64 KB
Date modified: 1/15/2004 10:48:40 AM


This sections lists interfaces exposed by CodeLockKeyGen. For each class, the methods and events are listed.

The demo version is able to display members of only one class in component


Public Sub QueryInterface(riid, ppvObj)
Public Function AddRef() As UInt32
Public Function Release() As UInt32
Public Sub GetTypeInfoCount(pctinfo As UInt) As UInt32
Public Sub GetTypeInfo(ByVal itinfo As UInt, ByVal lcid As UInt32, pptinfo) As UInt32
Public Sub GetIDsOfNames(riid, rgszNames As Byte, ByVal cNames As UInt, ByVal lcid As UInt32, rgdispid As Long) As UInt32
Public Sub Invoke(ByVal dispidMember As Long, riid, ByVal lcid As UInt32, ByVal wFlags As UInt16, pdispparams, pvarResult As Variant, pexcepinfo, puArgErr As UInt) As UInt32
Public Function Get_RegistrationCode(ProgramCode As String, UserData As String, UserName As String, FileName As String, Days_Limit As Boolean) As String

The docs for Code-Lock say that the "Get_RegistrationCode" function is the only "callable" function.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.