Leaked source code of windows server 2003
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.
 
 
 
 
 
 

339 lines
9.8 KiB

/*******************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORP., 1997
*
* TITLE: DevDlg.Cpp
*
* VERSION: 2.0
*
* AUTHOR: ReedB
*
* DATE: 3 Apr, 1998
*
* DESCRIPTION:
* Implements device dialog UI for WIA devices. These methods execute
* only on the client side.
*
*******************************************************************************/
#include <objbase.h>
#include <stdio.h>
#include <tchar.h>
#include "wia.h"
#include "sti.h"
#include "wiadevd.h"
#include <initguid.h>
#include "wiadevdp.h"
HRESULT GetDeviceExtensionClassID( LPCWSTR pwszUiClassId, LPCTSTR pszCategory, IID &iidClassID )
{
HRESULT hr = E_FAIL;
//
// Make sure all of the parameters are valid
//
if (pwszUiClassId && pszCategory && lstrlenW(pwszUiClassId) && lstrlen(pszCategory))
{
//
// Construct the key name
//
TCHAR szRootKeyName[1024] = {0};
_sntprintf( szRootKeyName, (sizeof(szRootKeyName)/sizeof(szRootKeyName[0])) - 1, TEXT("CLSID\\%ws\\shellex\\%s"), pwszUiClassId, pszCategory );
//
// open the reg key
//
HKEY hKeyRoot = NULL;
DWORD dwResult = RegOpenKeyEx( HKEY_CLASSES_ROOT, szRootKeyName, 0, KEY_READ, &hKeyRoot );
if (ERROR_SUCCESS == dwResult)
{
//
// Get the buffer size
//
TCHAR szClassID[MAX_PATH] = {0};
DWORD dwLength = sizeof(szClassID)/sizeof(szClassID[0]);
//
// Note that we only take the first registry key
//
dwResult = RegEnumKeyEx( hKeyRoot, 0, szClassID, &dwLength, NULL, NULL, NULL, NULL );
if (ERROR_SUCCESS == dwResult)
{
//
// Convert the registry string to a CLSID
//
#if defined(UNICODE)
hr = CLSIDFromString( szClassID, &iidClassID );
#else
WCHAR wszClassID[MAX_PATH] = {0};
MultiByteToWideChar( CP_ACP, 0, szClassID, -1, wszClassID, MAX_PATH );
hr = CLSIDFromString( wszClassID, &iidClassID );
#endif
}
else hr = HRESULT_FROM_WIN32(dwResult);
//
// Close the registry key
//
RegCloseKey(hKeyRoot);
}
else
{
hr = HRESULT_FROM_WIN32(dwResult);
}
}
else
{
hr = E_INVALIDARG;
}
return hr;
}
HRESULT CreateDeviceExtension( LPCWSTR pwszUiClassId, LPCTSTR pszCategory, const IID &iid, void **ppvObject )
{
IID iidClassID = {0};
HRESULT hr = GetDeviceExtensionClassID( pwszUiClassId, pszCategory, iidClassID );
if (SUCCEEDED(hr))
{
hr = CoCreateInstance( iidClassID, NULL, CLSCTX_INPROC_SERVER, iid, ppvObject );
}
return hr;
}
HRESULT GetUiGuidFromWiaItem( IWiaItem *pWiaItem, LPWSTR pwszGuid, size_t nMaxLen )
{
HRESULT hr;
if (pWiaItem && pwszGuid)
{
IWiaPropertyStorage *pWiaPropertyStorage = NULL;
hr = pWiaItem->QueryInterface( IID_IWiaPropertyStorage, (void**)&pWiaPropertyStorage );
if (SUCCEEDED(hr))
{
PROPSPEC ps[1];
PROPVARIANT pv[1];
ps[0].ulKind = PRSPEC_PROPID;
ps[0].propid = WIA_DIP_UI_CLSID;
hr = pWiaPropertyStorage->ReadMultiple(sizeof(ps)/sizeof(ps[0]), ps, pv );
if (SUCCEEDED(hr))
{
if (VT_LPWSTR == pv[0].vt || VT_BSTR == pv[0].vt)
{
lstrcpynW( pwszGuid, pv[0].bstrVal, nMaxLen );
hr = S_OK;
}
FreePropVariantArray( sizeof(pv)/sizeof(pv[0]), pv );
}
pWiaPropertyStorage->Release();
}
}
else
{
hr = E_INVALIDARG;
}
return hr;
}
HRESULT GetDeviceExtensionClassID( IWiaItem *pWiaItem, LPCTSTR pszCategory, IID &iidClassID )
{
WCHAR wszGuid[MAX_PATH] = {0};
HRESULT hr = GetUiGuidFromWiaItem(pWiaItem,wszGuid,sizeof(wszGuid)/sizeof(wszGuid[0]));
if (SUCCEEDED(hr))
{
hr = GetDeviceExtensionClassID( wszGuid, pszCategory, iidClassID );
}
return hr;
}
HRESULT CreateDeviceExtension( IWiaItem *pWiaItem, LPCTSTR pszCategory, const IID &iid, void **ppvObject )
{
WCHAR wszGuid[MAX_PATH] = {0};
HRESULT hr = GetUiGuidFromWiaItem(pWiaItem,wszGuid,sizeof(wszGuid)/sizeof(wszGuid[0]));
if (SUCCEEDED(hr))
{
hr = CreateDeviceExtension( wszGuid, pszCategory, iid, ppvObject );
}
return hr;
}
/*******************************************************************************
*
* InvokeVendorDeviceDlg
*
* DESCRIPTION:
* Helper function which displays the system-supplied device dlg
*
* PARAMETERS:
*
*******************************************************************************/
static HRESULT InvokeSystemDeviceDlg(
IWiaItem __RPC_FAR *This,
DEVICEDIALOGDATA &DeviceDialogData )
{
IWiaUIExtension *pIWiaUIExtension = NULL;
HRESULT hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaUIExtension, (void**)(&pIWiaUIExtension) );
if (SUCCEEDED(hr))
{
//
// The following call will return E_NOTIMPL if it is a device type
// we don't handle in the system UI
//
hr = pIWiaUIExtension->DeviceDialog(&DeviceDialogData);
pIWiaUIExtension->Release();
}
return hr;
}
/*******************************************************************************
*
* InvokeVendorDeviceDlg
*
* DESCRIPTION:
* Helper function which displays the IHV-supplied device dlg
*
* PARAMETERS:
*
*******************************************************************************/
static HRESULT InvokeVendorDeviceDlg(
IWiaItem __RPC_FAR *This,
DEVICEDIALOGDATA &DeviceDialogData )
{
IWiaUIExtension *pIWiaUIExtension = NULL;
HRESULT hr = CreateDeviceExtension( This, SHELLEX_WIAUIEXTENSION_NAME, IID_IWiaUIExtension, (void**)(&pIWiaUIExtension) );
if (SUCCEEDED(hr))
{
//
// The following call will return E_NOTIMPL if the IHV has
// not implemented a custom UI
//
hr = pIWiaUIExtension->DeviceDialog(&DeviceDialogData);
pIWiaUIExtension->Release();
}
else
{
//
// We want to override this return value, so we can
// handle it by showing the system UI as a fallback.
// Basically, we are going to assume a failure to create
// the extension means that the extension doesn't exist.
// We don't do that for the system UI, because if it can't
// load, that is considered a catastrophic failure.
//
hr = E_NOTIMPL;
}
return hr;
}
/*******************************************************************************
*
* IWiaItem_DeviceDlg_Proxy
*
* DESCRIPTION:
* Display device data acquistion UI.
*
* PARAMETERS:
*
*******************************************************************************/
HRESULT _stdcall IWiaItem_DeviceDlg_Proxy(
IWiaItem __RPC_FAR *This,
HWND hwndParent,
LONG lFlags,
LONG lIntent,
LONG *plItemCount,
IWiaItem ***ppIWiaItems)
{
HRESULT hr = E_FAIL;
//
// Make sure we have valid pointer arguments
//
if (!plItemCount || !ppIWiaItems)
{
return E_POINTER;
}
//
// Initialize the OUT arguments
//
*plItemCount = 0;
*ppIWiaItems = NULL;
//
// Verify that this is a root item.
//
LONG lItemType = 0;
hr = This->GetItemType(&lItemType);
if ((FAILED(hr)) || !(lItemType & WiaItemTypeRoot))
{
return E_INVALIDARG;
}
//
// Prepare the struct we will be passing to the function
//
DEVICEDIALOGDATA DeviceDialogData = {0};
DeviceDialogData.cbSize = sizeof(DeviceDialogData);
DeviceDialogData.hwndParent = hwndParent;
DeviceDialogData.pIWiaItemRoot = This;
DeviceDialogData.dwFlags = lFlags;
DeviceDialogData.lIntent = lIntent;
DeviceDialogData.ppWiaItems = *ppIWiaItems;
//
// If the client wants to use the system UI, the order we try to do it in is:
// System UI --> IHV UI
// Otherwise, we do:
// IHV UI --> System UI
//
if (0 == (lFlags & WIA_DEVICE_DIALOG_USE_COMMON_UI))
{
hr = InvokeVendorDeviceDlg( This, DeviceDialogData );
if (E_NOTIMPL == hr)
{
hr = InvokeSystemDeviceDlg( This, DeviceDialogData );
}
}
else
{
hr = InvokeSystemDeviceDlg( This, DeviceDialogData );
if (E_NOTIMPL == hr)
{
hr = InvokeVendorDeviceDlg( This, DeviceDialogData );
}
}
//
// It should return S_OK for success, but who knows?
//
if (SUCCEEDED(hr) && hr != S_FALSE)
{
*ppIWiaItems = DeviceDialogData.ppWiaItems;
*plItemCount = DeviceDialogData.lItemCount;
}
return(hr);
}
/*******************************************************************************
*
* IWiaItem_DeviceDlg_Stub
*
* DESCRIPTION:
* Never called.
*
* PARAMETERS:
*
*******************************************************************************/
HRESULT _stdcall IWiaItem_DeviceDlg_Stub(
IWiaItem __RPC_FAR *This,
HWND hwndParent,
LONG lFlags,
LONG lIntent,
LONG *plItemCount,
IWiaItem ***pIWiaItems)
{
return(S_OK);
}