|
|
/*++
Copyright (C) 1999- Microsoft Corporation
Module Name:
minidrv.h
Abstract:
This module declares CWiaMiniDriver class
Author:
William Hsieh (williamh) created
Revision History:
--*/
#ifndef MINIDRV__H_
#define MINIDRV__H_
DECLARE_INTERFACE(INonDelegatingUnknown) { STDMETHOD(NonDelegatingQueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppv) PURE; STDMETHOD_(ULONG,NonDelegatingAddRef) (THIS) PURE; STDMETHOD_(ULONG,NonDelegatingRelease) (THIS) PURE; };
//
// General purpose GUIDs
//
DEFINE_GUID(GUID_NULL, 0,0,0,0,0,0,0,0,0,0,0);
DEFINE_GUID(FMT_NOTHING, 0x81a566e7,0x8620,0x4fba,0xbc,0x8e,0xb2,0x7c,0x17,0xad,0x9e,0xfd);
//
// This is the HRESULT code we used to report that a device error has occurred
//
const HRESULT HRESULT_DEVICE_ERROR = HRESULT_FROM_WIN32(ERROR_GEN_FAILURE); const HRESULT HRESULT_DEVICE_NOT_RESPONDING = HRESULT_FROM_WIN32(ERROR_TIMEOUT);
//
// Device error codes
//
enum { DEVERR_OK = 0, DEVERR_UNKNOWN }; #define DEVERR_MIN DEVERR_OK
#define DEVERR_MAX DEVERR_UNKNOWN
//
// Session ID to use
//
const ULONG WIA_SESSION_ID = 1;
//
// Handy constants for common item types
//
const ULONG ITEMTYPE_FILE = WiaItemTypeFile; const ULONG ITEMTYPE_IMAGE = WiaItemTypeFile | WiaItemTypeImage; const ULONG ITEMTYPE_AUDIO = WiaItemTypeFile | WiaItemTypeAudio; const ULONG ITEMTYPE_VIDEO = WiaItemTypeFile | WiaItemTypeVideo; const ULONG ITEMTYPE_FOLDER = WiaItemTypeFolder; const ULONG ITEMTYPE_BURST = WiaItemTypeFolder | WiaItemTypeBurst; const ULONG ITEMTYPE_HPAN = WiaItemTypeFolder | WiaItemTypeHPanorama; const ULONG ITEMTYPE_VPAN = WiaItemTypeFolder | WiaItemTypeVPanorama;
//
// Maximum number of vendor-defined events supported
//
const ULONG MAX_VENDOR_EVENTS = 128;
//
// Structure which holds everything needed for each format type.
//
typedef struct _FORMAT_INFO { LPGUID FormatGuid; // WIA format GUID
PWSTR FormatString; // item name in a printf-style format string
LONG ItemType; // WIA item type
PWSTR ExtString; // file name extension
} FORMAT_INFO, *PFORMAT_INFO;
//
// Structure for holding information about each property.
//
typedef struct _PROP_INFO { PROPID PropId; // WIA property id
LPOLESTR PropName; // WIA property name
} PROP_INFO, *PPROP_INFO;
//
// structure for holding information about vendor events
class CVendorEventInfo { public: GUID *pGuid; // WIA GUID for event
BSTR EventName; // may be NULL if vendor did not provide event name in INF file
CVendorEventInfo() : pGuid(NULL), EventName(NULL) {}; ~CVendorEventInfo() { if (pGuid) delete pGuid; SysFreeString(EventName); } };
//
// Driver item context
//
typedef struct tagDrvItemContext { CPtpObjectInfo *pObjectInfo; // pointer to the PTP ObjectInfo structure
ULONG NumFormatInfos; // number of format infos stored
WIA_FORMAT_INFO *pFormatInfos; // supported formats array
ULONG ThumbSize; // thumnail image size in bytes
BYTE *pThumb; // thumnail bits
}DRVITEM_CONTEXT, *PDRVITEM_CONTEXT;
#ifdef DEADCODE
//
// Tree node. These are used to temporarily hold the items between reading
// all of the PTP objects and creating the PTP item tree.
//
typedef struct _OBJECT_TREE_NODE { CPtpObjectInfo *pObjectInfo; struct _OBJECT_TREE_NODE *pNext; struct _OBJECT_TREE_NODE *pFirstChild; } OBJECT_TREE_NODE, *POBJECT_TREE_NODE; #endif // DEADCODE
//
// Our minidriver clsid.
//
#if defined( _WIN32 ) && !defined( _NO_COM)
// b5ee90b0-d5c5-11d2-82d5-00c04f8ec183
DEFINE_GUID(CLSID_PTPWiaMiniDriver, 0xb5ee90b0,0xd5c5,0x11d2,0x82,0xd5,0x00,0xc0,0x4f,0x8e,0xc1,0x83); #endif
class CWiaMiniDriver : public INonDelegatingUnknown, public IStiUSD, public IWiaMiniDrv { public: CWiaMiniDriver(LPUNKNOWN punkOuter); ~CWiaMiniDriver(); //
// INonDelegatingUnknown interface
//
STDMETHODIMP_(ULONG) NonDelegatingAddRef(); STDMETHODIMP_(ULONG) NonDelegatingRelease(); STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, LPVOID * ppvObj);
//
// IUnknown interface
//
STDMETHODIMP_(ULONG) AddRef( void); STDMETHODIMP_(ULONG) Release( void); STDMETHODIMP QueryInterface( REFIID riid, LPVOID * ppvObj);
//
// IStiUSD interface
//
STDMETHODIMP Initialize(PSTIDEVICECONTROL pHelDcb, DWORD dwStiVersion, HKEY hParametersKey); STDMETHODIMP GetCapabilities (PSTI_USD_CAPS pDevCaps); STDMETHODIMP GetStatus (PSTI_DEVICE_STATUS pDevStatus); STDMETHODIMP DeviceReset(); STDMETHODIMP Diagnostic(LPDIAG pBuffer); STDMETHODIMP SetNotificationHandle(HANDLE hEvent); STDMETHODIMP GetNotificationData(LPSTINOTIFY lpNotify); STDMETHODIMP Escape(STI_RAW_CONTROL_CODE EscapeFunction, LPVOID lpInData, DWORD cbInDataSize, LPVOID pOutData, DWORD dwOutDataSize, LPDWORD pdwActualDataSize); STDMETHODIMP GetLastError (LPDWORD pdwLastDeviceError); STDMETHODIMP GetLastErrorInfo (STI_ERROR_INFO *pLastErrorInfo); STDMETHODIMP LockDevice(); STDMETHODIMP UnLockDevice(); STDMETHODIMP RawReadData(LPVOID lpBuffer, LPDWORD lpdwNumberOfBytes, LPOVERLAPPED lpOverlapped); STDMETHODIMP RawWriteData(LPVOID lpBuffer, DWORD nNumberOfBytes, LPOVERLAPPED lpOverlapped); STDMETHODIMP RawReadCommand(LPVOID lpBuffer, LPDWORD lpdwNumberOfBytes, LPOVERLAPPED lpOverlapped); STDMETHODIMP RawWriteCommand(LPVOID lpBuffer, DWORD nNumberOfBytes, LPOVERLAPPED lpOverlapped);
//
// IWiaMiniDrv interface
//
STDMETHODIMP drvInitializeWia(BYTE *pWiasContext, LONG lFlags, BSTR bstrDeviceID, BSTR bstrRootFullItemName, IUnknown *pStiDevice, IUnknown *pIUnknownOuter, IWiaDrvItem **ppIDrvItemRoot, IUnknown **ppIUnknownInner, LONG *plDevErrVal); STDMETHODIMP drvUnInitializeWia(BYTE* pWiasContext); STDMETHODIMP drvDeviceCommand(BYTE *pWiasContext, LONG lFlags, const GUID *pGUIDCommand, IWiaDrvItem **ppMiniDrvItem, LONG *plDevErrVal); STDMETHODIMP drvDeleteItem(BYTE *pWiasContext, LONG lFlags, LONG *plDevErrVal); STDMETHODIMP drvGetCapabilities(BYTE *pWiasContext, LONG lFlags, LONG *pCelt, WIA_DEV_CAP_DRV **ppCapabilities, LONG *plDevErrVal); STDMETHODIMP drvInitItemProperties(BYTE *pWiasContext, LONG lFlags, LONG *plDevErrVal); STDMETHODIMP drvLockWiaDevice(BYTE *pWiasContext, LONG lFlags, LONG *plDevErrVal); STDMETHODIMP drvUnLockWiaDevice(BYTE *pWiasContext, LONG lFlags, LONG *plDevErrVal); STDMETHODIMP drvAnalyzeItem(BYTE *pWiasContext, LONG lFlags, LONG *plDevErrVal); STDMETHODIMP drvGetWiaFormatInfo(BYTE *pWiasContext, LONG lFlags, LONG *pCelt, WIA_FORMAT_INFO **ppwfi, LONG *plDevErrVal); STDMETHODIMP drvNotifyPnpEvent(const GUID *pEventGUID, BSTR bstrDeviceID, ULONG ulReserved); STDMETHODIMP drvReadItemProperties(BYTE *pWiaItem, LONG lFlags, ULONG nPropSpec, const PROPSPEC *pPropSpec, LONG *plDevErrVal); STDMETHODIMP drvWriteItemProperties(BYTE *pWiasContext, LONG lFLags, PMINIDRV_TRANSFER_CONTEXT pmdtc, LONG *plDevErrVal); STDMETHODIMP drvValidateItemProperties(BYTE *pWiasContext, LONG lFlags, ULONG nPropSpec, const PROPSPEC *pPropSpec, LONG *plDevErrVal); STDMETHODIMP drvAcquireItemData(BYTE *pWiasContext, LONG lFlags, PMINIDRV_TRANSFER_CONTEXT pDataContext, LONG *plDevErrVal); STDMETHODIMP drvGetDeviceErrorStr(LONG lFlags, LONG lDevErrVal, LPOLESTR *ppszDevErrStr, LONG *plDevErrVal); STDMETHODIMP drvFreeDrvItemContext(LONG lFlags, BYTE *pDevContext, LONG *plDevErrVal);
//
// Public helper functions (in eventcb.cpp)
//
HRESULT EventCallbackDispatch(PPTP_EVENT pEvent);
private:
//
// Private helper functions (in minidriver.cpp)
//
HRESULT Shutdown(); HRESULT TakePicture(BYTE *pWiasContext, IWiaDrvItem **ppNewItem); LONG GetTotalFreeImageSpace(); HRESULT WiasContextToItemContext(BYTE *pWiasContext, DRVITEM_CONTEXT **ppItemContext, IWiaDrvItem **ppDrvItem = NULL); HRESULT LoadStrings(); HRESULT GetResourceString(LONG lResourceID, WCHAR *pString, int length); HRESULT InitVendorExtentions(HKEY hkDevParams); HRESULT UpdateStorageInfo(ULONG StorageId); HRESULT NotifyWiaOnStateChanges();
//
// Private helper functions (in devitem.cpp)
//
HRESULT CreateDrvItemTree(IWiaDrvItem **ppRoot); HRESULT AddObject(DWORD ObjectHandle, BOOL bQueueEvent = FALSE, CPtpObjectInfo *pProvidedObjectInfo = NULL); HRESULT InitDeviceProperties(BYTE *pWiasContext); HRESULT ReadDeviceProperties(BYTE *pWiasContext, LONG NumPropSpecs, const PROPSPEC *pPropSpecs); HRESULT WriteDeviceProperties(BYTE *pWiasContext); HRESULT ValidateDeviceProperties(BYTE *pWiasContext, LONG NumPropSpecs, const PROPSPEC *pPropSpecs); HRESULT FindCorrDimension(BYTE *pWiasContext, LONG *pWidth, LONG *pHeight); int FindProportionalValue(int valueX, int minX, int maxX, int minY, int maxY, int stepY); PPROP_INFO PropCodeToPropInfo(WORD PropCode); int NumLogicalStorages();
//
// Private helper functions (in imgitem.cpp)
//
HRESULT InitItemProperties(BYTE *pWiasContext); HRESULT IsObjectProtected(CPtpObjectInfo *pObjectInfo, LONG &lProtection); HRESULT GetObjectTime(CPtpObjectInfo *pObjectInfo, SYSTEMTIME *pSystemTime); HRESULT ReadItemProperties(BYTE *pWiasContext, LONG NumPropSpecs, const PROPSPEC *pPropSpecs); HRESULT CacheThumbnail(PDRVITEM_CONTEXT pDrvItemCtx); HRESULT ValidateItemProperties(BYTE *pWiasContext, LONG NumPropSpecs, const PROPSPEC *pPropSpecs, LONG ItemType); HRESULT AcquireDataAndTranslate(BYTE *pWiasContext, DRVITEM_CONTEXT *pItemCtx, PMINIDRV_TRANSFER_CONTEXT pmdtc); HRESULT AcquireAndTranslateJpegWithoutGeometry(BYTE *pWiasContext, DRVITEM_CONTEXT *pItemCtx, PMINIDRV_TRANSFER_CONTEXT pmdtc); HRESULT AcquireAndTranslateAnyImage(BYTE *pWiasContext, DRVITEM_CONTEXT *pItemCtx, PMINIDRV_TRANSFER_CONTEXT pmdtc); HRESULT AcquireData(DRVITEM_CONTEXT *pItemCtx, PMINIDRV_TRANSFER_CONTEXT pmdtc);
//
// Event handling functions (in eventcb.cpp)
//
HRESULT AddNewObject(DWORD ObjectHandle); HRESULT RemoveObject(DWORD ObjectHandle); HRESULT AddNewStorage(DWORD StorageId); HRESULT RemoveStorage(DWORD StorageId); HRESULT DevicePropChanged(WORD PropCode); HRESULT ObjectInfoChanged(DWORD ObjectHandle); HRESULT StorageFull(DWORD StorageId); HRESULT StorageInfoChanged(DWORD StorageId); HRESULT CaptureComplete(); HRESULT PostVendorEvent(WORD EventCode);
//
// Inline utilities
//
BOOL IsItemTypeFolder(LONG ItemType) { return ((WiaItemTypeFolder & ItemType) && !(ItemType & (WiaItemTypeStorage | WiaItemTypeRoot))); }
//
// Member variables
//
WIA_DEV_CAP_DRV *m_Capabilities; // List of device capabilities. Build once and use every time we are asked
UINT m_nEventCaps; // Number of events supported
UINT m_nCmdCaps; // Number of commands supported
BOOL m_fInitCaptureChecked; // Indicates if we have already queried camera for InitiateCapture command support
int m_OpenApps; // Number of apps that are communicating with this driver
IWiaDrvItem *m_pDrvItemRoot; // Pointer to the root of the driver item tree
CPTPCamera *m_pPTPCamera; // Pointer to camera object--actually holds CUsbCamera object
CPtpDeviceInfo m_DeviceInfo; // DeviceInfo structure for the camera
CArray32 m_StorageIds; // Holds the current storage ids
CWiaArray<CPtpStorageInfo> m_StorageInfos; // Holds the StorageInfo structures
CWiaArray<CPtpPropDesc> m_PropDescs; // Property description structures
CWiaMap<ULONG, IWiaDrvItem *> m_HandleItem; // Used to map PTP object handles to WIA driver items
LONG m_NumImages; // The number of images currently on the device
IStiDevice *m_pStiDevice; // Pointer to the driver's STI interface
BSTR m_bstrDeviceId; // STI device ID
BSTR m_bstrRootItemFullName; // Full name of root item
PSTIDEVICECONTROL m_pDcb; // Pointer to the IStiDeviceControl interface
HANDLE m_TakePictureDoneEvent; // Event handle to indicate when TakePicture command is done
DWORD m_VendorExtId; // Vendor extension id (from registry)
CWiaMap<WORD, PROP_INFO *> m_VendorPropMap; // Maps PropCodes to PROP_INFO structures
CWiaMap<WORD, CVendorEventInfo*> m_VendorEventMap; // Maps EventCodes to event info
HANDLE m_hPtpMutex; // Mutex used for exclusive access to device
CArray32 m_DcimHandle; // ObjectHandle of the DCIM folder for each storage, if it exists
CWiaMap<ULONG, IWiaDrvItem *> m_AncAssocParent; // Maps ancillary association handles to their parents
DWORD m_dwObjectBeingSent; // Temporary location for object handle between SendObjectInfo and SendObject
CWiaArray<DWORD> m_CapturedObjects; // List of new objects reported during capture operation, but not yet processed
BOOL m_bTwoDigitsMillisecondsOutput; // In XP, PTP driver was sending DATETIME string to camera with two digits
// for milliseconds (bug 699699). Some cameras may expect this format.
ULONG m_Refs; // Reference count on the object
IUnknown *m_punkOuter; // Pointer to outer IUnknown
};
//
// Functions for handling PTP callbacks
//
HRESULT EventCallback(LPVOID pCallbackParam, PPTP_EVENT pEvent); HRESULT DataCallback(LPVOID pCallbackParam, LONG lPercentComplete, LONG lOffset, LONG lLength, BYTE **ppBuffer, LONG *plBufferSize);
//
// Helper functions
//
PFORMAT_INFO FormatCodeToFormatInfo(WORD FormatCode, WORD AssocType = 0); WORD FormatGuidToFormatCode(GUID *pFormatGuid); WORD PropIdToPropCode(PROPID PropId); VOID SplitImageSize(CBstr cbstr, LONG *pWidth, LONG *pHeight);
//
// Simple object for handling mutexes. It will make sure that the mutex is released
// no matter how the function is exited.
//
class CPtpMutex { public: CPtpMutex(HANDLE hMutex); ~CPtpMutex();
private: HANDLE m_hMutex; };
#endif // #ifndef MINIDRV__H_
|