Question

I'm rewording this question since I understand a bit more now. Originally, what I had was too vague. I've discovered that I'm being routed by something called "Code Access Security." This is old-hat to everyone reading this, I'm sure, but not to me.

The application is very large so in a nutshell I have two assemblies. One is a utilities assembly with various "tools" used throughout the program. The other is calling upon these tools in order to function.

In the utilities assembly, there are many functions that are PInvoked but the one giving me grief is: SetupDiGetDeviceInterfaceDetail() (see here). My function prototype looks like this:

[DllImport("SetupApi.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return : MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetDeviceInterfaceDetail(
    SafeHandleZeroOrMinusOneIsInvalid deviceInfoSet,
    ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData,
    IntPtr deviceInterfaceDetailData,
    uint deviceInterfaceDetailDataSize,
    IntPtr requiredSize,
    IntPtr deviceInfoData);

In the assembly which uses this function, I'm using the two step process outlined in the remarks in order to gain the understanding of how much space I need to store the DevicePath which is in the SP_DEVICE_INTERFACE_DETAIL_DATA structure (see here). For example:

string GetDevicePath(SafeHandleSeroOrMinusOneIsInvalid hList, SP_DEVICE_INTERFACE_DATA infoSet)
{
    IntPtr pReqSize = Marshal.AllocHGlobal(4);
    Marshal.WriteInt32(pReqSize, 0);
    uint reqSize;

    // get the size needed
    PInvoke.SetupDiGetDeviceInterfaceDetail(hList,
                                            ref infoSet,
                                            IntPtr.Zero,
                                            0,
                                            pReqSize,
                                            IntPtr.Zero);

    reqSize = (uint)Marshal.ReadInt32(pReqSize, 0);

    IntPtr pDevInfoDetail = Marshal.AllocHGlobal((int)reqSize + 4); // +4 for cbSize

    // call again, this time getting the actual data wanted
    PInvoke.SetupDiGetDeviceInterfaceDetail(hList,
                                            ref infoSet,
                                            pDevInfoDetail,
                                            reqSize,
                                            IntPtr.Zero,
                                            IntPtr.Zero);

    string path;
    // work .NET magic to read from unmanaged memory the path string and assign it
    // to the above variable.  Deallocate both unmanaged memory blocks.

    return path;
}

The most frustrating thing is, these assemblies are used by two different programs. One is a GUI using the Visual Studio Isolated Shell. The other is simply a command line program. When the GUI is running, the above code is called and executes as expected. In the command line tool however, they fail (as described in the MSDN reference for this Setup API function) with some data about what happened. At this point, I'm able only to recover a portion of the data that is returned. This is what comes back from the runtime: "stem.Security.PartialTrustVisibilityLevel, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089".

I know this has something to do with Code Access Security but I'm not at all sure how to fix. Using some suggestions that I've found thus far I've tried this attribute to the assembly (I placed it before the namespace block of code): [assembly: AllowPartiallyTrustedCallers]

But this caused other compilation problems.

Please, anything would be most helpful and greatly appreciated.

Andy

Was it helpful?

Solution

Unfortunately, the problem isn't yet fixed. However, the problem appears to have nothing to do with Code Access Security as I first thought. I was being thrown a red herring. I stepped my way through the code using the memory window in Visual Studio and noticed that these strings were in memory before calling the Setup API function to fill them. Occasionally, I would get a different block of memory with different contents too, I just usually ended up with the contents I pasted.

The problem actually appears to have something to do with the 64 vs. 32 bit environments (at least, that's my theory at this point).

However, this question isn't the actual problem so I'm "answering" it to close it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top