Code Access Security предотвращает вызовы PInvoking Setup API

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

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

В сборке утилит есть много функций, которые 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. Другой - просто программа командной строки. Когда работает графический интерфейс, вышеприведенный код вызывается и выполняется, как и ожидалось. Однако в инструменте командной строки они терпят неудачу (как описано в справочнике MSDN для этой функции API установки) с некоторыми данными о том, что произошло. На данный момент я могу восстановить только часть возвращаемых данных. Вот что возвращается из среды выполнения: «stem.Security.PartialTrustVisibilityLevel, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089».

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

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

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

Энди


person Andrew Falanga    schedule 08.03.2012    source источник
comment
Не могли бы вы предоставить полную информацию об исключении, возвращаемом методом ToString()?   -  person Nicole Calinoiu    schedule 08.03.2012
comment
@Nicole Насколько я могу судить, никаких исключений не генерируется. Visual Studio не ломается из-за необработанных исключений, и мой код не заключен в блоки try/catch. Единственное, что я указываю, это то, что функция Setup API возвращает код ошибки 1784 (неверный пользовательский буфер) и помещает сведения об устройстве, предоставляющем доступ к интерфейсу, в член пути. К сожалению, когда я увеличиваю размер буфера, чтобы захватить все это, я получаю только бессмысленные данные.   -  person Andrew Falanga    schedule 08.03.2012
comment
Где вы находите ссылку на PartialTrustVisibilityLevel?   -  person Nicole Calinoiu    schedule 09.03.2012
comment
@ Николь Я не уверен, что полностью понимаю ваш вопрос, но я вообще не ссылаюсь на него напрямую. Ни один из моих кодов.   -  person Andrew Falanga    schedule 09.03.2012
comment
Я имел в виду текстовую ссылку, а не ссылку на код. В своем вопросе вы написали, что это то, что возвращается из среды выполнения: Где ты взял эту строку?   -  person Nicole Calinoiu    schedule 09.03.2012
comment
@Николь и др. все, кажется, что это, кажется, отвлекающий маневр. Я начинаю подозревать, что проблема как-то связана с разрядностью скомпилированной сборки (или, возможно, с тем, что делает JIT). Когда я запускаю из изолированной оболочки Visual Studio, окно памяти в моем отладчике показывает адреса в 32-битном формате, но при отладке приложения командной строки адреса равны 64. Я думаю, что проблема именно в этом. Каким-то образом область памяти, которая используется при использовании приложения командной строки, указывает на недопустимое место. Это больше не похоже на разрешения.   -  person Andrew Falanga    schedule 09.03.2012


Ответы (1)


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

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

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

person Andrew Falanga    schedule 09.03.2012
comment
Вы должны принять свой собственный ответ. Вопрос, конечно, тоже не закроется. - person Security Hound; 09.03.2012