|
|
/*****************************************************************************
* * StiObj.c * * Copyright (c) 1996 Microsoft Corporation. All Rights Reserved. * * Abstract: * * The IStillImage main interface. * * Contents: * * CStiObj_New * *****************************************************************************/ #include "sticomm.h"
#include "enum.h"
#include "stisvc.h"
//
// Private defines
//
#define DbgFl DbgFlSti
//
//
//
#undef IStillImage
//
// DEVICE_INFO_SIZE and WIA_DEVICE_INFO_SIZE
//
// These defines represent the space needed to store the device information
// structs and the string data that some of their members point to.
// STI_DEVICE_INFORMATION has 5 strings while STI_WIA_DEVICE_INFORMATION
// has 6. To be completely safe, these device info sizes should be
// (MAX_PATH * sizeof(WCHAR) * no. of strings) + struct size.
//
#define DEVICE_INFO_SIZE (sizeof(STI_DEVICE_INFORMATION)+(MAX_PATH * sizeof(WCHAR) * 5))
#define WIA_DEVICE_INFO_SIZE (sizeof(STI_WIA_DEVICE_INFORMATION)+(MAX_PATH * sizeof(WCHAR) * 6))
//
// DEVICE_LIST_SIZE. Note that this is currently a fixed size, but will change
// as soon we abstract device enumeration into a class.
//
// Device list size is fixed at the moment. It's size is:
// MAX_NUM_DEVICES * (max(DEVICE_INFO_SIZE, WIA_DEVICE_INFO_SIZE))
// i.e. enough to hold MAX_NUM_DEVICES only.
#define MAX_NUM_DEVICES 16
#define DEVICE_LIST_SIZE MAX_NUM_DEVICES * (max(DEVICE_INFO_SIZE, WIA_DEVICE_INFO_SIZE))
/*****************************************************************************
* * @doc INTERNAL * * @struct CStiObj | * * The <i IStillImage> object, from which other things come. * * * @field IStillImage | Sti | * * STI interface * * @field IStillImage | dwVersion | * * Version identifier * * @comm * * We contain no instance data, so no critical section * is necessary. * *****************************************************************************/
typedef struct CStiObj {
/* Supported interfaces */ TFORM(IStillImage) TFORM(sti); SFORM(IStillImage) SFORM(sti);
DWORD dwVersion;
} CStiObj, *PCStiObj;
#define ThisClass CStiObj
#define ThisInterface TFORM(IStillImage)
#define ThisInterfaceA IStillImageA
#define ThisInterfaceW IStillImageW
#define ThisInterfaceT IStillImage
/*****************************************************************************
* * Declare the interfaces we will be providing. * *****************************************************************************/
Primary_Interface(CStiObj, TFORM(ThisInterfaceT)); Secondary_Interface(CStiObj, SFORM(ThisInterfaceT));
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | QueryInterface | * * Gives a client access to other interfaces on an object. * * @cwrap LPStillImage | lpStillImage * * @parm IN REFIID | riid | * * The requested interface's IID. * * @parm OUT LPVOID * | ppvObj | * * Receives a pointer to the obtained interface. * * @returns * * Returns a COM error code. * * @xref OLE documentation for <mf IUnknown::QueryInterface>. * ***************************************************************************** * * @doc EXTERNAL * * @method HRESULT | IStillImage | AddRef | * * Increments the reference count for the interface. * * @cwrap LPStillImage | lpStillImage * * @returns * * Returns the object reference count. * * @xref OLE documentation for <mf IUnknown::AddRef>. * ***************************************************************************** * * @doc EXTERNAL * * @method HRESULT | IStillImage | Release | * * Decrements the reference count for the interface. * If the reference count on the object falls to zero, * the object is freed from memory. * * @cwrap LPStillImage | lpStillImage * * @returns * * Returns the object reference count. * * @xref OLE documentation for <mf IUnknown::Release>. * ***************************************************************************** * * @doc INTERNAL * * @method HRESULT | IStillImage | QIHelper | * * We don't have any dynamic interfaces and simply forward * to <f Common_QIHelper>. * * @parm IN REFIID | riid | * * The requested interface's IID. * * @parm OUT LPVOID * | ppvObj | * * Receives a pointer to the obtained interface. * ***************************************************************************** * * @doc INTERNAL * * @method HRESULT | IStillImage | Finalize | * * We don't have any instance data, so we can just * forward to <f Common_Finalize>. * *****************************************************************************/
#ifdef DEBUG
Default_QueryInterface(CStiObj) Default_AddRef(CStiObj) Default_Release(CStiObj)
#else
#define CStiObj_QueryInterface Common_QueryInterface
#define CStiObj_AddRef Common_AddRef
#define CStiObj_Release Common_Release
#endif
#define CStiObj_QIHelper Common_QIHelper
//#define CStiObj_Finalize Common_Finalize
#pragma BEGIN_CONST_DATA
#pragma END_CONST_DATA
/*****************************************************************************
* * @doc INTERNAL * * @method HRESULT | IStillImage | CreateDeviceHelper | * * Creates and initializes an instance of a device which is * specified by the GUID and IID. * * @cwrap LPStillImage | lpStillImage * * @parm IN PCGUID | pguid | * * See <mf IStillImage::CreateDevice>. * * @parm OUT PPV | ppvObj | * * See <mf IStillImage::CreateDevice>. * * @parm IN LPUNKNOWN | punkOuter | * * See <mf IStillImage::CreateDevice>. * * @parm IN RIID | riid | * * The interface the application wants to create. This will * be <i IStillImageDevice> . * If the object is aggregated, then this parameter is ignored. * * @returns * * Returns a COM error code. * *****************************************************************************/
STDMETHODIMP CStiObj_CreateDeviceHelper( PCStiObj this, LPWSTR pwszDeviceName, PPV ppvObj, DWORD dwMode, PUNK punkOuter, RIID riid) { HRESULT hres = STIERR_INVALID_PARAM;
EnterProc(CStiObj_CreateDeviceHelper,(_ "ppxG", this, pwszDeviceName, punkOuter, riid));
hres = CStiDevice_New(punkOuter, riid, ppvObj);
if (SUCCEEDED(hres) && punkOuter == 0) { PSTIDEVICE pdev = *ppvObj; hres = IStiDevice_Initialize(pdev, g_hInst,pwszDeviceName,this->dwVersion,dwMode); if (SUCCEEDED(hres)) { } else { Invoke_Release(ppvObj); }
}
ExitOleProcPpv(ppvObj); return hres;
}
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | CreateDevice | * * Creates and initializes an instance of a device which is * specified by the GUID and IID. * * @cwrap LPStillImage | lpStillImage * * @parm REFGUID | rguid | * Identifies the instance of the * device for which the indicated interface * is requested. The <mf IStillImage::EnumDevices> method * can be used to determine which instance GUIDs are supported by * the system. * * @parm OUT LPSTIDEVICE * | lplpStillImageDevice | * Points to where to return * the pointer to the <i IStillImageDevice> interface, if successful. * * @parm IN LPUNKNOWN | punkOuter | Pointer to controlling unknown * for OLE aggregation, or 0 if the interface is not aggregated. * Most callers will pass 0. * * @comm Calling this function with <p punkOuter> = NULL * is equivalent to creating the object via * <f CoCreateInstance>(&CLSID_StillImageDevice, NULL, * CLSCTX_INPROC_SERVER, <p riid>, <p lplpStillImageDevice>); * then initializing it with <f Initialize>. * * Calling this function with <p punkOuter> != NULL * is equivalent to creating the object via * <f CoCreateInstance>(&CLSID_StillImageDevice, <p punkOuter>, * CLSCTX_INPROC_SERVER, &IID_IUnknown, <p lplpStillImageDevice>). * The aggregated object must be initialized manually. * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * * <c STIERR_NOINTERFACE> = <c E_NOINTERFACE> * The specified interface is not supported by the object. * * <c STIERR_DEVICENOTREG> = The device instance does not * correspond to a device that is registered with StillImage. * *****************************************************************************/
STDMETHODIMP CStiObj_CreateDeviceW( PV pSti, LPWSTR pwszDeviceName, DWORD dwMode, PSTIDEVICE *ppDev, PUNK punkOuter ) { HRESULT hres = STIERR_INVALID_PARAM; EnterProcR(IStillImage::CreateDevice,(_ "ppp", pSti, pwszDeviceName, punkOuter));
// Validate passed pointer to interface and obtain pointer to object instance
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
hres = CStiObj_CreateDeviceHelper(this, pwszDeviceName, (PPV)ppDev,dwMode,punkOuter, &IID_IStiDevice); }
ExitOleProcPpv(ppDev); return hres; }
STDMETHODIMP CStiObj_CreateDeviceA( PV pSti, LPCSTR pszDeviceName, DWORD dwMode, PSTIDEVICE *ppDev, PUNK punkOuter ) { HRESULT hres = STIERR_INVALID_PARAM;
EnterProcR(IStillImage::CreateDevice,(_ "ppp", pSti, pszDeviceName, punkOuter));
// Validate passed pointer to interface and obtain pointer to object instance
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
PVOID pBuffer = NULL; UINT uiSize = (lstrlenA(pszDeviceName)+1)*sizeof(WCHAR);
hres = AllocCbPpv(uiSize, &pBuffer); if (SUCCEEDED(hres)) {
*((LPWSTR)pBuffer) = L'\0'; AToU(pBuffer,uiSize,pszDeviceName);
hres = CStiObj_CreateDeviceHelper(this, (LPWSTR)pBuffer, (PPV)ppDev, dwMode, punkOuter, &IID_IStiDevice);
FreePpv(&pBuffer); } }
ExitOleProcPpv(ppDev); return hres; }
/*****************************************************************************
* * @doc INTERNAL * * @method HRESULT | IStillImage | GetDeviceInfoHelper | * * * @cwrap LPStillImage | lpStillImage * * @returns * * Returns a COM error code. * * No validation performed * *****************************************************************************/
BOOL INLINE AddOneString(LPCWSTR pStart,LPCWSTR pNew,LPWSTR *ppTarget) { if (pStart + OSUtil_StrLenW(pNew) + 1 < *ppTarget ) { (*ppTarget)-= (OSUtil_StrLenW(pNew) + 1); OSUtil_lstrcpyW(*ppTarget,pNew); return TRUE; }
return FALSE; }
/*
BOOL INLINE AddOneStringA(LPCSTR pStart,LPCSTR pNew,LPSTR *ppTarget) { if (pStart + lstrlenA(pNew) + 1 < *ppTarget ) { (*ppTarget)-= (lstrlenA(pNew) + 1); lstrcpyA(*ppTarget,pNew); return TRUE; }
return FALSE; } */
BOOL PullFromRegistry( HKEY hkeyDevice, LPWSTR *ppwstrPointer, LPCWSTR lpwstrKey, LPCWSTR lpwstrBarrier, LPWSTR *ppwstrBuffer ) { BOOL bReturn = TRUE; LPWSTR pwstrNewString = NULL;
ReadRegistryString(hkeyDevice,lpwstrKey,L"",FALSE,&pwstrNewString);
*ppwstrPointer = NULL;
if (pwstrNewString) {
bReturn = AddOneString(lpwstrBarrier, pwstrNewString,ppwstrBuffer);
FreePv(pwstrNewString);
*ppwstrPointer = *ppwstrBuffer; }
return bReturn; }
STDMETHODIMP GetDeviceInfoHelper( LPWSTR pszDeviceName, PSTI_DEVICE_INFORMATION *ppCurrentDevPtr, PWSTR *ppwszCurrentString ) {
HRESULT hres = STIERR_INVALID_PARAM; HKEY hkeyDevice;
PSTI_DEVICE_INFORMATION pDevPtr = *ppCurrentDevPtr; // PWSTR pwszNewString = NULL;
PWSTR pwszBarrier;
PWSTR pwszTargetString = *ppwszCurrentString;
DWORD dwMajorType,dwMinorType;
// Open device registry key
hres = OpenDeviceRegistryKey(pszDeviceName,NULL,&hkeyDevice);
if (!SUCCEEDED(hres)) { return hres; }
//
// Read flags and strings
//
pDevPtr->dwSize = cbX(STI_DEVICE_INFORMATION);
dwMajorType = dwMinorType = 0;
ZeroX(pDevPtr->DeviceCapabilities) ; ZeroX(pDevPtr->dwHardwareConfiguration) ;
dwMajorType = (STI_DEVICE_TYPE)ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_DEVICETYPE_W,StiDeviceTypeDefault); dwMinorType = (STI_DEVICE_TYPE)ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_DEVICESUBTYPE_W,0);
pDevPtr->DeviceCapabilities.dwGeneric = ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_GENERIC_CAPS_W,0);
pDevPtr->DeviceType = MAKELONG(dwMinorType,dwMajorType);
pDevPtr->dwHardwareConfiguration = ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_HARDWARE_W,0);
OSUtil_lstrcpyW(pDevPtr->szDeviceInternalName,pszDeviceName);
//
// Add strings
//
pwszBarrier = (LPWSTR)((LPBYTE)pDevPtr + pDevPtr->dwSize);
//
// Add strings
//
pwszBarrier = (LPWSTR)((LPBYTE)pDevPtr + pDevPtr->dwSize);
if ( !PullFromRegistry(hkeyDevice, &pDevPtr -> pszVendorDescription, REGSTR_VAL_VENDOR_NAME_W, pwszBarrier, &pwszTargetString) ||
!PullFromRegistry(hkeyDevice, &pDevPtr->pszLocalName, REGSTR_VAL_FRIENDLY_NAME_W, pwszBarrier, &pwszTargetString) ||
!PullFromRegistry(hkeyDevice, &pDevPtr->pszDeviceDescription, REGSTR_VAL_DEVICE_NAME_W, pwszBarrier, &pwszTargetString) ||
!PullFromRegistry(hkeyDevice, &pDevPtr->pszPortName, REGSTR_VAL_DEVICEPORT_W, pwszBarrier, &pwszTargetString) ||
//!PullFromRegistry(hkeyDevice, &pDevPtr->pszTwainDataSource,
//REGSTR_VAL_TWAIN_SOURCE_W, pwszBarrier, &pwszTargetString) ||
//!PullFromRegistry(hkeyDevice, &pDevPtr->pszEventList,
//REGSTR_VAL_EVENTS_W, pwszBarrier, &pwszTargetString) ||
!PullFromRegistry(hkeyDevice, &pDevPtr->pszPropProvider, REGSTR_VAL_PROP_PROVIDER_W, pwszBarrier, &pwszTargetString)) {
// we ran out of memory, somewhere
RegCloseKey(hkeyDevice); return E_OUTOFMEMORY;
}
#ifdef DEAD_CODE
ReadRegistryString(hkeyDevice,REGSTR_VAL_VENDOR_NAME_W,L"",FALSE,&pwszNewString);
pDevPtr->pszVendorDescription = NULL;
if (pwszNewString) {
if (!AddOneString(pwszBarrier,pwszNewString,&pwszTargetString)) { // Not enough room for next string
hres = E_OUTOFMEMORY; goto Cleanup; }
FreePv(pwszNewString); pwszNewString = NULL;
pDevPtr->pszVendorDescription = pwszTargetString; }
ReadRegistryString(hkeyDevice,REGSTR_VAL_DEV_NAME_W,L"",FALSE,&pwszNewString); if (!pwszNewString || !*pwszNewString) { FreePv(pwszNewString); pwszNewString = NULL;
ReadRegistryString(hkeyDevice,REGSTR_VAL_DRIVER_DESC_W,L"",FALSE,&pwszNewString); }
pDevPtr->pszLocalName = NULL;
if (pwszNewString) {
if (!AddOneString(pwszBarrier,pwszNewString,&pwszTargetString)) { // Not enough room for next string
hres = E_OUTOFMEMORY; goto Cleanup; }
FreePv(pwszNewString); pwszNewString = NULL;
pDevPtr->pszLocalName = pwszTargetString; } #endif
*ppCurrentDevPtr += 1; *ppwszCurrentString = pwszTargetString;
#ifdef DEAD_CODE
Cleanup: if (pwszNewString) { FreePv(pwszNewString); } #endif
RegCloseKey(hkeyDevice);
return S_OK;
}
/**************************************************************************\
* GetDeviceInfoHelperWIA * * get WIA info as well * * Arguments: * * * * Return Value: * * Status * * History: * * 10/6/1998 Original Version * \**************************************************************************/
STDMETHODIMP GetDeviceInfoHelperWIA( LPWSTR pszDeviceName, PSTI_WIA_DEVICE_INFORMATION *ppCurrentDevPtr, PWSTR *ppwszCurrentString ) {
HRESULT hres = STIERR_INVALID_PARAM;
HKEY hkeyDevice; HKEY hkeyDeviceData;
PSTI_WIA_DEVICE_INFORMATION pDevPtr = *ppCurrentDevPtr; PWSTR pwszBarrier;
PWSTR pwszTargetString = *ppwszCurrentString;
DWORD dwMajorType,dwMinorType;
BOOL bRet;
// Open device registry key
hres = OpenDeviceRegistryKey(pszDeviceName,NULL,&hkeyDevice);
if (!SUCCEEDED(hres)) { return hres; }
//
// open DeviceData field
//
hres = OpenDeviceRegistryKey(pszDeviceName,L"DeviceData",&hkeyDeviceData);
if (!SUCCEEDED(hres)) { RegCloseKey(hkeyDevice); return hres; }
//
// Read flags and strings
//
pDevPtr->dwSize = cbX(STI_WIA_DEVICE_INFORMATION);
dwMajorType = dwMinorType = 0;
ZeroX(pDevPtr->DeviceCapabilities) ; ZeroX(pDevPtr->dwHardwareConfiguration) ;
dwMajorType = (STI_DEVICE_TYPE)ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_DEVICETYPE_W,StiDeviceTypeDefault); dwMinorType = (STI_DEVICE_TYPE)ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_DEVICESUBTYPE_W,0);
pDevPtr->DeviceCapabilities.dwGeneric = ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_GENERIC_CAPS_W,0);
pDevPtr->DeviceType = MAKELONG(dwMinorType,dwMajorType);
pDevPtr->dwHardwareConfiguration = ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_HARDWARE_W,0);
OSUtil_lstrcpyW(pDevPtr->szDeviceInternalName,pszDeviceName);
//
// Add strings
//
pwszBarrier = (LPWSTR)((LPBYTE)pDevPtr + pDevPtr->dwSize);
bRet = PullFromRegistry(hkeyDevice, &pDevPtr ->pszVendorDescription, REGSTR_VAL_VENDOR_NAME_W, pwszBarrier, &pwszTargetString);
if (!bRet) { goto InfoCleanup; }
bRet = PullFromRegistry(hkeyDevice, &pDevPtr->pszLocalName, REGSTR_VAL_FRIENDLY_NAME_W, pwszBarrier, &pwszTargetString);
if (!bRet) { goto InfoCleanup; }
bRet = PullFromRegistry(hkeyDevice, &pDevPtr->pszDeviceDescription, REGSTR_VAL_DEVICE_NAME_W, pwszBarrier, &pwszTargetString); if (!bRet) { goto InfoCleanup; }
bRet = PullFromRegistry(hkeyDevice, &pDevPtr->pszPortName, REGSTR_VAL_DEVICEPORT_W, pwszBarrier, &pwszTargetString); if (!bRet) { goto InfoCleanup; }
bRet = PullFromRegistry(hkeyDevice, &pDevPtr->pszPropProvider, REGSTR_VAL_PROP_PROVIDER_W, pwszBarrier, &pwszTargetString); if (!bRet) { goto InfoCleanup; }
//
// WIA VALUES
//
bRet = PullFromRegistry(hkeyDeviceData, &pDevPtr->pszServer, WIA_DIP_SERVER_NAME_STR, pwszBarrier, &pwszTargetString); if (!bRet) { goto InfoCleanup; }
*ppCurrentDevPtr += 1; *ppwszCurrentString = pwszTargetString;
RegCloseKey(hkeyDeviceData); RegCloseKey(hkeyDevice);
return S_OK;
InfoCleanup:
//
// we ran out of memory, somewhere
//
RegCloseKey(hkeyDevice); RegCloseKey(hkeyDeviceData); return E_OUTOFMEMORY; }
/*
* Setting device information helper * */ STDMETHODIMP SetDeviceInfoHelper( PSTI_DEVICE_INFORMATION pDevPtr ) { HRESULT hres = S_OK; HKEY hkeyDevice;
PWSTR pwszNewString = NULL;
DWORD dwHardwareConfiguration; DWORD dwError;
if (!pDevPtr || OSUtil_StrLenW(pDevPtr->szDeviceInternalName) > STI_MAX_INTERNAL_NAME_LENGTH) { return STIERR_INVALID_PARAM; }
//
// Open device registry key
//
hres = OpenDeviceRegistryKey(pDevPtr->szDeviceInternalName,NULL,&hkeyDevice);
if (!SUCCEEDED(hres)) { return STIERR_INVALID_DEVICE_NAME; }
ZeroX(dwHardwareConfiguration) ; dwHardwareConfiguration = ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_HARDWARE_W,0);
#ifdef NOT_IMPL
//
// Changing device information by caller is allowed only for Unknown device types
// For all others settings are handled by setup and control panel
//
if (dwHardwareConfiguration != STI_HW_CONFIG_UNKNOWN ) { hres = STIERR_INVALID_HW_TYPE; goto Cleanup; } #endif
//
// Store new port name, and new FriendlyName
//
if (!IsBadStringPtrW(pDevPtr->pszPortName, MAX_PATH * sizeof(WCHAR))) { dwError = WriteRegistryStringW(hkeyDevice , REGSTR_VAL_DEVICEPORT_W, pDevPtr->pszPortName, (OSUtil_StrLenW(pDevPtr->pszPortName)+1)*sizeof(WCHAR), REG_SZ ); if ((dwError == ERROR_SUCCESS) && !(IsBadStringPtrW(pDevPtr->pszLocalName, MAX_PATH * sizeof(WCHAR)))) {
dwError = WriteRegistryStringW(hkeyDevice , REGSTR_VAL_FRIENDLY_NAME_W, pDevPtr->pszLocalName, (OSUtil_StrLenW(pDevPtr->pszLocalName)+1)*sizeof(WCHAR), REG_SZ ); if (dwError == ERROR_SUCCESS) { hres = S_OK; } }
if (dwError != ERROR_SUCCESS) { hres = MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError); } } else { hres = STIERR_INVALID_PARAM; goto Cleanup; }
Cleanup: if (pwszNewString) { FreePv(pwszNewString); }
RegCloseKey(hkeyDevice);
return hres; }
/*****************************************************************************
* * @doc INTERNAL * * @method HRESULT | IStillImage | IsStillImageDeviceRegistryNode | * * Verifies if given enumeration registry node is associated with Still Image device * * @cwrap LPStillImage | lpStillImage * * @returns * * TRUE if node is representing still image devie * * No validation performed * *****************************************************************************/ BOOL WINAPI IsStillImageDeviceRegistryNode( LPTSTR ptszDeviceKey ) { BOOL fRet = FALSE; DWORD dwError;
HKEY hkeyDevice = NULL; HKEY hkeyDeviceParameters = NULL;
TCHAR szDevClass[64]; // NOTE: This technically shouldn't be a
// hardcoded number, we should do a RegQueryValueEx
// to get the required size, allocate the memory,
// and then call RegQueryValueEx for the data.
// However, if either the class name or image name
// cannot fit into this buffer, we know it doesn't
// belong to us, so this is OK.
TCHAR szDevDriver[STI_MAX_INTERNAL_NAME_LENGTH]; TCHAR szDeviceKey[MAX_PATH];
ULONG cbData;
//
// Open enumeration registry key
//
dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, // hkey
ptszDeviceKey, // reg entry string
0, // dwReserved
KEY_READ, // access
&hkeyDevice); // pHkeyReturned.
if (ERROR_SUCCESS != dwError) { return FALSE; }
//
// First check it's class . It should be equal to "Image"
//
cbData = sizeof(szDevClass); *szDevClass = TEXT('\0'); if ((RegQueryValueEx(hkeyDevice, REGSTR_VAL_CLASS, NULL, NULL, (PBYTE)szDevClass, &cbData) != ERROR_SUCCESS) || (lstrcmpi(szDevClass, CLASSNAME) != 0)) { fRet = FALSE; goto CleanUp; }
//
// Now we check subclass in one of two locations: either in enumeration subkey, or in
// control subkey
//
cbData = sizeof(szDevClass); if (RegQueryValueEx(hkeyDevice, REGSTR_VAL_SUBCLASS, NULL, NULL, (PBYTE)szDevClass, &cbData) == ERROR_SUCCESS) {
fRet = (lstrcmpi(szDevClass, STILLIMAGE) == 0) ? TRUE : FALSE; goto CleanUp; }
cbData = sizeof(szDevDriver); dwError = RegQueryValueEx(hkeyDevice, REGSTR_VAL_DRIVER, NULL, NULL, (PBYTE)szDevDriver, &cbData); if (ERROR_SUCCESS != dwError ) { goto CleanUp; }
lstrcat(lstrcpy(szDeviceKey, (g_NoUnicodePlatform) ? REGSTR_PATH_STIDEVICES : REGSTR_PATH_STIDEVICES_NT), TEXT("\\"));
lstrcat(szDeviceKey,szDevDriver);
dwError = RegCreateKeyEx(HKEY_LOCAL_MACHINE, szDeviceKey, 0L, NULL, 0L, KEY_READ, NULL, &hkeyDeviceParameters, NULL ); if (ERROR_SUCCESS != dwError) { goto CleanUp; }
cbData = sizeof(szDevClass); dwError = RegQueryValueEx(hkeyDeviceParameters, REGSTR_VAL_SUBCLASS, NULL, NULL, (PBYTE)szDevClass, &cbData); if (ERROR_SUCCESS == dwError) {
fRet = (lstrcmpi(szDevClass, STILLIMAGE) == 0) ? TRUE : FALSE; goto CleanUp; }
CleanUp: if (hkeyDevice) { RegCloseKey(hkeyDevice); hkeyDevice = NULL; }
if (hkeyDeviceParameters) { RegCloseKey(hkeyDeviceParameters); hkeyDeviceParameters = NULL; }
return fRet;
} // endproc IsStillImageDeviceRegistryNode
/*
DWORD EnumNextLevel( LPSTR *ppCurrentDevPtr, LPWSTR *ppwszCurrentString, DWORD *pdwItemsReturned, BOOL *pfAlreadyEnumerated, LPSTR pszDeviceKey, int Level ) {
HKEY hkeyDevice;
char szDevDriver[STI_MAX_INTERNAL_NAME_LENGTH]; WCHAR wszDeviceKey[MAX_PATH];
ULONG cbString; ULONG cbData; DWORD dwIndex; DWORD dwError; DEVINST dnDevNode; USHORT cbEnumPath; HANDLE hDevInfo; GUID Guid; DWORD dwRequired; DWORD Idx; SP_DEVINFO_DATA spDevInfoData; DWORD dwConfigFlags;
dwError = 0;
if (Level == 0) {
if(!IsStillImageDeviceRegistryNodeA(pszDeviceKey)) { //
// Nobody there...continue with the enumeration
//
return 0; }
dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, // hkey
pszDeviceKey, // reg entry string
0, // dwReserved
KEY_READ, // access
&hkeyDevice); // pHkeyReturned.
if (dwError != ERROR_SUCCESS) { return 0; }
dnDevNode = 0;
cbEnumPath = ((g_NoUnicodePlatform) ? lstrlen(REGSTR_PATH_ENUM) : lstrlen(REGSTR_PATH_NT_ENUM_A)) + 1;
CM_Locate_DevNode (&dnDevNode, pszDeviceKey + cbEnumPath, 0);
if (dnDevNode == 0 && *pfAlreadyEnumerated == FALSE) {
#ifdef NODEF
//
// This is dead code, it should be removed.
//
//
// Try to locate this devnode by forcing a re-enumeration.
//
if (SetupDiClassGuidsFromName (REGSTR_KEY_SCSI_CLASS, &Guid, sizeof(GUID), &dwRequired)) {
hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, 0);
if (hDevInfo != INVALID_HANDLE_VALUE) {
spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++) {
CM_Reenumerate_DevNode (spDevInfoData.DevInst, CM_REENUMERATE_SYNCHRONOUS);
}
}
SetupDiDestroyDeviceInfoList (hDevInfo); } #endif
//
// Try again to locate our devnode.
//
*pfAlreadyEnumerated = TRUE;
CM_Locate_DevNode (&dnDevNode, pszDeviceKey + cbEnumPath, 0);
if (dnDevNode == 0) {
//
// Skip this one.
//
RegCloseKey(hkeyDevice); return 0; } }
//
// Check that this device is in the current hardware profile
//
dwConfigFlags = 0;
CM_Get_HW_Prof_Flags (pszDeviceKey + cbEnumPath, 0, &dwConfigFlags, 0);
if (dwConfigFlags & CSCONFIGFLAG_DO_NOT_CREATE) {
//
// Skip this one.
//
RegCloseKey(hkeyDevice); return 0; }
cbData = sizeof(szDevDriver); if ((RegQueryValueEx(hkeyDevice, REGSTR_VAL_DRIVER, NULL, NULL, szDevDriver, &cbData) == ERROR_SUCCESS)) {
//
// Got one device - add it to the buffer
//
AToU(wszDeviceKey,sizeof(wszDeviceKey)/sizeof(WCHAR),szDevDriver); dwError = (DWORD)GetDeviceInfoHelper(wszDeviceKey, (PSTI_DEVICE_INFORMATION *)ppCurrentDevPtr, ppwszCurrentString); if (!SUCCEEDED(dwError)) {
RegCloseKey(hkeyDevice);
//
// Return value is HRESULT, we should return a Win32 error
//
if (dwError == E_OUTOFMEMORY) { return ERROR_NOT_ENOUGH_MEMORY; } else { return ERROR_INVALID_DATA; } }
(*pdwItemsReturned)++; RegCloseKey(hkeyDevice); return 0;
}
RegCloseKey(hkeyDevice); return 0; }
cbString = lstrlen(pszDeviceKey);
dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, // hkey
pszDeviceKey, // reg entry string
0, // dwReserved
KEY_READ, // access
&hkeyDevice); // pHkeyReturned.
for (dwIndex = 0; dwError == ERROR_SUCCESS; dwIndex++) {
*(pszDeviceKey + cbString) = '\\'; cbData = MAX_PATH - cbString - 1;
dwError = RegEnumKey(hkeyDevice, dwIndex, &pszDeviceKey[cbString+1], cbData);
if (dwError == ERROR_SUCCESS) { if ((dwError = EnumNextLevel (ppCurrentDevPtr, ppwszCurrentString, pdwItemsReturned, pfAlreadyEnumerated, pszDeviceKey, Level - 1)) != ERROR_SUCCESS) {
RegCloseKey(hkeyDevice); pszDeviceKey[cbString] = '\0'; return (dwError);
} } }
RegCloseKey(hkeyDevice); pszDeviceKey[cbString] = '\0'; return(0); } */
DWORD EnumFromSetupApi( LPSTR *ppCurrentDevPtr, LPWSTR *ppwszCurrentString, DWORD *pdwItemsReturned ) {
HANDLE hDevInfo; GUID Guid = GUID_DEVCLASS_IMAGE; DWORD dwRequired; DWORD Idx; SP_DEVINFO_DATA spDevInfoData; SP_DEVICE_INTERFACE_DATA spDevInterfaceData; HKEY hKeyDevice; char szDevDriver[STI_MAX_INTERNAL_NAME_LENGTH]; TCHAR tszDevClass[32]; WCHAR wszDeviceKey[MAX_PATH]; ULONG cbData; DWORD dwError; DWORD dwReturn; DWORD dwType; DWORD dwKeyType;
BOOL fRet; LONG lRet;
PWIA_DEVKEYLIST pWiaDevKeyList;
dwRequired = 0; dwError = ERROR_SUCCESS; dwReturn = ERROR_NO_MATCH; pWiaDevKeyList = NULL;
//
// Get the class device list
//
pWiaDevKeyList = WiaCreateDeviceRegistryList(TRUE); if(NULL != pWiaDevKeyList){
for (Idx = 0; Idx < pWiaDevKeyList->dwNumberOfDevices; Idx++) {
//
// Check whether we have space for this device inside the device list.
// NOTE: This will change when the device list size becomes dynamic
//
if (((Idx + 1) * max(DEVICE_INFO_SIZE, WIA_DEVICE_INFO_SIZE)) > DEVICE_LIST_SIZE) { break; }
//
// Now get all the device info
//
cbData = sizeof(szDevDriver); *szDevDriver = '\0'; dwError = RegQueryValueExA(pWiaDevKeyList->Dev[Idx].hkDeviceRegistry, REGSTR_VAL_DEVICE_ID_A, // REGSTR_VAL_FRIENDLY_NAME_A,
NULL, NULL, (LPBYTE)szDevDriver, &cbData); if(ERROR_SUCCESS == dwError){
AToU(wszDeviceKey,sizeof(wszDeviceKey)/sizeof(WCHAR),szDevDriver);
dwError = (DWORD)GetDeviceInfoHelper(wszDeviceKey, (PSTI_DEVICE_INFORMATION *)ppCurrentDevPtr, ppwszCurrentString); if (!SUCCEEDED(dwError)) {
//
// dwError is an HRESULT, we should return a Win32 error
//
if (dwError == E_OUTOFMEMORY) { dwReturn = ERROR_NOT_ENOUGH_MEMORY; } else { dwReturn = ERROR_INVALID_DATA; } break; } else { //
// At least one device passed.
//
dwReturn = ERROR_SUCCESS; }
(*pdwItemsReturned)++; } else { // if(ERROR_SUCCESS == dwError)
} // if(ERROR_SUCCESS == dwError)
} // for (Idx = 0; pWiaDevKeyList->dwNumberOfDevices; Idx++)
} // if(NULL != pWiaDevKeyList)
//
// Free device registry list.
//
if(NULL != pWiaDevKeyList){ WiaDestroyDeviceRegistryList(pWiaDevKeyList); }
return (dwReturn); }
/*****************************************************************************
* * @doc INTERNAL * * @method HRESULT | IStillImage | BuildDeviceListHelper | * * Fills passed buffer with list of available still image devices * * @cwrap LPStillImage | lpStillImage * * @returns * * Returns a COM error code. * *****************************************************************************/
// BUGBUG does not honor filter flags
STDMETHODIMP BuildDeviceListHelper( DWORD dwType, DWORD dwFlags, DWORD *pdwItemsReturned, LPVOID *ppBuffer ) {
HRESULT hres; DWORD dwError; LPSTR pCurrentDevPtr; LPWSTR pwszCurrentString; BOOL fAlreadyEnumerated;
*pdwItemsReturned = 0; *ppBuffer = NULL; hres = S_OK;
// Get initial buffer for return data
hres = AllocCbPpv(DEVICE_LIST_SIZE, ppBuffer); if (!SUCCEEDED(hres)) { return E_OUTOFMEMORY; }
hres = S_OK;
//
// Re-enumerate parallel device if it's installed and not detected on OS boot.
//
if(0 == dwFlags){ //
// Enumerate LPT port via WIA service.
//
SC_HANDLE hSCM; SC_HANDLE hService; SERVICE_STATUS ServiceStatus;
__try {
//
// Open Service Control Manager.
//
hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_CONNECT); if (!hSCM) { dwError = GetLastError(); __leave; }
//
// Open WIA service.
//
hService = OpenService( hSCM, STI_SERVICE_NAME, SERVICE_USER_DEFINED_CONTROL ); if (!hService) { dwError = GetLastError(); __leave; } //
// Post custom service control message.
//
ControlService(hService, STI_SERVICE_CONTROL_LPTENUM, &ServiceStatus);
//
// Close service handle.
//
CloseServiceHandle(hService); } // __try
__finally { if(NULL != hSCM){ CloseServiceHandle( hSCM ); } // if(NULL != hSCM)
} // __finally
} // if(0 == dwFlags)
//
// NOTE: DEVICE_LIST_SIZE is hard coded for the time being. Checks are done in
// EnumFromSetupApi to ensure we never overrun this buffer.
//
pCurrentDevPtr = *ppBuffer; pwszCurrentString = (LPWSTR)(pCurrentDevPtr + DEVICE_LIST_SIZE); fAlreadyEnumerated = FALSE;
dwError = EnumFromSetupApi (&pCurrentDevPtr, &pwszCurrentString, pdwItemsReturned);
if (dwError != NOERROR) { hres = MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError); FreePpv(ppBuffer); }
return hres;
}
BOOL TranslateDeviceInfo( PSTI_DEVICE_INFORMATIONA pDest, LPSTR *pCurrentStringDest, PSTI_DEVICE_INFORMATIONW pSrc ) {
LPSTR pStringDest = *pCurrentStringDest;
pDest->dwSize = cbX(STI_DEVICE_INFORMATIONA); pDest->DeviceType = pSrc->DeviceType; pDest->DeviceCapabilities = pSrc->DeviceCapabilities; pDest->dwHardwareConfiguration = pSrc->dwHardwareConfiguration;
UToA(pDest->szDeviceInternalName,STI_MAX_INTERNAL_NAME_LENGTH,pSrc->szDeviceInternalName);
UToA(pStringDest,MAX_PATH,pSrc->pszVendorDescription); pDest->pszVendorDescription = pStringDest; pStringDest+=lstrlenA(pStringDest)+sizeof(CHAR);
UToA(pStringDest,MAX_PATH,pSrc->pszDeviceDescription); pDest->pszDeviceDescription = pStringDest; pStringDest+=lstrlenA(pStringDest)+sizeof(CHAR);
UToA(pStringDest,MAX_PATH,pSrc->pszPortName); pDest->pszPortName = pStringDest; pStringDest+=lstrlenA(pStringDest)+sizeof(CHAR);
UToA(pStringDest,MAX_PATH,pSrc->pszPropProvider); pDest->pszPropProvider = pStringDest; pStringDest+=lstrlenA(pStringDest)+sizeof(CHAR);
UToA(pStringDest,MAX_PATH,pSrc->pszLocalName); pDest->pszLocalName = pStringDest; pStringDest+=lstrlenA(pStringDest)+sizeof(CHAR);
*pCurrentStringDest = pStringDest;
return TRUE; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | GetDeviceList | * * * @cwrap LPStillImage | lpStillImage * * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * * <c STIERR_NOINTERFACE> = <c E_NOINTERFACE> * The specified interface is not supported by the object. * * <c STIERR_DEVICENOTREG> = The device instance does not * correspond to a device that is registered with StillImage. * *****************************************************************************/
STDMETHODIMP CStiObj_GetDeviceListW( PV pSti, DWORD dwType, DWORD dwFlags, DWORD *pdwItemsReturned, LPVOID *ppBuffer ) {
HRESULT hres = STIERR_INVALID_PARAM;
EnterProcR(IStillImage::GetDeviceList,(_ "pp", pSti,ppBuffer ));
// Validate passed pointer to interface and obtain pointer to object instance
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
if ( SUCCEEDED(hres = hresFullValidPdwOut_(ppBuffer, s_szProc, 5)) && SUCCEEDED(hres = hresFullValidPdwOut_(pdwItemsReturned, s_szProc, 4)) ) { hres = BuildDeviceListHelper(dwType,dwFlags,pdwItemsReturned,ppBuffer);
if (!SUCCEEDED(hres) ) { FreePpv(ppBuffer); } } }
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_GetDeviceListA( PV pSti, DWORD dwType, DWORD dwFlags, DWORD *pdwItemsReturned, LPVOID *ppBuffer ) {
HRESULT hres = STIERR_INVALID_PARAM;
EnterProcR(IStillImage::GetDeviceList,(_ "pp", pSti,ppBuffer ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
if ( SUCCEEDED(hres = hresFullValidPdwOut_(ppBuffer, s_szProc, 5)) && SUCCEEDED(hres = hresFullValidPdwOut_(pdwItemsReturned, s_szProc, 4)) ) {
LPVOID pvTempBuffer = NULL; UINT uiSize;
hres = BuildDeviceListHelper(dwType,dwFlags,pdwItemsReturned,&pvTempBuffer);
if (SUCCEEDED(hres) ) {
LPSTR pStringDest; PSTI_DEVICE_INFORMATIONA pDest; PSTI_DEVICE_INFORMATIONW pSrc; UINT uiIndex;
//
// Allocate new buffer , transform data into ANSI and free scratch
//
uiSize = (UINT)LocalSize(pvTempBuffer); if (uiSize > 0 && pdwItemsReturned > 0) {
hres = AllocCbPpv(uiSize, ppBuffer); if (SUCCEEDED(hres)) {
pDest = *ppBuffer; pSrc = pvTempBuffer; pStringDest = (LPSTR)(pDest+ *pdwItemsReturned);
for (uiIndex = 0; uiIndex < *pdwItemsReturned; uiIndex++) {
TranslateDeviceInfo(pDest,&pStringDest,pSrc);
pDest++, pSrc++; } } }
FreePpv(&pvTempBuffer); } } }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | GetDeviceInfo | * * @cwrap LPStillImage | lpStillImage * * @parm REFGUID | rguid | * Identifies the instance of the * device for which the indicated interface * is requested. The <mf IStillImage::EnumDevices> method * can be used to determine which instance GUIDs are supported by * the system. * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * *****************************************************************************/
STDMETHODIMP CStiObj_GetDeviceInfoW( PV pSti, LPWSTR pwszDeviceName, LPVOID *ppBuffer ) {
HRESULT hres= STIERR_INVALID_PARAM;
PSTI_DEVICE_INFORMATION pCurrentDevPtr; LPWSTR pwszCurrentString;
EnterProcR(IStillImage::GetDeviceInfo,(_ "ppp", pSti,pwszDeviceName,ppBuffer ));
// Validate passed pointer to interface and obtain pointer to object instance
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
// Get initial buffer for return data
hres = AllocCbPpv(DEVICE_INFO_SIZE, ppBuffer); if (!SUCCEEDED(hres)) { return E_OUTOFMEMORY; }
// Get information on this device calling helper routine
pCurrentDevPtr = (PSTI_DEVICE_INFORMATION)*ppBuffer; pwszCurrentString = (LPWSTR)((LPBYTE)*ppBuffer+DEVICE_INFO_SIZE);
hres=GetDeviceInfoHelper(pwszDeviceName,&pCurrentDevPtr,&pwszCurrentString);
if (!SUCCEEDED(hres)) { FreePpv(ppBuffer); }
}
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_GetDeviceInfoA( PV pSti, LPCSTR pszDeviceName, LPVOID *ppBuffer ) {
HRESULT hres = STIERR_INVALID_PARAM;
EnterProcR(IStillImage::GetDeviceInfo,(_ "ppp", pSti,pszDeviceName,ppBuffer ));
// Validate passed pointer to interface and obtain pointer to object instance
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
WCHAR wszDeviceName[STI_MAX_INTERNAL_NAME_LENGTH] = {L'\0'}; PVOID pBuffer;
AToU(wszDeviceName,STI_MAX_INTERNAL_NAME_LENGTH,pszDeviceName);
hres = CStiObj_GetDeviceInfoW(pSti,wszDeviceName,&pBuffer); if (SUCCEEDED(hres)) {
hres = AllocCbPpv(DEVICE_INFO_SIZE, ppBuffer);
if (SUCCEEDED(hres)) {
LPSTR pStringDest = (LPSTR)*ppBuffer+sizeof(STI_DEVICE_INFORMATIONA);
TranslateDeviceInfo((PSTI_DEVICE_INFORMATIONA)*ppBuffer, &pStringDest, (PSTI_DEVICE_INFORMATIONW)pBuffer);
FreePpv(&pBuffer); } } }
ExitOleProc(); return hres; }
/**************************************************************************\
* PrivateGetDeviceInfoW * * Private server entry point to get WIA device info * * Arguments: * * * * Return Value: * * Status * * History: * * 10/7/1998 Original Version * \**************************************************************************/
STDMETHODIMP StiPrivateGetDeviceInfoHelperW( LPWSTR pwszDeviceName, LPVOID *ppBuffer ) { HRESULT hres = STIERR_INVALID_PARAM; LPWSTR pwszCurrentString;
PSTI_WIA_DEVICE_INFORMATION pCurrentDevPtr;
//
// Get initial buffer for return data
//
hres = AllocCbPpv(WIA_DEVICE_INFO_SIZE, ppBuffer);
if (!SUCCEEDED(hres)) { return E_OUTOFMEMORY; }
//
// Get information on this device calling helper routine
//
pCurrentDevPtr = (PSTI_WIA_DEVICE_INFORMATION)*ppBuffer; pwszCurrentString = (LPWSTR)((LPBYTE)*ppBuffer+WIA_DEVICE_INFO_SIZE);
hres=GetDeviceInfoHelperWIA(pwszDeviceName, &pCurrentDevPtr,&pwszCurrentString);
if (!SUCCEEDED(hres)) { FreePpv(ppBuffer); *ppBuffer = NULL; } else { if (*ppBuffer) { if (OSUtil_StrLenW(((PSTI_WIA_DEVICE_INFORMATION) *ppBuffer)->pszServer) == 0) { //
// Assume that this is not a WIA device, since server name is
// blank.
//
FreePpv(ppBuffer); *ppBuffer = NULL; } else { //
// set size of buffer so buffers can be chained independently
//
if (pCurrentDevPtr) { pCurrentDevPtr->dwSize = WIA_DEVICE_INFO_SIZE; } } } }
return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | SetDeviceValue | * * @cwrap LPStillImage | lpStillImage * * @parm * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * *****************************************************************************/
STDMETHODIMP CStiObj_SetDeviceValueW( PV pSti, LPWSTR pwszDeviceName, LPWSTR pwszValueName, DWORD Type, LPBYTE pData, DWORD cbData ) {
HRESULT hres = STIERR_INVALID_PARAM; HKEY hkeyDevice; LONG dwError;
EnterProcR(IStillImage::SetDeviceValue,(_ "ppp", pSti,pwszDeviceName,pData ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
//
// Open device registry key
//
hres = OpenDeviceRegistryKey(pwszDeviceName,REGSTR_VAL_DATA_W,&hkeyDevice);
if (!SUCCEEDED(hres)) { return hres; }
//
// Implement set value
//
dwError = OSUtil_RegSetValueExW(hkeyDevice, pwszValueName, Type, pData, cbData, (this->dwVersion & STI_VERSION_FLAG_UNICODE) ? TRUE : FALSE); if (hkeyDevice) { RegCloseKey(hkeyDevice); }
hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
}
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_SetDeviceValueA( PV pSti, LPCSTR pszDeviceName, LPCSTR pszValueName, DWORD Type, LPBYTE pData, DWORD cbData ) {
HRESULT hres; HKEY hkeyDevice; LONG dwError;
EnterProcR(IStillImage::SetDeviceValue,(_ "ppp", pSti,pszDeviceName,pData ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
WCHAR wszDeviceName[STI_MAX_INTERNAL_NAME_LENGTH] = {L'\0'}; WCHAR wszValueName[MAX_PATH] = {L'\0'};
AToU(wszDeviceName,STI_MAX_INTERNAL_NAME_LENGTH,pszDeviceName); AToU(wszValueName,MAX_PATH,pszValueName);
//
// Open device registry key
//
hres = OpenDeviceRegistryKey(wszDeviceName,REGSTR_VAL_DATA_W,&hkeyDevice);
if (SUCCEEDED(hres)) {
//
// Implement set value
//
dwError = OSUtil_RegSetValueExW(hkeyDevice, wszValueName, Type, pData, cbData, (this->dwVersion & STI_VERSION_FLAG_UNICODE) ? TRUE : FALSE); if (hkeyDevice) { RegCloseKey(hkeyDevice); }
hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError); }
}
ExitOleProc(); return hres; }
/****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | GetDeviceValue | * * @cwrap LPStillImage | lpStillImage * * @parm * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * *****************************************************************************/
STDMETHODIMP CStiObj_GetDeviceValueW( PV pSti, LPWSTR pwszDeviceName, LPWSTR pwszValueName, LPDWORD pType, LPBYTE pData, LPDWORD pcbData ) {
HRESULT hres = STIERR_INVALID_PARAM;
HKEY hkeyDevice; LONG dwError;
EnterProcR(IStillImage::GetDeviceValue,(_ "ppp", pSti,pwszDeviceName,pData ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
//
// Open device registry key
//
hres = OpenDeviceRegistryKey(pwszDeviceName,REGSTR_VAL_DATA_W,&hkeyDevice);
if (!SUCCEEDED(hres)) { return hres; }
//
// Implement get value
//
dwError = OSUtil_RegQueryValueExW(hkeyDevice, pwszValueName, pType, pData, pcbData, (this->dwVersion & STI_VERSION_FLAG_UNICODE) ? TRUE : FALSE); if (hkeyDevice) { RegCloseKey(hkeyDevice); }
hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
}
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_GetDeviceValueA( PV pSti, LPCSTR pszDeviceName, LPCSTR pszValueName, LPDWORD pType, LPBYTE pData, LPDWORD pcbData ) {
HRESULT hres = STIERR_INVALID_PARAM; HKEY hkeyDevice; LONG dwError;
EnterProcR(IStillImage::GetDeviceValue,(_ "ppp", pSti,pszDeviceName,pData ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
LPWSTR pwszDevName = NULL;
hres = OSUtil_GetWideString(&pwszDevName,pszDeviceName); if (SUCCEEDED(hres)) {
//
// Open device registry key
//
hres = OpenDeviceRegistryKey(pwszDevName,REGSTR_VAL_DATA_W,&hkeyDevice);
if (SUCCEEDED(hres)) {
//
// Implement get value
//
dwError = RegQueryValueExA(hkeyDevice, pszValueName, 0, pType, pData, pcbData); if (hkeyDevice) { RegCloseKey(hkeyDevice); }
hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError); } } }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | GetSTILaunchInformation | * * @cwrap LPStillImage | lpStillImage * * @parm * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * *****************************************************************************/
STDMETHODIMP CStiObj_GetSTILaunchInformationW( PV pSti, WCHAR *pwszDeviceName, DWORD *pdwEventCode, WCHAR *pwszEventName ) {
HRESULT hres = STIERR_INVALID_PARAM;
EnterProcR(IStillImage::GetSTILaunchInformation,(_ "pppp", pSti,pwszDeviceName,pdwEventCode,pwszEventName ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
//
// Parse process command line to check if there is STI information
//
hres = ExtractCommandLineArgumentW("StiDevice",pwszDeviceName); if (SUCCEEDED(hres) ) { hres = ExtractCommandLineArgumentW("StiEvent",pwszEventName); } }
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_GetSTILaunchInformationA( PV pSti, LPSTR pszDeviceName, DWORD *pdwEventCode, LPSTR pszEventName ) {
HRESULT hres = STIERR_INVALID_PARAM;
EnterProcR(IStillImage::GetSTILaunchInformation,(_ "pppp", pSti,pszDeviceName,pdwEventCode,pszEventName ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
hres = ExtractCommandLineArgumentA("StiDevice",pszDeviceName); if (SUCCEEDED(hres) ) { hres = ExtractCommandLineArgumentA("StiEvent",pszEventName); } }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | RegisterLaunchApplication | * * @cwrap LPStillImage | lpStillImage * * @parm * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * *****************************************************************************/
static WCHAR szSTICommandLineTail[] = {L" /StiDevice:%1 /StiEvent:%2"}; static CHAR szSTICommandLineTail_A[] = {" /StiDevice:%1 /StiEvent:%2"};
STDMETHODIMP CStiObj_RegisterLaunchApplicationW( PV pSti, LPWSTR pwszAppName, LPWSTR pwszCommandLine ) {
HRESULT hres = STIERR_INVALID_PARAM; DWORD dwErr = 0;
DWORD dwCommandLineLength, cbNewLength;
LPWSTR pszWide = NULL;
HKEY hkeyApps; CHAR szAppName[MAX_PATH] = {'\0'}; CHAR szCmdLine[MAX_PATH] = {'\0'};
EnterProcR(IStillImage::RegisterLaunchApplication,(_ "ppp", pSti,pwszAppName,pwszCommandLine ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
if (pwszCommandLine && *pwszCommandLine && pwszAppName && *pwszAppName ) {
//
// Add STI formatiing tail to the command line
//
dwCommandLineLength = OSUtil_StrLenW(pwszCommandLine); cbNewLength = ((dwCommandLineLength+1) + OSUtil_StrLenW(szSTICommandLineTail) + 1)*sizeof(WCHAR) ;
hres = AllocCbPpv(cbNewLength, (PPV)&pszWide);
if (pszWide) {
HRESULT hresCom ;
// Need to initialize COM apartment to call WIA event registration
hresCom = CoInitialize(NULL);
OSUtil_lstrcpyW(pszWide,pwszCommandLine); OSUtil_lstrcatW(pszWide,szSTICommandLineTail);
dwErr = OSUtil_RegCreateKeyExW(HKEY_LOCAL_MACHINE, REGSTR_PATH_REG_APPS_W, 0L, NULL, 0L, KEY_ALL_ACCESS, NULL, &hkeyApps, NULL );
if (NOERROR == dwErr ) {
WriteRegistryStringW(hkeyApps, pwszAppName , pszWide, cbNewLength, REG_SZ);
RegCloseKey(hkeyApps); }
//
// Register for standard WIA events on all devices , setting as non default
//
if (WideCharToMultiByte(CP_ACP, 0, pwszAppName, -1, szAppName, MAX_PATH, NULL, NULL)) { if (WideCharToMultiByte(CP_ACP, 0, pszWide, -1, szCmdLine, MAX_PATH, NULL, NULL)) {
hres = RunRegisterProcess(szAppName, szCmdLine); } else { hres = E_FAIL; } } else { hres = E_FAIL; }
FreePpv(&pszWide);
// Balance apartment initiazation
if ((S_OK == hresCom) || (S_FALSE == hresCom)) { CoUninitialize(); }
hres = (dwErr == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwErr);
} else { DebugOutPtszV(DbgFl, TEXT("Could not get unicode string -- out of memory")); hres = E_OUTOFMEMORY; } } else { hres = STIERR_INVALID_PARAM; } }
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_RegisterLaunchApplicationA( PV pSti, LPCSTR pszAppName, LPCSTR pszCommandLine ) {
HRESULT hres = STIERR_INVALID_PARAM; DWORD dwErr = 0;
DWORD dwCommandLineLength, cbNewLength;
LPWSTR pszWide = NULL;
HKEY hkeyApps;
EnterProcR(IStillImage::RegisterLaunchApplication,(_ "ppp", pSti,pszAppName,pszCommandLine ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
// Add STI formatiing tail to the command line
//
if (pszCommandLine && *pszCommandLine && pszAppName && *pszAppName ) {
LPSTR pszBuffer;
// Add STI formatiing tail to the command line
//
dwCommandLineLength = lstrlenA(pszCommandLine); cbNewLength = ((dwCommandLineLength+1) + OSUtil_StrLenW(szSTICommandLineTail) + 1)*sizeof(WCHAR) ;
hres = AllocCbPpv(cbNewLength, (PPV)&pszBuffer);
if (pszBuffer) {
lstrcpyA(pszBuffer,pszCommandLine); UToA(pszBuffer+lstrlenA(pszBuffer), (cbNewLength - dwCommandLineLength), szSTICommandLineTail);
dwErr = RegCreateKeyExA(HKEY_LOCAL_MACHINE, REGSTR_PATH_REG_APPS_A, 0L, NULL, 0L, KEY_ALL_ACCESS, NULL, &hkeyApps, NULL );
if (NOERROR == dwErr ) {
WriteRegistryStringA(hkeyApps, pszAppName , pszBuffer, lstrlenA(pszBuffer)+1, REG_SZ);
RegCloseKey(hkeyApps); }
{ //
// Register for standard WIA events on all devices , setting as non default
//
PVOID pWideCMDLine = NULL; UINT uiSize = (lstrlenA(pszBuffer)+1)*sizeof(WCHAR); CHAR szCmdLine[MAX_PATH] = {'\0'};
//
// Make sure we wont overrun our buffer
//
if ((lstrlenA(szCmdLine) + lstrlenA(szSTICommandLineTail_A) + lstrlenA(" ") + sizeof('\0')) < (MAX_PATH)) {
lstrcatA(szCmdLine, pszCommandLine); lstrcatA(szCmdLine, " "); lstrcatA(szCmdLine, szSTICommandLineTail_A); dwErr = (DWORD) RunRegisterProcess((LPSTR)pszAppName, szCmdLine); } else { dwErr = (DWORD) E_INVALIDARG; } }
FreePpv(&pszBuffer);
hres = (dwErr == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwErr);
} else { DebugOutPtszV(DbgFl,TEXT("Could not get unicode string -- out of memory")); hres = E_OUTOFMEMORY; } } else { hres = STIERR_INVALID_PARAM; } }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | RegisterLaunchApplication | * * @cwrap LPStillImage | lpStillImage * * @parm * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * *****************************************************************************/
STDMETHODIMP CStiObj_UnregisterLaunchApplicationW( PV pSti, LPWSTR pwszAppName ) {
HRESULT hres = STIERR_INVALID_PARAM; DWORD dwErr;
HKEY hkeyApps;
EnterProcR(IStillImage::UnregisterLaunchApplication,(_ "pp", pSti,pwszAppName ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
dwErr = OSUtil_RegOpenKeyExW(HKEY_LOCAL_MACHINE, REGSTR_PATH_REG_APPS_W, 0L, KEY_ALL_ACCESS, &hkeyApps );
if (NOERROR == dwErr ) {
OSUtil_RegDeleteValueW(hkeyApps,pwszAppName);
RegCloseKey(hkeyApps); }
hres = (dwErr == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwErr);
}
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_UnregisterLaunchApplicationA( PV pSti, LPCSTR pszAppName ) {
HRESULT hres = STIERR_INVALID_PARAM; DWORD dwErr;
HKEY hkeyApps;
EnterProcR(IStillImage::UnregisterLaunchApplication,(_ "pp", pSti,pszAppName ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
dwErr = RegOpenKeyExA(HKEY_LOCAL_MACHINE, REGSTR_PATH_REG_APPS_A, 0L, KEY_ALL_ACCESS, &hkeyApps );
if (NOERROR == dwErr ) {
RegDeleteValueA(hkeyApps,pszAppName);
RegCloseKey(hkeyApps); }
hres = (dwErr == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwErr);
}
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | LaunchApplicationForDevice | * * @cwrap LPStillImage | lpStillImage * * @parm * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * *****************************************************************************/
STDMETHODIMP CStiObj_LaunchApplicationForDeviceW( PV pSti, LPWSTR pwszDeviceName, LPWSTR pwszAppName, LPSTINOTIFY pStiNotify ) {
HRESULT hres = STIERR_INVALID_PARAM; DWORD dwError ;
EnterProcR(IStillImage::LaunchApplicationForDevice,(_ "pp", pSti,pwszAppName ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
dwError = RpcStiApiLaunchApplication(NULL, pwszDeviceName, pwszAppName, pStiNotify );
hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError); }
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_LaunchApplicationForDeviceA( PV pSti, LPCSTR pszDeviceName, LPCSTR pszApplicationName, LPSTINOTIFY pStiNotify ) {
HRESULT hres = STIERR_INVALID_PARAM; DWORD dwError;
EnterProcR(IStillImage::LaunchApplicationForDevice,(_ "pp", pSti,pszApplicationName ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
LPWSTR pwszDevName = NULL; LPWSTR pwszAppName = NULL;
hres = OSUtil_GetWideString(&pwszDevName,pszDeviceName); if (SUCCEEDED(hres)) { hres = OSUtil_GetWideString(&pwszAppName,pszApplicationName); if (SUCCEEDED(hres)) {
dwError = RpcStiApiLaunchApplication(NULL, pwszDevName, pwszAppName, pStiNotify );
hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError); } }
FreePpv(&pwszAppName); FreePpv(&pwszDevName); }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | SetupDeviceParameters | * * @cwrap LPStillImage | lpStillImage * * @parm * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * *****************************************************************************/ STDMETHODIMP CStiObj_SetupDeviceParametersW( PV pSti, PSTI_DEVICE_INFORMATIONW pDevInfo ) {
HRESULT hres = STIERR_INVALID_PARAM;
EnterProcR(IStillImage::SetupDeviceParameters,(_ "pp", pSti, pDevInfo));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
hres = SetDeviceInfoHelper(pDevInfo); }
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_SetupDeviceParametersA( PV pSti, PSTI_DEVICE_INFORMATIONA pDevInfo ) {
HRESULT hres = STIERR_INVALID_PARAM;
EnterProcR(IStillImage::SetupDeviceParameters,(_ "pp", pSti, pDevInfo));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
hres = STIERR_UNSUPPORTED; }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | SetupDeviceParameters | * * @cwrap LPStillImage | lpStillImage * * @parm * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * *****************************************************************************/ STDMETHODIMP CStiObj_WriteToErrorLogW( PV pSti, DWORD dwMessageType, LPCWSTR pwszMessage ) {
HRESULT hres = S_OK;
EnterProcR(IStillImage::WriteToErrorLog,(_ "pp", pSti, pwszMessage));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
//
// Validate parameters here
//
if (SUCCEEDED(hres = hresFullValidReadPvCb(pwszMessage,2, 3))) {
#ifndef UNICODE
//
// Since we're ANSI, the ReportStiLogMessage is expecting an ANSI string,
// but our message is UNICODE, so we must convert.
// NOTE: We never expect CStiObj_WriteToErrorLogW to be called if we're compiling
// ANSI, but just in case...
//
LPSTR lpszANSI = NULL;
if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszANSI,pwszMessage))) { ReportStiLogMessage(g_hStiFileLog, dwMessageType, lpszANSI ); FreePpv(&lpszANSI); } #else
ReportStiLogMessage(g_hStiFileLog, dwMessageType, pwszMessage ); #endif
}
}
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_WriteToErrorLogA( PV pSti, DWORD dwMessageType, LPCSTR pszMessage ) { HRESULT hres = S_OK;
EnterProcR(IStillImage::WriteToErrorLog,(_ "pp", pSti, pszMessage));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
//
// Validate parameters here
//
if (SUCCEEDED(hres = hresFullValidReadPvCb(pszMessage,2, 3))) {
#ifndef UNICODE
ReportStiLogMessage(g_hStiFileLog, dwMessageType, pszMessage ); #else
//
// Since we're UNICODE, the ReportStiLogMessage is expecting a WideString,
// but our message is ANSI, so we must convert.
// NOTE: We never expect CStiObj_WriteToErrorLogA to be called if we're compiling
// UNICODE, but just in case...
//
LPWSTR lpwszWide = NULL;
if ( SUCCEEDED(OSUtil_GetWideString(&lpwszWide,pszMessage))) { ReportStiLogMessage(g_hStiFileLog, dwMessageType, lpwszWide ); FreePpv(&lpwszWide); } #endif
}
}
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | | * * * To control state of notification handling. For polled devices this means state of monitor * polling, for true notification devices means enabling/disabling notification flow * from monitor to registered applications * * * @cwrap LPStillImage | lpStillImage * * @parm * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * *****************************************************************************/
STDMETHODIMP CStiObj_EnableHwNotificationsW( PV pSti, LPCWSTR pwszDeviceName, BOOL bNewState) {
HRESULT hres = STIERR_INVALID_PARAM; DWORD dwError = NOERROR;
EnterProcR(IStillImage::CStiObj_EnableHwNotifications,(_ "pp", pSti,pwszDeviceName ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
dwError = RpcStiApiEnableHwNotifications(NULL, pwszDeviceName, bNewState);
hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError); }
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_EnableHwNotificationsA( PV pSti, LPCSTR pszDeviceName, BOOL bNewState) {
HRESULT hres = STIERR_INVALID_PARAM; DWORD dwError = NOERROR;
EnterProcR(IStillImage::CStiObj_EnableHwNotifications,(_ "pp", pSti,pszDeviceName ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
LPWSTR pwszDeviceName=NULL ;
hres = OSUtil_GetWideString(&pwszDeviceName,pszDeviceName);
if (SUCCEEDED(hres)) {
dwError = RpcStiApiEnableHwNotifications(NULL, pwszDeviceName, bNewState);
hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError); }
FreePpv(&pwszDeviceName); }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | | * * * To control state of notification handling. For polled devices this means state of monitor * polling, for true notification devices means enabling/disabling notification flow * from monitor to registered applications * * * @cwrap LPStillImage | lpStillImage * * @parm * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * *****************************************************************************/
STDMETHODIMP CStiObj_GetHwNotificationStateW( PV pSti, LPCWSTR pwszDeviceName, BOOL* pbCurrentState) {
HRESULT hres = STIERR_INVALID_PARAM; DWORD dwError = NOERROR;
EnterProcR(IStillImage::CStiObj_GetHwNotificationState,(_ "pp", pSti,pwszDeviceName ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
dwError = RpcStiApiGetHwNotificationState(NULL, pwszDeviceName, pbCurrentState);
hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
}
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_GetHwNotificationStateA( PV pSti, LPCSTR pszDeviceName, BOOL* pbCurrentState) {
HRESULT hres = STIERR_INVALID_PARAM; DWORD dwError = NOERROR;
EnterProcR(IStillImage::CStiObj_GetHwNotificationState,(_ "pp", pSti,pszDeviceName ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
LPWSTR pwszDeviceName=NULL ;
hres = OSUtil_GetWideString(&pwszDeviceName,pszDeviceName);
if (SUCCEEDED(hres)) {
dwError = RpcStiApiGetHwNotificationState(NULL, pwszDeviceName, pbCurrentState);
hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError); }
FreePpv(&pwszDeviceName); }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | RefreshDeviceBus | * * * When device is installed but not accessible, application may request bus refresh * which in some cases will make device known. This is mainly used for nonPnP buses * like SCSI, when device was powered on after PnP enumeration * * * * * @cwrap LPStillImage | lpStillImage * * @parm * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The * <p ppvOut> parameter is not a valid pointer. * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * *****************************************************************************/
HRESULT WINAPI RefreshDeviceParentHelper( LPCWSTR pwszDeviceName ) {
HRESULT hres; DWORD dwError = NOERROR; CONFIGRET cmRetCode = CR_SUCCESS ;
HANDLE hDevInfo; DEVINST hdevParent;
GUID Guid = GUID_DEVCLASS_IMAGE; DWORD dwRequired; DWORD Idx; SP_DEVINFO_DATA spDevInfoData;
WCHAR szDevDriver[STI_MAX_INTERNAL_NAME_LENGTH];
ULONG cbData;
BOOL fRet; BOOL fFoundDriverNameMatch;
dwRequired = 0; dwError = 0;
//
// Navigating through Setup API set
// As we don't have reverse search to retrive device info handle , based on
// driver name, we do exsaustive search. Number of imaging devices for given class ID
// is never as large to make a problem.
//
//
hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE);
fFoundDriverNameMatch = FALSE;
hres = STIERR_INVALID_DEVICE_NAME;
if (hDevInfo != INVALID_HANDLE_VALUE) {
spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++) {
//
// Compare driver name
//
*szDevDriver = L'\0'; fRet = SetupDiGetDeviceRegistryPropertyW (hDevInfo, &spDevInfoData, SPDRP_DRIVER, NULL, (LPBYTE)szDevDriver, sizeof (szDevDriver), &cbData );
if (fRet && !lstrcmpiW(szDevDriver,pwszDeviceName)) {
fFoundDriverNameMatch = TRUE; break;
}
}
if(fFoundDriverNameMatch) {
//
// Found instance for the device with matching driver name
//
hdevParent = 0;
cmRetCode = CM_Get_Parent(&hdevParent, spDevInfoData.DevInst, 0);
dwError = GetLastError();
if((CR_SUCCESS == cmRetCode) && hdevParent) {
CM_Reenumerate_DevNode(hdevParent,CM_REENUMERATE_NORMAL ); dwError = GetLastError(); }
hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
} else { hres = STIERR_INVALID_DEVICE_NAME; }
//
SetupDiDestroyDeviceInfoList (hDevInfo);
} else {
hres = STIERR_INVALID_DEVICE_NAME;
}
return hres;
}
STDMETHODIMP CStiObj_RefreshDeviceBusW( PV pSti, LPCWSTR pwszDeviceName ) {
HRESULT hres = STIERR_INVALID_PARAM; DWORD dwErr = NOERROR; CONFIGRET cmRetCode = CR_SUCCESS ;
EnterProcR(IStillImage::CStiObj_RefreshDeviceBus,(_ "pp", pSti,pwszDeviceName ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) { PCStiObj this = _thisPvNm(pSti, stiW);
hres = RefreshDeviceParentHelper(pwszDeviceName);
}
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_RefreshDeviceBusA( PV pSti, LPCSTR pszDeviceName ) {
HRESULT hres = STIERR_INVALID_PARAM; DWORD dwError = NOERROR;
EnterProcR(IStillImage::CStiObj_RefreshDeviceBus,(_ "pp", pSti,pszDeviceName ));
//
// Validate passed pointer to interface and obtain pointer to object instance
//
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) { PCStiObj this = _thisPvNm(pSti, stiA);
LPWSTR pwszDeviceName=NULL ;
hres = OSUtil_GetWideString(&pwszDeviceName,pszDeviceName);
if (SUCCEEDED(hres)) { if (pwszDeviceName) { hres = RefreshDeviceParentHelper(pwszDeviceName); FreePpv(&pwszDeviceName); } } }
ExitOleProc(); return hres; }
////////////////////////////////////////////////////////////////////////////////
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | IStillImage | Initialize | * * Initialize a StillImage object. * * The <f StillImageCreate> method automatically * initializes the StillImage object device after creating it. * Applications normally do not need to call this function. * * @cwrap LPStillImage | lpStillImage * * @parm IN HINSTANCE | hinst | * * Instance handle of the application or DLL that is creating * the StillImage object. * * StillImage uses this value to determine whether the * application or DLL has been certified. * * @parm DWORD | dwVersion | * * Version number of the dinput.h header file that was used. * This value must be <c StillImage_VERSION>. * * StillImage uses this value to determine what version of * StillImage the application or DLL was designed for. * * @returns * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c DI_OK> = <c S_OK>: The device is attached. * *****************************************************************************/
STDMETHODIMP CStiObj_InitializeW( PV pSti, HINSTANCE hinst, DWORD dwVersion ) { HRESULT hres; EnterProcR(IStillImage::Initialize, (_ "pxx", pSti, hinst, dwVersion));
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
PCStiObj this = _thisPv(pSti);
if (SUCCEEDED(hres = hresValidInstanceVer(hinst, dwVersion))) { this->dwVersion = dwVersion; }
}
ExitOleProc(); return hres; }
STDMETHODIMP CStiObj_InitializeA( PV pSti, HINSTANCE hinst, DWORD dwVersion ) { HRESULT hres; EnterProcR(IStillImage::Initialize, (_ "pxx", pSti, hinst, dwVersion));
if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
PCStiObj this = _thisPv(pSti);
if (SUCCEEDED(hres = hresValidInstanceVer(hinst, dwVersion))) { this->dwVersion = dwVersion; }
}
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc INTERNAL * * @func void | CStiObj_Finalize | * * Releases the resources of a STI object * * @parm PV | pvObj | * * Object being released. Note that it may not have been * completely initialized, so everything should be done * carefully. * *****************************************************************************/
void INTERNAL CStiObj_Finalize(PV pvObj) {
PCStiObj this = pvObj;
//
// Free COM libraries if connected to them
//
DllUnInitializeCOM();
}
/*****************************************************************************
* * @doc INTERNAL * * @func HRESULT | StiCreateHelper | * * <bnew>This function creates a new StillImage object * which supports the <i IStillImage> COM interface. * * On success, the function returns a pointer to the new object in * *<p lplpSti>. * <enew> * * @parm IN HINSTANCE | hinst | * * Instance handle of the application or DLL that is creating * the Sti object. * * @parm DWORD | dwVersion | * * Version number of the sti.h header file that was used. * This value must be <c STI_VERSION>. * * @parm OUT PPV | ppvObj | * Points to where to return * the pointer to the <i ISti> interface, if successful. * * @parm IN LPUNKNOWN | punkOuter | Pointer to controlling unknown. * * @parm RIID | riid | * * The interface the application wants to create. * * If the object is aggregated, then this parameter is ignored. * * @returns * * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c STI_OK> = <c S_OK>: The operation completed successfully. * * <c STIERR_INVALIDPARAM> * * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>: * Out of memory. * *****************************************************************************/
STDMETHODIMP StiCreateHelper( HINSTANCE hinst, DWORD dwVer, PPV ppvObj, PUNK punkOuter, RIID riid) { HRESULT hres; EnterProc(StiCreateHelper, (_ "xxxG", hinst, dwVer, punkOuter, riid));
hres = CStiObj_New(punkOuter,punkOuter ? &IID_IUnknown : riid, ppvObj);
if (SUCCEEDED(hres) && punkOuter == 0) { PSTI psti = *ppvObj; hres = psti->lpVtbl->Initialize(psti, hinst, dwVer); if (SUCCEEDED(hres)) { } else { Invoke_Release(ppvObj); } }
ExitOleProcPpv(ppvObj); return hres; }
/*****************************************************************************
* * @doc INTERNAL * * @mfunc HRESULT | IStillImage | New | * * Create a new instance of an IStillImage object. * * @parm IN PUNK | punkOuter | * * Controlling unknown for aggregation. * * @parm IN RIID | riid | * Desired interface to new object. * * @parm OUT PPV | ppvObj | * Output pointer for new object. * * @returns * * Standard OLE <t HRESULT>. * *****************************************************************************/
STDMETHODIMP CStiObj_New(PUNK punkOuter, RIID riid, PPV ppvObj) { HRESULT hres; EnterProcR(IStillImage::CreateInstance, (_ "Gp", riid, ppvObj));
hres = Common_NewRiid(CStiObj, punkOuter, riid, ppvObj);
ExitOleProcPpvR(ppvObj); return hres; }
/*****************************************************************************
* * The long-awaited vtbls and templates * *****************************************************************************/
#pragma BEGIN_CONST_DATA
#define CStiObj_Signature (DWORD)'STI'
Interface_Template_Begin(CStiObj) Primary_Interface_Template(CStiObj,TFORM(ThisInterfaceT)) Secondary_Interface_Template(CStiObj, SFORM(ThisInterfaceT)) Interface_Template_End(CStiObj)
Primary_Interface_Begin(CStiObj, TFORM(ThisInterfaceT)) TFORM(CStiObj_Initialize), TFORM(CStiObj_GetDeviceList), TFORM(CStiObj_GetDeviceInfo), TFORM(CStiObj_CreateDevice), TFORM(CStiObj_GetDeviceValue), TFORM(CStiObj_SetDeviceValue), TFORM(CStiObj_GetSTILaunchInformation), TFORM(CStiObj_RegisterLaunchApplication), TFORM(CStiObj_UnregisterLaunchApplication), TFORM(CStiObj_EnableHwNotifications), TFORM(CStiObj_GetHwNotificationState), TFORM(CStiObj_RefreshDeviceBus), TFORM(CStiObj_LaunchApplicationForDevice), TFORM(CStiObj_SetupDeviceParameters), TFORM(CStiObj_WriteToErrorLog) Primary_Interface_End(CStiObj, TFORM(ThisInterfaceT))
Secondary_Interface_Begin(CStiObj,SFORM(ThisInterfaceT), SFORM(sti)) SFORM(CStiObj_Initialize), SFORM(CStiObj_GetDeviceList), SFORM(CStiObj_GetDeviceInfo), SFORM(CStiObj_CreateDevice), SFORM(CStiObj_GetDeviceValue), SFORM(CStiObj_SetDeviceValue), SFORM(CStiObj_GetSTILaunchInformation), SFORM(CStiObj_RegisterLaunchApplication), SFORM(CStiObj_UnregisterLaunchApplication), SFORM(CStiObj_EnableHwNotifications), SFORM(CStiObj_GetHwNotificationState), SFORM(CStiObj_RefreshDeviceBus), SFORM(CStiObj_LaunchApplicationForDevice), SFORM(CStiObj_SetupDeviceParameters), SFORM(CStiObj_WriteToErrorLog) Secondary_Interface_End(CStiObj,SFORM(ThisInterfaceT), SFORM(sti))
|