다음을 통해 공유


애플리케이션이 WIA 디바이스를 만드는 방법

애플리케이션이 WIA 디바이스 드라이버를 사용하려는 경우 IWiaDevMgr::CreateDevice 메서드를 호출합니다(Microsoft Windows SDK 설명서에 설명됨). WIA 서비스는 먼저 IStiUSD::LockDevice 를 호출하여 상호 배타적인 액세스를 위해 WIA 드라이버를 잠급니다. 다음으로 WIA 서비스는 IWiaMiniDrv::d rvInitializeWia 를 호출하여 초기 WIA 항목 트리 구조를 만듭니다. 마지막으로 WIA 서비스는 IStiUSD::UnLockDevice를 호출하여 디바이스 드라이버의 잠금을 해제합니다.

IWiaMiniDrv::d rvInitializeWia 메서드는 다음 작업을 수행해야 합니다.

  1. 적절한 디바이스 잠금을 위해 pStiDevice 매개 변수가 가리키는 인터페이스를 캐시합니다. (자세한 내용은 IWiaMiniDrv::d rvLockWiaDevice)를 참조하세요.

  2. 초기 WIA 항목 트리 구조를 만듭니다.

  3. 현재 애플리케이션 연결 수를 증분합니다. 이 개수는 애플리케이션이 여전히 연결되어 있는지 여부를 드라이버에 알리는 데 사용됩니다. 또한 IWiaMiniDrv::d rvUnInitializeWia에서 수행할 적절한 작업을 결정하는 데 도움이 됩니다.

WIA 항목의 이름은 논리적 의미로 지정해야 합니다. Microsoft에는 Windows XP 이상에 대해 다음 항목 이름이 필요합니다.

루트
WIA 항목 트리의 루트 항목에 대한 용어입니다.

평판
이 용어는 플랫베드 스캐너만 지원하는 스캐너 또는 문서 피더가 있는 플랫베드 스캐너를 지원하는 스캐너의 용어입니다.

피더
이 용어는 피더만 지원하는 스캐너의 용어입니다.

WIA 서비스는 WIA 애플리케이션의 IWiaDevMgr::CreateDevice 호출에 대한 응답으로 IWiaMiniDrv::d rvInitializeWia 메서드를 호출합니다(Windows SDK 설명서에 설명됨). 그 결과 WIA 서비스는 각 새 클라이언트 연결에 대해 IWiaMiniDrv::d rvInitializeWia 메서드를 호출합니다.

IWiaMiniDrv::d rvInitializeWia 메서드는 모든 프라이빗 구조를 초기화하고 드라이버 항목 트리를 만들어야 합니다. 드라이버 항목 트리에는 이 WIA 디바이스에서 지원하는 모든 WIA 항목의 레이아웃이 표시됩니다. 이 메서드는 내용(WIA 속성)이 아닌 초기 트리 구조만 만드는 데 사용됩니다. WIA 서비스는 IWiaMiniDrv::d rvInitItemProperties 메서드를 여러 차례 호출하여 WIA 드라이버 항목에 대한 WIA 속성을 개별적으로 채웁습니다.

모든 WIA 디바이스에는 모든 WIA 디바이스 항목의 부모인 루트 항목이 있습니다. WIA 디바이스 항목을 만들려면 WIA 드라이버가 WIA 서비스 도우미 함수인 wiasCreateDrvItem을 호출해야 합니다.

다음 예제에서는 WIA 디바이스 루트 항목을 만드는 방법을 보여줍니다.

LONG lItemFlags = WiaItemTypeFolder|WiaItemTypeDevice|WiaItemTypeRoot;
IWiaDrvItem  *pIWiaDrvRootItem  = NULL;
HRESULT hr = 
    wiasCreateDrvItem(
                       lItemFlags, // item flags
                       bstrRootItemName, // item name ("Root")
                       bstrRootFullItemName, // item full name ("0000\Root")
                      (IWiaMiniDrv *)this, // this WIA driver object
                       sizeof(MINIDRIVERITEMCONTEXT), // size of context
                       NULL, // context
                       &pIWiaDrvRootItem // created ROOT item
                      );                 // (IWiaDrvItem interface)

if(S_OK == hr){

  //
  // ROOT item was created successfully
  //

 }

이전 예제에서 만든 루트 항목 바로 아래에 있는 WIA 자식 항목을 만들려면 다음과 유사한 코드를 사용합니다.

참고 **** 새로 만든 자식 항목을 루트 항목에 추가하려면 IWiaDrvItem::AddItemToFolder 메서드가 호출됩니다.

LONG lItemFlags = WiaItemTypeFile|WiaItemTypeDevice|WiaItemTypeImage;
PMINIDRIVERITEMCONTEXT pItemContext    = NULL;
IWiaDrvItem           *pIWiaDrvNewItem = NULL;
HRESULT hr = 
    wiasCreateDrvItem(
                       lItemFlags, // item flags
                       bstrItemName,  // item name ("Flatbed")
                       bstrFullItemName,  // item full name ("0000\Root\Flatbed")
                      (IWiaMiniDrv *)this,  // this WIA driver object
     sizeof(MINIDRIVERITEMCONTEXT), // size of context
                      (PBYTE)&pItemContext, // context
                      &pIWiaDrvNewItem // created child item
                     );                // (IWiaDrvItem interface)  

if(S_OK == hr){

  //
  // A New WIA driver item was created successfully
  //

  hr = pIWiaDrvNewItem->AddItemToFolder(pIWiaDrvRootItem); // add the new item to the ROOT
  if(S_OK == hr){

     //
     // successfully created and added a new WIA driver item to 
     // the WIA driver item tree.
    //

   }
   pNewItem->Release();
   pNewItem = NULL;
 }

다음 예제에서는 IWiaMiniDrv::d rvInitializeWia 메서드의 구현을 보여줍니다.

HRESULT _stdcall CWIADevice::drvInitializeWia(
  BYTE        *pWiasContext,
  LONG        lFlags,
  BSTR        bstrDeviceID,
  BSTR        bstrRootFullItemName,
  IUnknown    *pStiDevice,
  IUnknown    *pIUnknownOuter,
  IWiaDrvItem **ppIDrvItemRoot,
  IUnknown    **ppIUnknownInner,
  LONG        *plDevErrVal)
{
  //
  // If the caller did not pass in the correct parameters,
 // then fail the call with E_INVALIDARG.
  //

  if (!pWiasContext) {
      return E_INVALIDARG;
  }

  if (!plDevErrVal) {
      return E_INVALIDARG;
  }

  HRESULT hr = S_OK;

  *plDevErrVal = 0;
  *ppIDrvItemRoot = NULL;
  *ppIUnknownInner = NULL;

  if (m_pStiDevice == NULL) {

      //
      // save STI device interface for locking
      //

      m_pStiDevice = (IStiDevice *)pStiDevice;
  }

  //
  // build WIA item tree
  //

  LONG lItemFlags = WiaItemTypeFolder|WiaItemTypeDevice|WiaItemTypeRoot;

  IWiaDrvItem  *pIWiaDrvRootItem  = NULL;

  //
  // create the ROOT item of the WIA device.  This name should NOT be 
  // localized in different languages. "Root" is used by WIA drivers.
  //

  BSTR bstrRootItemName = SysAllocString(WIA_DEVICE_ROOT_NAME);
  if(!bstrRootItemName) {
      return E_OUTOFMEMORY;
  }

  hr = wiasCreateDrvItem(lItemFlags,  // item flags
               bstrRootItemName,  // item name ("Root")
               bstrRootFullItemName,  // item full name ("0000\Root")
                (IWiaMiniDrv *)this,  // this WIA driver object
      sizeof(MINIDRIVERITEMCONTEXT),  // size of context
                               NULL,  // context
                 &pIWiaDrvRootItem);  // created ROOT item
                                      // (IWiaDrvItem interface)
  if (S_OK == hr) {

    //
    // ROOT item was created successfully, save the newly created Root
    // item in the pointer given by the WIA service (ppIDrvItemRoot).
    //

      *ppIDrvItemRoot = pIWiaDrvRootItem;

    //
    // Create a child item  directly under the Root WIA item
    //

      lItemFlags = WiaItemTypeFile|WiaItemTypeDevice|WiaItemTypeImage;

      PMINIDRIVERITEMCONTEXT pItemContext    = NULL;
      IWiaDrvItem           *pIWiaDrvNewItem = NULL;

      //
      // create a name for the WIA child item.  "Flatbed" is used by 
      // WIA drivers that support a flatbed scanner.
      //

      BSTR bstrItemName = SysAllocString(WIA_DEVICE_FLATBED_NAME);

      if (bstrItemName) {

          WCHAR  wszFullItemName[MAX_PATH + 1] = {0};
          _snwprintf(wszFullItemName,(sizeof(wszFullItemName) / sizeof(WCHAR)) - 1,L"%ls\\%ls",
                   bstrRootFullItemName,bstrItemName);

        BSTR bstrFullItemName = SysAllocString(wszFullItemName);
        if (bstrFullItemName) {
          hr = wiasCreateDrvItem(lItemFlags,  // item flags
                               bstrItemName,  // item name ("Flatbed")
                             trFullItemName,  // item full name ("0000\Root\Flatbed")
                        (IWiaMiniDrv *)this,  // this WIA driver object
               sizeof(MINIDRIVERITEMCONTEXT), // size of context
                       (BYTE**)&pItemContext, // context
                        &pIWiaDrvNewItem);    // created child item
                                              // (IWiaDrvItem interface)

            if (S_OK == hr) {

                //
                // A New WIA driver item was created successfully
                //

                hr = pIWiaDrvNewItem->AddItemToFolder(pIWiaDrvRootItem); // add the new item to the ROOT
  if (S_OK == hr) {

                    //
                    // successfully created and added a new WIA 
                    // driver item to the WIA driver item tree.
                    //

                }

                //
                // The new item is no longer needed, because it has
                // been passed to the WIA service.
                //

                pIWiaDrvNewItem->Release();
                pIWiaDrvNewItem = NULL;
            }
            SysFreeString(bstrFullItemName);
            bstrFullItemName = NULL;
        } else {
            hr = E_OUTOFMEMORY;
        }
        SysFreeString(bstrItemName);
        bstrItemName = NULL;
    } else {
        hr = E_OUTOFMEMORY;
    }
  }

  //
  // increment application connection count
  //

  if(S_OK == hr){
    InterlockedIncrement(&m_lClientsConnected);
  }

  return hr;
}