Como o aplicativo cria o dispositivo WIA
Quando um aplicativo pretende usar um driver de dispositivo WIA, ele chama o método IWiaDevMgr::CreateDevice (descrito na documentação do SDK do Microsoft Windows). O serviço WIA primeiro chama IStiUSD::LockDevice para bloquear o driver WIA para acesso mutuamente exclusivo. Em seguida, o serviço WIA chama IWiaMiniDrv::d rvInitializeWia para criar a estrutura inicial da árvore de itens WIA. Por fim, o serviço WIA desbloqueia o driver do dispositivo chamando IStiUSD::UnLockDevice.
O método IWiaMiniDrv::d rvInitializeWia deve executar as tarefas a seguir.
Armazene em cache a interface para a qual o parâmetro pStiDevice aponta para o bloqueio de dispositivo adequado. (Para obter mais informações, consulte IWiaMiniDrv::d rvLockWiaDevice.)
Crie a estrutura inicial da árvore de itens WIA.
Incremente a contagem de conexões do aplicativo atual. Essa contagem é usada para informar ao driver se um aplicativo ainda está conectado. Ele também ajuda a determinar a ação adequada a ser tomada em IWiaMiniDrv::d rvUnInitializeWia.
Os itens WIA devem ser nomeados com algum significado lógico. A Microsoft requer os seguintes nomes de item para o Windows XP e posteriores.
Raiz
Esse é o termo para o item raiz da árvore de itens WIA.
Mesa
Esse é o termo para um scanner que dá suporte apenas a um scanner de flatbed ou a um scanner que dá suporte a um scanner de flatbed com um alimentador de documentos.
Alimentador
Esse é o termo para um verificador que dá suporte apenas a um alimentador.
O serviço WIA chama o método IWiaMiniDrv::d rvInitializeWia em resposta à chamada de um aplicativo WIA para IWiaDevMgr::CreateDevice (descrito na documentação do SDK do Windows). Uma consequência disso é que o serviço WIA chama o método IWiaMiniDrv::d rvInitializeWia para cada nova conexão de cliente.
O método IWiaMiniDrv::d rvInitializeWia deve inicializar quaisquer estruturas privadas e criar a árvore de itens do driver. A árvore de itens do driver mostra o layout de todos os itens WIA compatíveis com esse dispositivo WIA. Esse método é usado apenas para criar a estrutura de árvore inicial, não o conteúdo (propriedades wia). O serviço WIA preencherá individualmente as propriedades wia para os itens do driver WIA fazendo várias chamadas para o método IWiaMiniDrv::d rvInitItemProperties .
Todos os dispositivos WIA têm um item raiz, que é o pai de todos os itens do dispositivo WIA. Para criar um item de dispositivo WIA, o driver WIA deve chamar a função auxiliar de serviço WIA, wiasCreateDrvItem.
O exemplo a seguir mostra como criar um item raiz do dispositivo 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
//
}
Para criar um item filho wia, localizado diretamente sob o item raiz criado no exemplo anterior, use código semelhante ao seguinte.
Observação **** Observe que o método IWiaDrvItem::AddItemToFolder é chamado para adicionar o item filho recém-criado ao item raiz.
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;
}
O exemplo a seguir mostra uma implementação do método 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;
}