2009年9月18日 星期五

[WIA]Item Tree





***************************************************************************

1. Item Tree 架構, 如圖1
1.1 有一個Root item 及一個 Flatbed or Feeder item(Flatbed 和 Feeder 共用一個Item)
1.2 每一個item 中有許多WINDOWS 定義好的property (DIP_xxx_xxx, DPA_xxx_xxx, ...)
1.3 0000\xxx 或 0001\xxx 為 WINDOWS 決定的。


2. 可以使用wiatest.exe 看到Item Tree 中的每個Item 及其所有的property, 如圖2
3. Item Tree 由AP, Wia service , mini driver 各擁有一份。wia service 會自行同步這三份。



圖1:



圖2:







建立時機點:


//
//建立Item 的架構
//
IWiaMiniDrv::drvInitializeWia(...)
{
.
.
//建立Root Item
IWiaDrvItem *pIWiaDrvRootItem = NULL;
wiasCreateDrvItem(... , &pIWiaDrvRootItem)
.
.
//建立Flatbed Item
IWiaDrvItem *pIWiaDrvNewItem = NULL;
wiasCreateDrvItem(... , &pIWiaDrvNewItem)

//attach Flatbed Item to Root Item
pIWiaDrvNewItem->AddItemToFolder(pIWiaDrvRootItem);
.
.
.

}


//
//建立每個Item 中的property 及其初始值, 一個Item 會進來一次(Root 一次, Flatbed 一次)
//
IWiaMiniDrv::drvInitItemProperties(...)
{
//判斷進來的是Root 或 Flatbed 寫入相對映的property(使用wiasXXX 的function)
//ex:
//wiasSetItemPropNames();
//wiasWriteMultiple();
//wiasSetItemPropAttribs();
//.
//.
.
.
.
}




p.s.
在Vista/7 下,其Item Tree架構差不多,如下:

1. Item Tree 架構,
1.1 有一個Root item 及一個 Flatbed or Feeder item or 其它的 Item(Flatbed 和 Feeder 各自有其Item)
1.2 每一個item 中有許多WINDOWS 定義好的property (DIP_xxx_xxx, DPA_xxx_xxx, ...), 但有些property 的名稱改變,如

(DPA_xxx_xx -> DPS_xxx_xxx), 而且可能會有所移動(ex: 從 Root -> Flatbed)

2. 可以使用wiainfo2.exe 看到Item Tree 中的每個Item 及其所有的property
3. Item Tree 由AP, Wia service , mini driver 各擁有一份。wia service 會自行同步這三份。

2009年9月10日 星期四

[WIA] the order of Release

CWiaDevice::CWiaDevice

HRESULT CWIADriver::drvInitializeWia(__inout BYTE *pWiasContext,
LONG lFlags,
__in BSTR bstrDeviceID,
__in BSTR bstrRootFullItemName,
__in IUnknown *pStiDevice,
__in IUnknown *pIUnknownOuter,
__out IWiaDrvItem **ppIDrvItemRoot,
__out IUnknown **ppIUnknownInner,
__out LONG *plDevErrVal)





HRESULT CWIADriver::drvUnInitializeWia(__inout BYTE *pWiasContext)

CWiaDevice::~CWiaDevice


//
Wia UI 出現時一定會呼叫drvInitializeWia,
但drvInitializeWia 和 drvUnInitializeWia 並不一定會成對出現。所以有可能呼叫多次的drvInitializeWia, 而只呼叫一次的drvUnInitializeWia.

drvInitializeWia: 只在第一次呼叫時初始化所需資源。之後只要回傳ok.
drvUnInitializeWia:
CWiaDevice::~CWiaDevice:
1. 釋放資源
2. CancelIO(SetNotificationHandle(NULL))
3. Release handle(CreateFile 建立用來控制device)





定義:
******************************************************************************
一個 Hanlde週期(Handle life cycle):
1. device 插入到拔出
2. 開機到關機


WIA UI:
default WIA AP(offered by WINDOWS)


class CWIADriver : public INonDelegatingUnknown, // NonDelegatingUnknown
public IStiUSD, // STI USD interface
public IWiaMiniDrv // WIA Minidriver interface
CWIADriver :
component 內的一個 class 用來提供 IStiUSD, IWiaMiniDrv兩個 Interface


說明:
******************************************************************************
IStiUSD::Initialize():
週期時機:週期開始
呼叫時機:一偵測到Device 的存在--安裝完Driver或插入Device(device 插入或開機)
應作動作:初始化 Handle(created by CreateFile)

IWiaMiniDrv::drvInitializeWia:
週期時機:週期內
呼叫時機:建立連線(IWiaDevMgr::CreateDevice), ex: 打開WIA UI
應作動作:
1. 在第一次進來,保存傳入的IStiDevice 指標(IStiDevice 為 IStiUSD的使用者介面),
下次再進來時便以此指標是否已有值來判斷是否為一個週期的開始,
指標內有值便為週期內,否則為一新的週期。
2. 增加連線計數(進來一次加一)

IWiaMiniDrv::drvUnInitializeWia:
週期時機:週期內
呼叫時機:結束連線
應作動作:
1. 減少連線計數(進來一次減一)
如果連線計數為0 時釋放掉一些週期內可以釋放的large memory


CWiaDevice::~CWiaDevice:
週期時機:週期結束
呼叫時機:一偵測到Device 的'不'存在(device 拔出或關機)
應作動作:
1. 釋放 Handle(created by CreateFile),
如果有支援push mode 得先CancelIO(by SetNotificationHandle(NULL))


WDK 中說明:
1. 並不保證每一次的IWiaMiniDrv::drvInitializeWia 和 IWiaMiniDrv::drvUnInitializeWia 會成對出現。
2. 週期內,不保證每一次(除了第一次)都會先呼叫IWiaMiniDrv::drvInitializeWia
再呼叫其它 IWiaMiniDrv的function.