SQL Server 프로세스 외부에서 DLL 기반 COM 개체 실행

이 문서에서는 SQL Server 프로세스 외부에서 DLL 기반 COM 개체를 실행하는 방법을 설명합니다.

원래 제품 버전: SQL Server
원래 KB 번호: 198891

요약

Microsoft SQL Server OLE Automation 저장 프로시저 집합 또는 확장 저장 프로시저를 통해 COM(사용자 지정 구성 요소 개체 모델) 개체를 로드하고 실행하는 기능을 제공합니다. 기본적으로 DLL 기반 COM 개체는 프로세스 서버에서와 같이 로드됩니다. 즉, COM 개체는 SQL Server 프로세스 메모리 주소 공간 내에서 로드될 뿐만 아니라 이 메모리 주소 공간에 대한 모든 액세스 권한도 갖습니다. 따라서 SQL Server 프로세스 공간에 로드된 COM 개체는 DLL 파일과 동일한 규칙을 준수해야 합니다. COM 개체가 SQL Server 프로세스 내에서 메모리를 덮어쓰거나 리소스를 누출하여 불안정할 수 있습니다.

COM 개체가 SQL Server 프로세스의 견고성에 영향을 미칠 수 있다는 의심이 있는 경우 이 문서의 단계를 사용하여 SQL Server 프로세스 공간 외부에서 COM 개체를 인스턴스화할 수 있습니다. 운영 체제에 위치 투명성의 DCOM(분산 구성 요소 개체 모델) 사양을 구현하면 SQL Server 프로세스 공간 외부에서 DLL 기반 COM 개체를 실행할 수 있습니다.

기본 애플리케이션의 주소 공간 외부에서 DLL 기반 COM 개체를 실행하는 프로세스를 원격이라고 합니다. 원격 작업을 수행하려면 다른 실행 파일이 SQL Server 실행 파일 대신 서로게이트 프로세스여야 합니다. DCOM 서비스 제어 관리자(rpcss.exe)에서 사용하는 기본 실행 파일의 이름은 dllhost.exe. DCOM 지원 구조는 dllhost.exe 파일을 사용하여 DLL을 프로세스 공간에 로드한 다음 프록시/스텁 쌍을 사용하여 요청된 인터페이스를 클라이언트로 투명하게 마샬링합니다. 이 경우 SQL Server. 이 실행 파일은 여러 인터페이스/메서드 요청을 동시에 수락할 수 있습니다. 인터페이스 사용이 완료되면 DCOM SCM(서비스 제어 관리자)은 dllhost.exe 파일의 정리 및 언로드를 관리합니다. COM 개체는 인스턴스화 사이에 상태 정보를 유지하지 않아야 합니다.

다음 단계는 SQL Server 프로세스 공간에서 sp_OACreate 만들어지는 DLL 기반 COM 개체에 적용할 수 있습니다.

추가 정보

COM 개체를 프로세스에서 인스턴스화하는 데 사용할 수 있는 두 가지 기본 메서드에 대한 정보는 다음과 같습니다.

COM 클라이언트가 개체의 원격을 요청합니다.

COM 개체를 호출하는 방법을 변경하여 SQL Server 주소 공간 외부에서 개체를 만들 것을 요청할 수 있습니다.

  • COM 개체가 프로시저를 사용하여 sp_OACreate 로드되는 경우 기본적으로 프로세스에서 로드됩니다. 그러나 이 프로시저에는 개체를 만들 위치의 컨텍스트를 나타내는 데 사용할 수 있는 선택적 세 번째 매개 변수가 있습니다. 이 매개 변수를 지정하지 않으면 기본 설정인 5(5)가 사용됩니다. 즉, 프로세스 내부 또는 외부에서 개체를 실행합니다. 매개 변수를 4(4)로 변경해야 합니다. 이는 이 구성 요소가 로컬 실행 파일로 실행될 것임을 DCOM에 나타냅니다. 다음 예제와 유사한 구문을 사용하여 저장 프로시저를 사용하여 COM 개체를 프로세스에서 실행하도록 DCOM에 sp_OACreate 명시적으로 알릴 수 있습니다.

    DECLARE @object int
    DECLARE @hr int
    EXEC @hr = sp_OACreate 'SQLOLE.SQLServer', @object OUT, 4
    
  • 확장 저장 프로시저 내에서 COM 개체를 만든 경우 또는 CoCreateInstanceExCoCreateInstance 세 번째 매개 변수를 로 CLSCTX_LOCAL_SERVER변경할 수 있습니다. 이는 를 사용하는 다음 코드 샘플에 나와 있습니다 CoCreateInstance.

    HRESULT hr = CoCreateInstance(CLSID_Test, NULL, CLSCTX_LOCAL_SERVER,
    IID_IUnknown, (void**)&piunknown);
    

개체의 강제로 원격으로 레지스트리 수정

COM 클라이언트를 수정하여 개체를 프로세스에서 만들도록 요청할 수 없는 경우 개체를 강제로 만들려면 두 가지 메서드가 존재합니다.

  • Visual C++와 함께 제공되는 OLE/COM 개체 뷰어(oleview.exe)를 사용하고 모든 개체 아래의 OLEComponent.Object 형식으로 ProgID를 찾습니다. COM 개체를 선택한 다음 개체 메뉴에서 플래그를 선택합니다 CoCreateInstance . 만 CLSCTX_LOCAL_SERVER 선택되어 있는지 확인합니다. 다음으로 , 구현Inproc 서버 탭에서서로게이트 프로세스 사용을 선택하고 사용자 지정 서로게이트에 대한 경로를 비워 두면 dllhost.exe 파일을 로드하고 COM DLL을 프로세스 공간 내에 가져올 수 있습니다.

  • 다음 단계를 사용하여 레지스트리를 수동으로 업데이트합니다.

    경고

    레지스트리 편집기 또는 다른 방법을 사용하여 레지스트리를 잘못 수정하는 경우 심각한 문제가 발생할 수 있습니다. 이러한 문제가 발생하면 운영 체제를 다시 설치해야 할 수도 있습니다. Microsoft는 이러한 문제의 해결을 보증하지 않습니다. 레지스트리를 수정하는 데 따르는 위험은 사용자가 부담해야 합니다.

    1. COM 개체의 CLSID(클래스 식별자)를 가져옵니다. CLSID는 128비트 숫자이며 이 COM 개체가 포함된 구성 요소, 모듈 또는 파일을 고유하게 식별하는 데 사용되는 GUID(Globally Unique Identifier)로 간주됩니다. OLE Automation 저장 프로시저를 사용하여 COM 개체를 만들 때 저장 프로시저에 대한 첫 번째 매개 변수는 프로그래밍 방식 식별자이거나 OLE 개체의 ProgID를 사용하여 CLSID를 파생합니다. 이 문자열은 OLE 개체의 클래스를 설명하고 다음과 같은 형식을 줍니다.

      OLEComponent.Object
      
    2. 프로그래밍 식별자를 사용하여 COM 개체의 클래스 식별자를 찾을 수 있습니다.

      레지스트리 편집기(regedit.exe)를 열고 키 아래에서 HKEY_CLASSES_ROOT 메서드를 Find 사용하여 OLEComponent.Object의 <이름으로 키를 찾습니다>. 다른 수준에서 찾을 수 있지만 바로 아래 HKEY_CLASSES_ROOT의 수준에 있어야 합니다. 키를 찾은 후 키 이름의 폴더를 확장하면 CLSID라는 하위 키가 표시됩니다. 해당 폴더를 선택하여 해당 키 내의 값을 확인합니다. 화면 오른쪽에는 Default라는 제목이 있습니다. 해당 키의 데이터는 다음 형식이어야 합니다.

      {59F929A0-74D8-11D2-8CBC-08005A390B09}

      이 값을 기록하거나 메모장에 복사합니다. 대괄호를 포함합니다.

    3. 키 아래를 HKEY_CLASSES_ROOT\CLSID 탐색하고 이 GUID 번호가 있는 하위 키를 찾습니다. 키를 강조 표시 HKEY_CLASSES_ROOT\CLSID 한 후 레지스트리 편집기 찾기 함수(편집 메뉴 아래)를 사용하고 GUID를 찾기 대화 상자에 붙여넣을 수 있습니다. COM DLL 파일의 위치를 가리키는 이 키 아래의 InprocServer32 하위 키를 검사하여 적절한 인터페이스를 찾았는지 확인합니다. TypeLib 키가 있는 경우 이 GUID 값을 검사. 이는 1단계에서 설명한 것과 달라야 합니다. 그렇지 않으면 COM 개체의 GUID가 아닌 TypeLib GUID가 있습니다. ProgID 하위 키의 값은 입니다 OLEComponent.Object.1. 끝에 있는 것은 이 샘플에만 해당하며 버전 관리 정보에 사용됩니다.

    4. GUID의 InprocServer32 하위 키 아래에 있는 동안 값이 ThreadingModel 존재하고 둘 다 또는 무료로 설정되어 있는지 확인하여 마샬링이 COM 개체의 스레딩 모델을 이해하여 SQL Server 프로세스 공간에서 COM을 실행할 수 있도록 합니다. 값이 없거나 Apartment로 ThreadingModel 설정된 경우 COM 개체 인스턴스화가 일치하지 않을 수 있습니다.

      참고

      값을 추가하는 ThreadingModel 경우 구현하기 전에 COM 개체를 테스트해야 합니다.

    5. 키 아래의 GUID 번호/하위 키를 강조 표시 HKEY_CLASSES_ROOT\CLSID 합니다. 편집 메뉴에서 새로 만들기를 선택한 다음 문자열 값을 선택합니다. 이름 열 아래에 AppID를 입력합니다.

    6. Enter 키를 누른 다음, 1단계에서 적어두는 클래스 식별자 또는 GUID 번호를 값으로 삽입합니다. GUID는 다음 예제와 같이 중괄호 안에 있어야 합니다.

      {59F929A0-74D8-11D2-8CBC-08005A390B09}
      

      애플리케이션 식별자 AppID는 DCOM에서 DLL을 실행 파일과 연결하는 데 사용됩니다.

    7. 아래에 HKEY_CLASSES_ROOT\AppID 새 하위 키를 추가하고 이전 단계에서 삽입한 대로 대괄호를 사용하여 해당 이름을 동일한 클래스 식별자 또는 GUID 번호로 설정합니다.

    8. GUID 이름을 강조 표시합니다. 편집 메뉴에서 새로 만들기를 선택한 다음 문자열 값을 선택합니다. 이름 열 아래에 dllSurrogate를 입력합니다.

      이 값에 대해 데이터 열을 비워 둡니다. 데이터 열이 비어 있으므로 DCOM에 기본 실행 파일을 실행하고 dllhost.exe프로세스 공간 내에 COM 개체를 로드하도록 알릴 수 있습니다.

    9. 레지스트리 편집기를 닫습니다. 시작을 클릭한 다음 실행을 선택합니다. 실행 대화 상자에서 DCOMCNFG를 입력합니다.

      ENTER 키를 눌러 분산 COM 구성 속성 대화 상자를 엽니다. 기본 속성 탭을 클릭하고 이 컴퓨터에서 분산 COM 사용이 선택되어 있는지 확인합니다. 그렇지 않은 경우 선택한 다음 적용을 선택합니다.

    10. SQL Server 실행 중인 Windows NT 사용자 계정에 이 개체의 레지스트리 키에 대한 모든 권한이 있는지 확인합니다. 권한이 충분하지 않거나 레지스트리 키가 잘못 입력된 경우 COM 개체를 만들 때 다음 오류가 발생할 수 있습니다.

      OLE 자동화 오류 정보
      HRESULT: 0x80040154
      원본: ODSOLE 확장 프로시저
      설명: 등록되지 않은 클래스

      OLE 자동화 오류 정보
      HRESULT: 0x80070005
      원본: ODSOLE 확장 프로시저
      설명: 액세스가 거부되었습니다.

      OLE 자동화 오류 정보
      HRESULT: 0x80080005
      원본: ODSOLE 확장 프로시저
      설명: 서버 실행 실패

    11. dllhost.exe 파일을 실행하고 COM 개체를 프로세스 공간에 로드하는지 테스트하고 확인합니다. 이렇게 하려면 Windows NT 리소스 키트가 SQL Server 실행 중인 Windows NT 컴퓨터에 있어야 합니다. 명령 프롬프트를 열고 명령 프롬프트에서 모든 프로세스 및 관련 프로세스 식별자 또는 PID(프로세스 식별자)를 표시하는 tlist.exe 파일을 실행합니다. 이 실행되고 해당 호출이 실행된 후 Transact-SQL 스크립트 sp_OACreate 에서 스크립트가 종료되기 전에 다음을 사용하여 스크립트 완료를 추가로 20초 지연합니다.

      WAITFOR DELAY '000:00:20'
      

      스크립트를 실행하고 명령 프롬프트로 즉시 이동하여 tlist.exe 파일을 실행합니다. dllhost.exe PID를 확인합니다. tlist.exe 다시 실행하고 PID를 매개 변수로 전달합니다. 이는 dllhost.exe 프로세스 공간 내에 로드되는 DLL을 보여줍니다. DLL 기반 COM 개체는 이 프로세스 내에서 실행 중으로 나열되어야 합니다. 스크립트가 반환된 후 tlist.exe 실행하면 dllhost.exe 프로세스가 더 이상 실행되고 있지 않음이 다시 표시됩니다.

      다음 샘플 출력에서 ADODB입니다. 연결 개체는 SQL Server 프로세스 공간 외부에서 만들어집니다. COM 개체가 dllhost.exe 프로세스 공간에 있는 동안tlist.exe사용하는 이 스냅샷 수행되었습니다. COM 개체를 포함하는 모듈인 msado15.dll모듈이 로드됩니다.

      C:\>tlist dllhost
      275 dllhost.exe
      CWD: C:\NT40\system32\
      CmdLine: C:\NT40\System32\dllhost.exe {00000514-0000-0010-8000-00AA006D2EA4}
      -Embedding
      VirtualSize: 19180 KB PeakVirtualSize: 19180 KB WorkingSetSize: 1780 KB
      PeakWorkingSetSize: 1780 KB
      NumberOfThreads: 3
      278 Win32StartAddr:0x01001920 LastErr:0x00000000 State:Waiting
      215 Win32StartAddr:0x00001b5e LastErr:0x00000000 State:Waiting
      253 Win32StartAddr:0x00001b60 LastErr:0x000000cb State:Waiting
      4.0.1381.105 shp 0x01000000 dllhost.exe
      4.0.1381.130 shp 0x77f60000 ntdll.dll
      4.0.1381.121 shp 0x77dc0000 ADVAPI32.dll
      4.0.1381.133 shp 0x77f00000 KERNEL32.dll
      4.0.1381.133 shp 0x77e70000 USER32.dll
      4.0.1381.115 shp 0x77ed0000 GDI32.dll
      4.0.1381.131 shp 0x77e10000 RPCRT4.dll
      4.0.1381.117 shp 0x77b20000 ole32.dll
        6.0.8267.0 shp 0x78000000 MSVCRT.dll
                       0x1f310000 msado15.dll
       2.30.4265.1 shp 0x766f0000 OLEAUT32.dll
       4.0.1381.72 shp 0x77bf0000 rpcltc1.dll
      

참조

OLE 자동화 저장 프로시저(Transact-SQL)