2012-03-08 3 views
0

저는 조금 더 이해 했으므로이 질문을 다시 말합니다. 원래 나는 너무 애매했다. 나는 "코드 액세스 보안 (Code Access Security)"이라는 이름의 라우트를 발견했다. 이것은 모든이를 읽는 노인의 모자이다, 나는 확신한다. 그러나 나에게.코드 액세스 보안이 PInvoking 설치 API 호출을 방지합니다.

응용 프로그램이 매우 크기 때문에 요약하면 두 개의 어셈블리가 있습니다. 하나는 프로그램 전체에서 사용되는 다양한 "도구"가있는 유틸리티 어셈블리입니다. 다른 하나는 기능을 발휘하기 위해 이러한 도구를 요구하고 있습니다.

유틸리티 어셈블리에는 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 Isolated Shell을 사용하는 GUI입니다. 다른 하나는 단순히 명령 행 프로그램입니다. GUI가 실행 중일 때 위 코드가 호출되고 예상대로 실행됩니다. 그러나 명령 줄 도구에서 (Setup API 함수에 대한 MSDN 참조에서 설명한대로) 발생한 문제에 대한 일부 데이터가 실패합니다. 이 시점에서 나는 반환 된 데이터의 일부만 복구 할 수 있습니다. 이것은 런타임에서 되돌아 오는 것입니다 : "stem.Security.PartialTrustVisibilityLevel, mscorlib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089".

저는 이것이 코드 액세스 보안과 관련이 있다는 것을 알고 있습니다. 그러나 어떻게 수정해야할지 모르겠습니다. 지금까지 발견 한 몇 가지 제안을 사용하여 어셈블리에이 특성을 시도했습니다. 즉, 코드의 네임 스페이스 블록 앞에 배치했습니다. [assembly : AllowPartiallyTrustedCallers]

그러나 이로 인해 다른 컴파일 문제가 발생합니다.

무엇이든 가장 도움이되고 크게 감사하겠습니다.

Andy

+0

ToString() 메서드에서 반환 된 전체 예외 정보를 제공해 주실 수 있습니까? –

+0

@ Nicole 내가 알 수있는 한 예외는 발생하지 않습니다. Visual Studio는 처리되지 않은 예외를 위반하지 않으며 내 코드는 try/catch 블록으로 래핑되지 않습니다. 내 유일한 징후는 Setup API 함수가 오류 코드 1784 (사용자 버퍼가 유효하지 않음)와 함께 반환되며 인터페이스를 경로 구성원에 노출시키는 장치의 세부 정보를 넣는 것입니다.불행히도 버퍼를 늘려 캡쳐하기에 버퍼의 크기를 늘리면 무의미한 데이터 만 있으면됩니다. –

+0

PartialTrustVisibilityLevel에 대한 참조는 어디에서 찾을 수 있습니까? –

답변

0

불행히도이 문제는 아직 해결되지 않았습니다. 그러나이 문제는 처음에 생각한 것처럼 코드 액세스 보안과는 아무런 관련이없는 것처럼 보입니다. 나는 붉은 청어를 던지고 있었다. Visual Studio에서 메모리 창을 사용하여 코드를 진행하면서 Setup API 함수를 호출하기 전에 메모리에 이러한 문자열이 있음을 알았습니다. 때로는 다른 내용으로 다른 메모리 블록을 얻을 수도 있습니다. 보통 붙여 넣은 내용으로 끝납니다.

실제로 문제는 64 비트 대 32 비트 환경과 관련이 있습니다 (적어도이 점은 제 이론입니다).

그러나이 질문은 실제 문제가 아니므로 답변을 닫는 데 "대답하고 있습니다."

+0

당신은 당신 자신의 대답을 수락해야합니다. 확실하게 질문을 닫지 않을 것입니다. –