Partager via


Comment l’application crée l’appareil WIA

Lorsqu’une application a l’intention d’utiliser un pilote de périphérique WIA, elle appelle la méthode IWiaDevMgr::CreateDevice (décrite dans la documentation Microsoft Windows SDK). Le service WIA appelle d’abord IStiUSD::LockDevice pour verrouiller le pilote WIA pour un accès mutuellement exclusif. Ensuite, le service WIA appelle IWiaMiniDrv::d rvInitializeWia pour créer l’arborescence d’éléments WIA initial. Enfin, le service WIA déverrouille le pilote de périphérique en appelant IStiUSD::UnLockDevice.

La méthode IWiaMiniDrv::d rvInitializeWia doit effectuer les tâches suivantes.

  1. Mettez en cache l’interface vers laquelle pointe le paramètre pStiDevice pour un verrouillage approprié de l’appareil. (Pour plus d’informations, consultez IWiaMiniDrv::d rvLockWiaDevice.)

  2. Créez l’arborescence d’éléments WIA initiale.

  3. Incrémentez le nombre actuel de connexions d’application. Ce nombre est utilisé pour informer le pilote si une application est toujours connectée. Il permet également de déterminer l’action appropriée à entreprendre dans IWiaMiniDrv::d rvUnInitializeWia.

Les éléments WIA doivent être nommés avec une signification logique. Microsoft a besoin des noms d’éléments suivants pour Windows XP et versions ultérieures.

Racine
Il s’agit du terme correspondant à l’élément racine de l’arborescence d’éléments WIA.

Plat
Il s’agit du terme pour un scanneur qui prend uniquement en charge un scanneur à plat ou un scanneur qui prend en charge un scanneur à plat avec un chargeur de documents.

Alimentation
Il s’agit du terme d’un scanneur qui ne prend en charge qu’un chargeur.

Le service WIA appelle la méthode IWiaMiniDrv::d rvInitializeWia en réponse à l’appel d’une application WIA à IWiaDevMgr::CreateDevice (décrit dans la documentation du SDK Windows). En conséquence, le service WIA appelle la méthode IWiaMiniDrv::d rvInitializeWia pour chaque nouvelle connexion cliente.

La méthode IWiaMiniDrv::d rvInitializeWia doit initialiser toutes les structures privées et créer l’arborescence d’éléments de pilote. L’arborescence d’éléments de pilote affiche la disposition de tous les éléments WIA pris en charge par ce périphérique WIA. Cette méthode est utilisée pour créer l’arborescence initiale uniquement, et non le contenu (propriétés WIA). Le service WIA remplit individuellement les propriétés WIA pour les éléments du pilote WIA en effectuant plusieurs appels à la méthode IWiaMiniDrv::d rvInitItemProperties .

Tous les appareils WIA ont un élément racine, qui est le parent de tous les éléments d’appareil WIA. Pour créer un élément de périphérique WIA, le pilote WIA doit appeler la fonction d’assistance du service WIA, wiasCreateDrvItem.

L’exemple suivant montre comment créer un élément racine d’appareil 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
  //

 }

Pour créer un élément enfant WIA, situé directement sous l’élément racine créé dans l’exemple précédent, utilisez un code similaire à ce qui suit.

Remarque **** Notez que la méthode IWiaDrvItem::AddItemToFolder est appelée pour ajouter l’élément enfant nouvellement créé à l’élément racine.

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;
 }

L’exemple suivant montre une implémentation de la méthode 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;
}