Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1035 lines
24 KiB

/*****************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORPORATION, 2000
*
* TITLE: WiaProc.cpp
*
* VERSION: 1.0
*
* DATE: 2000/11/14
*
* DESCRIPTION: Manages Wia side of things
*
*****************************************************************************/
#include <stdafx.h>
#include <mmsystem.h>
#include "wiavideotest.h"
static struct
{
DWORD dwWiaDevMgrCookie;
DWORD dwSelectedDeviceCookie;
IUnknown *pCreateCallback;
IUnknown *pDeleteCallback;
IUnknown *pDisconnectedCallback;
IUnknown *pConnectedCallback;
IGlobalInterfaceTable *pGIT;
CRITICAL_SECTION CritSec;
} LOCAL_GVAR =
{
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
0,
FALSE,
NULL
};
/****************************Local Function Prototypes********************/
HRESULT ClearDeviceList();
HRESULT AddItemToList(IWiaPropertyStorage *pItem,
TCHAR *pszFriendlyName,
TCHAR *pszDeviceID);
WPARAM GetNumDevicesInList();
IWiaPropertyStorage* GetWiaStorage(WPARAM uiIndex);
HRESULT CreateWiaDevMgr(IWiaDevMgr **ppDevMgr);
HRESULT GetProperty(IWiaPropertyStorage *pPropStorage,
PROPID nPropID,
LONG *pnValue);
HRESULT GetProperty(IWiaPropertyStorage *pPropStorage,
PROPID nPropID,
TCHAR *pszBuffer,
UINT cbBuffer);
HRESULT SetProperty(IWiaPropertyStorage *pPropStorage,
PROPID nPropID,
const PROPVARIANT *ppv,
PROPID nNameFirst);
HRESULT AppUtil_ConvertToWideString(const TCHAR *pszStringToConvert,
WCHAR *pwszString,
UINT cchString);
HRESULT AppUtil_ConvertToTCHAR(const WCHAR *pwszStringToConvert,
TCHAR *pszString,
UINT cchString);
HRESULT CreateRootItem(IWiaDevMgr *pDevMgr,
const TCHAR *pszWiaDeviceID,
IWiaItem **ppRootItem);
HRESULT RegisterForEvents(IWiaDevMgr *pDevMgr);
///////////////////////////////
// WiaProc_Init
//
HRESULT WiaProc_Init()
{
HRESULT hr = S_OK;
IWiaDevMgr *pWiaDevMgr = NULL;
if (LOCAL_GVAR.dwWiaDevMgrCookie != 0)
{
return S_OK;
}
__try
{
if (!InitializeCriticalSectionAndSpinCount(&LOCAL_GVAR.CritSec, MINLONG))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_OUTOFMEMORY;
}
if (hr == S_OK)
{
hr = CreateWiaDevMgr(&pWiaDevMgr);
}
if (hr == S_OK)
{
hr = CoCreateInstance(CLSID_StdGlobalInterfaceTable,
NULL,
CLSCTX_INPROC_SERVER,
IID_IGlobalInterfaceTable,
(void **)&LOCAL_GVAR.pGIT);
}
if (hr == S_OK)
{
LOCAL_GVAR.pGIT->RegisterInterfaceInGlobal(pWiaDevMgr,
IID_IWiaDevMgr,
&LOCAL_GVAR.dwWiaDevMgrCookie);
}
if (hr == S_OK)
{
hr = RegisterForEvents(pWiaDevMgr);
}
if (hr == S_OK)
{
WiaProc_PopulateDeviceList();
}
if (pWiaDevMgr)
{
pWiaDevMgr->Release();
pWiaDevMgr = NULL;
}
return hr;
}
///////////////////////////////
// WiaProc_Term
//
HRESULT WiaProc_Term()
{
HRESULT hr = S_OK;
ClearDeviceList();
if (LOCAL_GVAR.dwSelectedDeviceCookie != 0)
{
LOCAL_GVAR.pGIT->RevokeInterfaceFromGlobal(LOCAL_GVAR.dwSelectedDeviceCookie);
LOCAL_GVAR.dwSelectedDeviceCookie = 0;
}
if (LOCAL_GVAR.dwWiaDevMgrCookie != 0)
{
LOCAL_GVAR.pGIT->RevokeInterfaceFromGlobal(LOCAL_GVAR.dwWiaDevMgrCookie);
LOCAL_GVAR.dwWiaDevMgrCookie = 0;
DeleteCriticalSection(&LOCAL_GVAR.CritSec);
}
if (LOCAL_GVAR.pCreateCallback)
{
LOCAL_GVAR.pCreateCallback->Release();
LOCAL_GVAR.pCreateCallback = NULL;
}
if (LOCAL_GVAR.pDeleteCallback)
{
LOCAL_GVAR.pDeleteCallback->Release();
LOCAL_GVAR.pDeleteCallback = NULL;
}
if (LOCAL_GVAR.pConnectedCallback)
{
LOCAL_GVAR.pConnectedCallback->Release();
LOCAL_GVAR.pConnectedCallback = NULL;
}
if (LOCAL_GVAR.pDisconnectedCallback)
{
LOCAL_GVAR.pDisconnectedCallback->Release();
LOCAL_GVAR.pDisconnectedCallback = NULL;
}
if (LOCAL_GVAR.pGIT)
{
LOCAL_GVAR.pGIT->Release();
LOCAL_GVAR.pGIT = NULL;
}
return hr;
}
///////////////////////////////
// WiaProc_CreateSelectedDevice
//
HRESULT WiaProc_CreateSelectedDevice(TCHAR *pszDeviceID,
UINT cchDeviceID)
{
HRESULT hr = S_OK;
WPARAM Index = 0;
TCHAR szDeviceID[MAX_PATH] = {0};
IWiaDevMgr *pWiaDevMgr = NULL;
if ((LOCAL_GVAR.dwWiaDevMgrCookie == 0) ||
(LOCAL_GVAR.pGIT == NULL))
{
return E_POINTER;
}
hr = LOCAL_GVAR.pGIT->GetInterfaceFromGlobal(LOCAL_GVAR.dwWiaDevMgrCookie,
IID_IWiaDevMgr,
(void**)&pWiaDevMgr);
if (pWiaDevMgr == NULL)
{
return E_POINTER;
}
LRESULT lResult = 0;
lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_GETCURSEL,
0,
0);
Index = (WPARAM) lResult;
if (Index == LB_ERR)
{
hr = E_FAIL;
}
if (hr == S_OK)
{
IWiaItem *pSelectedDevice = NULL;
LPARAM lParam = 0;
lParam = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_GETITEMDATA,
Index,
0);
IWiaPropertyStorage *pItem = (IWiaPropertyStorage*)lParam;
if (pItem)
{
hr = GetProperty(pItem, WIA_DIP_DEV_ID, szDeviceID,
sizeof(szDeviceID)/sizeof(TCHAR));
if (hr == S_OK)
{
hr = CreateRootItem(pWiaDevMgr,
szDeviceID,
&pSelectedDevice);
}
if (hr == S_OK)
{
hr = LOCAL_GVAR.pGIT->RegisterInterfaceInGlobal(pSelectedDevice,
IID_IWiaItem,
&LOCAL_GVAR.dwSelectedDeviceCookie);
}
if (pszDeviceID)
{
_tcsncpy(pszDeviceID, szDeviceID, cchDeviceID);
}
if (pSelectedDevice)
{
pSelectedDevice->Release();
pSelectedDevice = NULL;
}
}
}
if (pWiaDevMgr)
{
pWiaDevMgr->Release();
pWiaDevMgr = NULL;
}
return hr;
}
///////////////////////////////
// WiaProc_GetImageDirectory
//
HRESULT WiaProc_GetImageDirectory(TCHAR *pszImageDirectory,
UINT cchImageDirectory)
{
HRESULT hr = S_OK;
IWiaPropertyStorage *pStorage = NULL;
IWiaItem *pSelectedDevice = NULL;
if ((LOCAL_GVAR.dwSelectedDeviceCookie == 0) ||
(LOCAL_GVAR.pGIT == NULL) ||
(pszImageDirectory == NULL))
{
return E_POINTER;
}
if (hr == S_OK)
{
hr = LOCAL_GVAR.pGIT->GetInterfaceFromGlobal(LOCAL_GVAR.dwSelectedDeviceCookie,
IID_IWiaItem,
(void**)&pSelectedDevice);
}
if (pSelectedDevice == NULL)
{
hr = E_POINTER;
}
if (hr == S_OK)
{
hr = pSelectedDevice->QueryInterface(IID_IWiaPropertyStorage,
(void**) &pStorage);
}
if (hr == S_OK)
{
hr = GetProperty(pStorage, WIA_DPV_IMAGES_DIRECTORY, pszImageDirectory,
cchImageDirectory);
}
if (pStorage)
{
pStorage->Release();
pStorage = NULL;
}
if (pSelectedDevice)
{
pSelectedDevice->Release();
pSelectedDevice = NULL;
}
return hr;
}
///////////////////////////////
// WiaProc_DeviceTakePicture
//
HRESULT WiaProc_DeviceTakePicture()
{
HRESULT hr = S_OK;
IWiaItem *pSelectedDevice = NULL;
if ((LOCAL_GVAR.dwSelectedDeviceCookie == 0) ||
(LOCAL_GVAR.pGIT == NULL))
{
return E_POINTER;
}
if (hr == S_OK)
{
hr = LOCAL_GVAR.pGIT->GetInterfaceFromGlobal(LOCAL_GVAR.dwSelectedDeviceCookie,
IID_IWiaItem,
(void**)&pSelectedDevice);
}
if (pSelectedDevice == NULL)
{
hr = E_POINTER;
}
if (hr == S_OK)
{
IWiaItem *pUnused = NULL;
hr = pSelectedDevice->DeviceCommand(0,
&WIA_CMD_TAKE_PICTURE,
&pUnused);
if (pUnused)
{
pUnused->Release();
pUnused = NULL;
}
}
if (pSelectedDevice)
{
pSelectedDevice->Release();
pSelectedDevice = NULL;
}
return hr;
}
///////////////////////////////
// ClearDeviceList
//
HRESULT ClearDeviceList()
{
HRESULT hr = S_OK;
WPARAM NumDevices = 0;
NumDevices = GetNumDevicesInList();
//
// Free all the IWiaItem pointers we saved in our
// list box.
//
if (NumDevices != LB_ERR)
{
for (WPARAM i = 0; i < NumDevices; i++)
{
IWiaPropertyStorage *pItem = NULL;
pItem = GetWiaStorage(i);
if (pItem)
{
pItem->Release();
}
}
}
//
// Empty the list
//
SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_RESETCONTENT,
0,
0);
return hr;
}
///////////////////////////////
// WiaProc_PopulateDeviceList
//
HRESULT WiaProc_PopulateDeviceList()
{
HRESULT hr = S_OK;
IEnumWIA_DEV_INFO *pEnum = NULL;
IWiaDevMgr *pWiaDevMgr = NULL;
hr = LOCAL_GVAR.pGIT->GetInterfaceFromGlobal(LOCAL_GVAR.dwWiaDevMgrCookie,
IID_IWiaDevMgr,
(void**)&pWiaDevMgr);
if (pWiaDevMgr == NULL)
{
return E_POINTER;
}
//
// Clear out the device list if it has any items in it.
//
ClearDeviceList();
if (hr == S_OK)
{
hr = pWiaDevMgr->EnumDeviceInfo(0, &pEnum);
}
while (hr == S_OK)
{
IWiaItem *pRootItem = NULL;
IWiaPropertyStorage *pPropStorage = NULL;
TCHAR szFriendlyName[MAX_PATH + 1] = {0};
TCHAR szWiaDeviceID[MAX_PATH + 1] = {0};
//
// Get the next device in the enumeration.
//
hr = pEnum->Next(1, &pPropStorage, NULL);
//
// Get the device's Wia Device ID
//
if (hr == S_OK)
{
hr = GetProperty(pPropStorage, WIA_DIP_DEV_ID, szWiaDeviceID,
sizeof(szWiaDeviceID)/sizeof(TCHAR));
}
//
// Get the device's Wia Device Name
//
if (hr == S_OK)
{
hr = GetProperty(pPropStorage, WIA_DIP_DEV_NAME, szFriendlyName,
sizeof(szFriendlyName)/sizeof(TCHAR));
}
//
// We do not relesae the propstorage item because we store the pointer
// in our list until we shutdown the app.
//
if (hr == S_OK)
{
AddItemToList(pPropStorage, szFriendlyName, szWiaDeviceID);
}
}
SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_SETCURSEL,
0,
0);
return hr;
}
///////////////////////////////
// RegisterForEvents
//
HRESULT RegisterForEvents(IWiaDevMgr *pWiaDevMgr)
{
HRESULT hr = S_OK;
CWiaEvent *pWiaEvent = NULL;
IWiaEventCallback *pIWiaEvent = NULL;
if (pWiaDevMgr == NULL)
{
return E_POINTER;
}
//
// Register our callback events
//
if (hr == S_OK)
{
// create the WiaEvent
pWiaEvent = new CWiaEvent();
if (pWiaEvent == NULL)
{
hr = E_OUTOFMEMORY;
}
}
if (hr == S_OK)
{
hr = pWiaEvent->QueryInterface(IID_IWiaEventCallback,
(void**)&pIWiaEvent);
}
if (hr == S_OK)
{
hr = pWiaDevMgr->RegisterEventCallbackInterface(WIA_REGISTER_EVENT_CALLBACK,
NULL,
&WIA_EVENT_DEVICE_CONNECTED,
pIWiaEvent,
&LOCAL_GVAR.pConnectedCallback);
hr = pWiaDevMgr->RegisterEventCallbackInterface(WIA_REGISTER_EVENT_CALLBACK,
NULL,
&WIA_EVENT_DEVICE_DISCONNECTED,
pIWiaEvent,
&LOCAL_GVAR.pDisconnectedCallback);
hr = pWiaDevMgr->RegisterEventCallbackInterface(WIA_REGISTER_EVENT_CALLBACK,
NULL,
&WIA_EVENT_ITEM_CREATED,
pIWiaEvent,
&LOCAL_GVAR.pCreateCallback);
hr = pWiaDevMgr->RegisterEventCallbackInterface(WIA_REGISTER_EVENT_CALLBACK,
NULL,
&WIA_EVENT_ITEM_DELETED,
pIWiaEvent,
&LOCAL_GVAR.pDeleteCallback);
}
//
// We don't need to delete pWiaEvent since we are releasing it.
//
if (pIWiaEvent)
{
pIWiaEvent->Release();
pIWiaEvent = NULL;
}
return hr;
}
///////////////////////////////
// AddItemToList
//
HRESULT AddItemToList(IWiaPropertyStorage *pItem,
TCHAR *pszFriendlyName,
TCHAR *pszDeviceID)
{
HRESULT hr = S_OK;
WPARAM Index = 0;
if ((pItem == NULL) ||
(pszFriendlyName == NULL) ||
(pszDeviceID == NULL))
{
hr = E_POINTER;
return hr;
}
TCHAR szNewItem[MAX_PATH * 2] = {0};
_sntprintf(szNewItem, sizeof(szNewItem)/sizeof(TCHAR),
TEXT("%s (%s)"), pszFriendlyName, pszDeviceID);
LRESULT lResult = 0;
lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_ADDSTRING,
0,
(LPARAM) szNewItem);
Index = (WPARAM) lResult;
//
// pItem already has an AddRef on it.
//
SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_SETITEMDATA,
Index,
(LPARAM) pItem);
return hr;
}
///////////////////////////////
// GetNumDevicesInList
//
WPARAM GetNumDevicesInList()
{
LRESULT lResult = 0;
WPARAM NumItems = 0;
lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_GETCOUNT,
0,
0);
NumItems = (WPARAM) lResult;
return NumItems;
}
///////////////////////////////
// GetWiaStorage
//
IWiaPropertyStorage* GetWiaStorage(WPARAM Index)
{
LPARAM lParam = 0;
IWiaPropertyStorage *pItem = NULL;
lParam = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_GETITEMDATA,
Index,
0);
pItem = (IWiaPropertyStorage*)lParam;
return pItem;
}
///////////////////////////////
// CreateWiaDevMgr
//
HRESULT CreateWiaDevMgr(IWiaDevMgr **ppDevMgr)
{
HRESULT hr = S_OK;
if (ppDevMgr == NULL)
{
hr = E_POINTER;
return hr;
}
hr = CoCreateInstance(CLSID_WiaDevMgr,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IWiaDevMgr,
(void**) ppDevMgr);
return hr;
}
///////////////////////////////
// WiaProc_GetProperty
//
// Generic
//
HRESULT WiaProc_GetProperty(IWiaPropertyStorage *pPropStorage,
PROPID nPropID,
PROPVARIANT *pPropVar)
{
HRESULT hr = S_OK;
if ((pPropStorage == NULL) ||
(pPropVar == NULL))
{
hr = E_POINTER;
return hr;
}
PropVariantInit(pPropVar);
PROPSPEC ps = {0};
ps.ulKind = PRSPEC_PROPID;
ps.propid = nPropID;
if (SUCCEEDED(hr))
{
hr = pPropStorage->ReadMultiple(1, &ps, pPropVar);
}
return hr;
}
///////////////////////////////
// GetProperty
//
// For 'long' properties
//
HRESULT GetProperty(IWiaPropertyStorage *pPropStorage,
PROPID nPropID,
LONG *pnValue)
{
HRESULT hr = S_OK;
if ((pPropStorage == NULL) ||
(pnValue == NULL))
{
hr = E_POINTER;
return hr;
}
PROPVARIANT pvPropValue;
*pnValue = 0;
PropVariantInit(&pvPropValue);
hr = WiaProc_GetProperty(pPropStorage, nPropID, &pvPropValue);
if (hr == S_OK)
{
if ((pvPropValue.vt == VT_I4) ||
(pvPropValue.vt == VT_UI4))
{
*pnValue = pvPropValue.lVal;
}
}
PropVariantClear(&pvPropValue);
return hr;
}
///////////////////////////////
// GetProperty
//
// For 'string' properties
//
HRESULT GetProperty(IWiaPropertyStorage *pPropStorage,
PROPID nPropID,
TCHAR *pszBuffer,
UINT cbBuffer)
{
HRESULT hr = S_OK;
if ((pPropStorage == NULL) ||
(pszBuffer == NULL))
{
hr = E_POINTER;
return hr;
}
PROPVARIANT pvPropValue;
PropVariantInit(&pvPropValue);
hr = WiaProc_GetProperty(pPropStorage, nPropID, &pvPropValue);
if (hr == S_OK)
{
if ((pvPropValue.vt == VT_LPWSTR) ||
(pvPropValue.vt == VT_BSTR))
{
AppUtil_ConvertToTCHAR(pvPropValue.pwszVal, pszBuffer, cbBuffer);
}
}
//
// This frees the BSTR
//
PropVariantClear(&pvPropValue);
return hr;
}
///////////////////////////////
// CreateRootItem
//
HRESULT CreateRootItem(IWiaDevMgr *pDevMgr,
const TCHAR *pszWiaDeviceID,
IWiaItem **ppRootItem)
{
HRESULT hr = S_OK;
if ((pDevMgr == NULL) ||
(pszWiaDeviceID == NULL) ||
(ppRootItem == NULL))
{
hr = E_POINTER;
return hr;
}
if (hr == S_OK)
{
BOOL bRetry = TRUE;
BSTR bstrDeviceID = NULL;
WCHAR wszWiaDeviceID[MAX_PATH] = {0};
AppUtil_ConvertToWideString(pszWiaDeviceID, wszWiaDeviceID,
sizeof(wszWiaDeviceID) / sizeof(WCHAR));
bstrDeviceID = SysAllocString(wszWiaDeviceID);
for (UINT uiRetryCount = 0;
(uiRetryCount < 5) && (bRetry);
++uiRetryCount)
{
hr = pDevMgr->CreateDevice(bstrDeviceID,
ppRootItem);
if (SUCCEEDED(hr))
{
//
// Break out of loop
//
bRetry = FALSE;
}
else if (hr == WIA_ERROR_BUSY)
{
//
// Wait a little while before retrying
//
Sleep(200);
}
else
{
//
// All other errors are considered fatal
//
bRetry = FALSE;
}
}
if (bstrDeviceID)
{
SysFreeString(bstrDeviceID);
bstrDeviceID = NULL;
}
}
return hr;
}
///////////////////////////////
// SetProperty
//
// Generic
//
HRESULT SetProperty(IWiaPropertyStorage *pPropStorage,
PROPID nPropID,
const PROPVARIANT *ppv,
PROPID nNameFirst)
{
HRESULT hr = 0;
PROPSPEC ps = {0};
if ((pPropStorage == NULL) ||
(ppv == NULL))
{
return E_POINTER;
}
ps.ulKind = PRSPEC_PROPID;
ps.propid = nPropID;
if (hr == S_OK)
{
hr = pPropStorage->WriteMultiple(1, &ps, ppv, nNameFirst);
}
return hr;
}
///////////////////////////////
// WiaProc_SetLastSavedImage
//
// For 'string' properties
//
HRESULT WiaProc_SetLastSavedImage(BSTR bstrLastSavedImage)
{
HRESULT hr = S_OK;
IWiaItem *pSelectedDevice = NULL;
IWiaPropertyStorage *pStorage = NULL;
PROPVARIANT pv = {0};
if ((LOCAL_GVAR.dwSelectedDeviceCookie == 0) ||
(LOCAL_GVAR.pGIT == NULL))
{
return E_POINTER;
}
EnterCriticalSection(&LOCAL_GVAR.CritSec);
if (hr == S_OK)
{
hr = LOCAL_GVAR.pGIT->GetInterfaceFromGlobal(LOCAL_GVAR.dwSelectedDeviceCookie,
IID_IWiaItem,
(void**)&pSelectedDevice);
}
if (pSelectedDevice == NULL)
{
hr = E_POINTER;
}
if (hr == S_OK)
{
hr = pSelectedDevice->QueryInterface(IID_IWiaPropertyStorage,
(void**)&pStorage);
}
if (hr == S_OK)
{
PropVariantInit(&pv);
pv.vt = VT_BSTR;
pv.bstrVal = bstrLastSavedImage;
hr = SetProperty(pStorage, WIA_DPV_LAST_PICTURE_TAKEN, &pv, 2);
}
if (pStorage)
{
pStorage->Release();
pStorage = NULL;
}
if (pSelectedDevice)
{
pSelectedDevice->Release();
pSelectedDevice = NULL;
}
LeaveCriticalSection(&LOCAL_GVAR.CritSec);
return hr;
}
///////////////////////////////
// WiaProc_PopulateItemList
//
HRESULT WiaProc_PopulateItemList()
{
HRESULT hr = S_OK;
if (LOCAL_GVAR.dwSelectedDeviceCookie == 0)
{
return E_POINTER;
}
hr = ImageLst_PopulateWiaItemList(LOCAL_GVAR.pGIT,
LOCAL_GVAR.dwSelectedDeviceCookie);
return hr;
}
///////////////////////////////
// WiaProc_DestroySelectedDevice
//
HRESULT WiaProc_DestroySelectedDevice()
{
HRESULT hr = S_OK;
if (LOCAL_GVAR.dwSelectedDeviceCookie == 0)
{
return E_POINTER;
}
ImageLst_CancelLoadAndWait(5000);
if ((LOCAL_GVAR.dwSelectedDeviceCookie != 0) &&
(LOCAL_GVAR.pGIT != NULL))
{
LOCAL_GVAR.pGIT->RevokeInterfaceFromGlobal(LOCAL_GVAR.dwSelectedDeviceCookie);
LOCAL_GVAR.dwSelectedDeviceCookie = 0;
}
ImageLst_Clear();
return hr;
}