views:

163

answers:

8

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;
    }
A: 

That non-deterministic crashing behavior is often seen with memory overwrites/corruption; sometimes it matters (crash), sometimes you get lucky.

You might want to check into getting a crash dump and analyze it with WindDbg. Since you have the source you could re-build it with the various stack, heap memory protection and warning systems enabled (depending on your compiler) and see what you get.

S.Skov
im building in vs2008, and will investigate windbg,
Nathan
A: 

I'd find out if it is a User Account Control related problem, you can try to disable it. 2003 doesn't have UAC. Your app pool account might not have the right to retrieve this information?

ArjanP
Good idea, but it doesn't make a difference im afraid
Nathan
A: 

I made a new C++ DLL from scratch which works fine when referenced as a console application on Windows Server 2003 and Windows Server 2008, but as soon as I reference it from the DLL in SharePoint the same things happens and it won't run.

It does find the DLL, but I think it has no permissions to execute it, even if I put it into the My Documents section and reference it directly!

Nathan
+1  A: 

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

lsalamon
During my reading WMI was often said to be unreliable, a problem in licensing software! Also the company have 'decided' that c++ is more secure as it does the low level stuff itself and cannot be infiltrated by a middleman, apparently!
Nathan
Well the reliability seems true, on my machine I get a name but no serial!
Nathan
+2  A: 

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 ;-)

Anders Rask
To test this I have tried creating everything as Administrator, app pool, current session, everything! Still no luck, obviously I dont want to run like this forever but as a way of testing its appropriate I think?
Nathan
well did you try what i described above?
Anders Rask
Yes, thanks for the tip but still no luck, it doesn't change anything and I get the same results
Nathan
A: 

Hi three things:

  1. In visual studio, go into the properties of your executable assembly, and under the debug tab, check the enable debugging unmanaged code option.

  2. If the method your are importing belongs to a class, you need to add the mangled C++ name (e.g. 2@MyClass@MyMethod?zii) as an entry point to the DllImport attribute (run depends on the native DLL to get it).

  3. You do not need C++ for that: http://www.codeproject.com/KB/cs/hard_disk_serialno.aspx

Danny Varod
1: The option was selected already.2: The method is not contained in a class as far as I know, and would this explain why it works in 03 and as a console app but not within sharepoint? 3: I've tried that method and can't get it to work reliably, or at all!
Nathan
A: 

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

"step in: Stepping over non user code"

That's the debugger, not the compiler, and if you configured it properly it wouldn't do that. Look for the options calls "Use native debugging" and "Just my code". The first one should be on and the second one off.

Ben Voigt
Thanks, if I untick just my code i just get the "no sourcecode for this location" error, and it won't even debug the C# dll that worked before!
Nathan
Did you deploy the .pdb file alongside the DLL? That's necessary for debugging the native side of things.And depending on which option you're looking at exactly, there may be an option for Hybrid or Both (native and managed debugging). But I think that only applies to starting the JIT debugger.
Ben Voigt
Yes I used the .pdb file
Nathan
A: 

This problem may happen due to one of the problems listed below.

  • the web part may not have the right permissions to call the DLL or

  • you may not have set the appropriate trust level for your SharePoint site.

For the permission you can use impersonation and for the trust level below site can help you.

http://msdn.microsoft.com/en-us/library/dd583158(office.11).aspx

Hojo