Code Access Security предотвращает вызовы API установки PInvoking - PullRequest
0 голосов
/ 08 марта 2012

Я переписываю этот вопрос, так как теперь я понимаю немного больше. Изначально то, что у меня было, было слишком расплывчатым. Я обнаружил, что меня маршрутизирует нечто, называемое «Безопасность доступа к коду». Я уверен, что это знакомая всем, но не мне.

Приложение очень большое, поэтому в двух словах у меня две сборки. Одним из них является сборка утилит с различными «инструментами», используемыми в программе. Другой призывает эти инструменты, чтобы функционировать.

В сборке утилит есть много функций, которые вызываются PInvoked, но одна из них огорчает меня: SetupDiGetDeviceInterfaceDetail () ( см. Здесь ). Мой прототип функции выглядит так:

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

В сборке, которая использует эту функцию, я использую двухэтапный процесс, описанный в комментариях, чтобы понять, сколько места мне нужно для хранения DevicePath, который находится в структуре SP_DEVICE_INTERFACE_DETAIL_DATA ( см здесь ). Например:

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

Самое неприятное, что эти сборки используются двумя разными программами. Одним из них является графический интерфейс с использованием изолированной оболочки Visual Studio. Другой просто программа командной строки. Когда GUI работает, приведенный выше код вызывается и выполняется, как и ожидалось. Однако в средстве командной строки они терпят неудачу (как описано в справочнике MSDN для этой функции API настройки) с некоторыми данными о том, что произошло. На данный момент я могу восстановить только часть возвращенных данных. Вот что возвращается из среды выполнения: «stem.Security.PartialTrustVisibilityLevel, mscorlib, версия = 4.0.0.0, Culture = нейтральный, PublicKeyToken = b77a5c561934e089».

Я знаю, что это как-то связано с Code Access Security, но я совсем не уверен, как это исправить. Используя некоторые предложения, которые я нашел до сих пор, я попробовал этот атрибут в сборке (я поместил его перед блоком пространства имен): [сборка: AllowPartiallyTrustedCallers]

Но это вызвало другие проблемы компиляции.

Пожалуйста, все, что будет наиболее полезно и высоко ценится.

Andy

1 Ответ

0 голосов
/ 09 марта 2012

К сожалению, проблема еще не устранена. Однако проблема, похоже, не имеет ничего общего с Code Access Security, как я сначала подумал. Мне бросали красную сельдь. Я прошелся по коду, используя окно памяти в Visual Studio, и заметил, что эти строки были в памяти, прежде чем вызывать функцию Setup API для их заполнения. Иногда я получал другой блок памяти с другим содержимым, просто я обычно получал содержимое, которое вставил.

Проблема, по-видимому, как-то связана с 64-битной и 32-битной средами (по крайней мере, это моя теория на данный момент).

Однако этот вопрос не является реальной проблемой, поэтому я «отвечаю», чтобы закрыть его.

...