2012-03-08 3 views
0

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

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

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

[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 (see here). Например:

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, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089».

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

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

Пожалуйста, что-нибудь было бы очень полезно и с благодарностью.

Andy

+0

Не могли бы вы предоставить полные данные об исключительных деталях, возвращенные его методом ToString()? –

+0

@Nicole Насколько я могу судить, никакого исключения не генерируется. Visual Studio не нарушает никаких необработанных исключений, и мой код не завернут в блоки try/catch. Единственное, что я вижу, это то, что функция API установки возвращается с кодом ошибки 1784 (Invalid user buffer) и помещает детали устройства, которое предоставляет интерфейс в элемент пути.К сожалению, когда я увеличиваю размер буфера, чтобы захватить все это, я получаю бессмысленные данные. –

+0

Где вы находите ссылку на PartialTrustVisibilityLevel? –

ответ

0

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

Проблема на самом деле, похоже, имеет отношение к средам с 64 по 32 бит (по крайней мере, это моя теория на данном этапе).

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

+0

Вы должны принять свой собственный ответ. Разумеется, это тоже не закроет вопрос. –