Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SharePoint fails to load a C++ DLL on Windows 2008

I have a SharePoint DLL that does some licensing things and as part of the code it uses an external C++ DLL to get the serial number of the hardisk.

When I run this application on Windows Server 2003 it works fine, but on Windows Server 2008 the whole site (loaded on load) crashes and resets continually. This is not Windows Server 2008 R2 and is the same in 64 or 32 bits.

If I put a Debugger.Break before the DLL execution then I see the code get to the point of the break and then never come back into the DLL again. I do get some debug assertion warnings from within the function, again only in Windows Server 2008, but I'm not sure this is related.

I created a console application that runs the C# DLL, which in turn loads the C++ DLL, and this works perfectly on Windows Server 2008 (although it does show the assertion errors, but I have suppressed these now). The assertion errors are not in my code but within ICtypes.c, and not something I can debug.

If I put a breakpoint in the DLL it is never hit and the compiler says:

"step in: Stepping over non user code"

If I try to debug into the DLL using Visual Studio.

I have tried wrapping the code used to call the DLL in:

SPSecurity.RunWithElevatedPrivileges(delegate()

But this also does not help.

I have the source code for this DLL so that is not a problem.

If I delete the DLL from the directory I get an error about a missing DLL. If I replace it, back to no error or warning just a complete failure.

If I replace this code with a hardcoded string the whole application works fine.

Any advice would be much appreciated, I can't understand why it works as a console application, yet not when run by SharePoint. This is with the same user account, on the same machine...

This is the code used to call the DLL:

 [DllImport("idDll.dll", EntryPoint = "GetMachineId", SetLastError = true)]
    extern static string GetComponentId([MarshalAs(UnmanagedType.LPStr)]String s);

    public static string GetComponentId()
    {
        Debugger.Break();
        if (_machine == string.Empty)
        {
            string temp = "";
            id= ComponentId.GetComponentId(temp);
        }
        return id;
    }
like image 542
Nath Avatar asked Oct 15 '22 08:10

Nath


2 Answers

This could be security related: An important point is that it works in a console app.

In a console app RunWithElevatedPrivileges has no effect since it emulates the app pool user for your worker process, a user that should have no special rights on the box itself.

In contrast a console app runs in context of the logged in user.

Try emulating a user with rights like when you run the console application specified here (with Undo() inside try/finally mind you!). When obtaining the token you can create an SPUserToken and establish site context using the SPSite constructor that takes a GUID and a SPUserToken

Theres several examples out there documenting this approach, here for example.

EDIT: oh and the reason it worked on 2003 could be that your app pool account had way too many rights ;-)

like image 72
Anders Rask Avatar answered Nov 03 '22 00:11

Anders Rask


Why not use WMI to get the serial number of hard disk, thus avoids execution of unmanaged code. See this sample How to Retrieve the REAL Hard Drive Serial Number

like image 23
lsalamon Avatar answered Nov 02 '22 22:11

lsalamon