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.
 
 
 
 
 
 

650 lines
22 KiB

#include "precomp.h"
#include "dsloader.h"
#include <sti.h>
extern IMessageFilter * g_pOldOleMessageFilter;
const DWORD FINDCONTEXT_SIGNATURE = 0x1F2E4C3D;
HINSTANCE g_hInstance;
TW_STATUS g_twStatus;
typedef struct tagFindContext {
DWORD Signature;
IEnumWIA_DEV_INFO *pEnumDevInfo;
}FINDCONTEXT, *PFINDCONTEXT;
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, void* lpReserved)
{
HRESULT hr = S_OK;
DBG_INIT((HINSTANCE)hModule);
switch (dwReason) {
case DLL_PROCESS_ATTACH:
// Disable thread library calls to avoid
// deadlock when we spin up the worker thread
DisableThreadLibraryCalls(hModule);
g_hInstance = hModule;
InitCommonControls();
break;
case DLL_PROCESS_DETACH:
break;
default:
break;
}
return TRUE ;
}
TW_UINT16 APIENTRY ImportedDSEntry(HANDLE hDS,TW_IDENTITY *AppId,TW_UINT32 DG,
TW_UINT16 DT,TW_UINT16 MSG,TW_MEMREF pData)
{
if (MSG != MSG_PROCESSEVENT) {
if(AppId != NULL) {
#ifdef UNICODE
//
// TWAIN only passes ANSI strings. DPRINTF(DM_TRACE,) is expecting TCHARs which are supposed to
// be WCHAR on NT. Conversion here is only for clear debug output, and will
// not be in release builds. (the calling application name is useful for logging)
//
WCHAR szProductName[255];
MultiByteToWideChar(CP_ACP, 0, AppId->ProductName, -1, szProductName, (sizeof(szProductName) / sizeof(szProductName[0])));
DBG_TRC(("[%ws] Sent to TWAIN Source, DG = %X, DT = %X, MSG = %X",szProductName,DG,DT,MSG));
#else
DBG_TRC(("[%s] Sent to TWAIN Source, DG = %X, DT = %X, MSG = %X",AppId->ProductName,DG,DT,MSG));
#endif
}
if (DT == DAT_CAPABILITY) {
if (g_dwDebugFlags & COREDBG_TRACES) {
char szBuf[256];
memset(szBuf,0,sizeof(szBuf));
switch (MSG) {
case MSG_GET:
lstrcpyA(szBuf,"MSG_GET");
break;
case MSG_GETCURRENT:
lstrcpyA(szBuf,"MSG_GETCURRENT");
break;
case MSG_GETDEFAULT:
lstrcpyA(szBuf,"MSG_GETDEFAULT");
break;
case MSG_SET:
lstrcpyA(szBuf,"MSG_SET");
break;
case MSG_RESET:
lstrcpyA(szBuf,"MSG_RESET");
break;
default:
lstrcpyA(szBuf,"MSG_UNKNOWN");
DBG_TRC(("Unknown MSG = %X",MSG));
break;
}
char szBuf2[256];
memset(szBuf2,0,sizeof(szBuf2));
switch (((TW_CAPABILITY*)pData)->Cap) {
case CAP_CUSTOMBASE:
lstrcpyA(szBuf2,"CAP_CUSTOMBASE");
break;
case CAP_XFERCOUNT:
lstrcpyA(szBuf2,"CAP_XFERCOUNT");
break;
case ICAP_COMPRESSION:
lstrcpyA(szBuf2,"ICAP_COMPRESSION");
break;
case ICAP_PIXELTYPE:
lstrcpyA(szBuf2,"ICAP_PIXELTYPE");
break;
case ICAP_UNITS:
lstrcpyA(szBuf2,"ICAP_UNITS");
break;
case ICAP_XFERMECH:
lstrcpyA(szBuf2,"ICAP_XFERMECH");
break;
case CAP_AUTHOR:
lstrcpyA(szBuf2,"CAP_AUTHOR");
break;
case CAP_CAPTION:
lstrcpyA(szBuf2,"CAP_CAPTION");
break;
case CAP_FEEDERENABLED:
lstrcpyA(szBuf2,"CAP_FEEDERENABLED");
break;
case CAP_FEEDERLOADED:
lstrcpyA(szBuf2,"CAP_FEEDERLOADED");
break;
case CAP_TIMEDATE:
lstrcpyA(szBuf2,"CAP_TIMEDATE");
break;
case CAP_SUPPORTEDCAPS:
lstrcpyA(szBuf2,"CAP_SUPPORTEDCAPS");
break;
case CAP_EXTENDEDCAPS:
lstrcpyA(szBuf2,"CAP_EXTENDEDCAPS");
break;
case CAP_AUTOFEED:
lstrcpyA(szBuf2,"CAP_AUTOFEED");
break;
case CAP_CLEARPAGE:
lstrcpyA(szBuf2,"CAP_CLEARPAGE");
break;
case CAP_FEEDPAGE:
lstrcpyA(szBuf2,"CAP_FEEDPAGE");
break;
case CAP_REWINDPAGE:
lstrcpyA(szBuf2,"CAP_REWINDPAGE");
break;
case CAP_INDICATORS:
lstrcpyA(szBuf2,"CAP_INDICATORS");
break;
case CAP_SUPPORTEDCAPSEXT:
lstrcpyA(szBuf2,"CAP_SUPPORTEDCAPSEXT");
break;
case CAP_PAPERDETECTABLE:
lstrcpyA(szBuf2,"CAP_PAPERDETECTABLE");
break;
case CAP_UICONTROLLABLE:
lstrcpyA(szBuf2,"CAP_UICONTROLLABLE");
break;
case CAP_DEVICEONLINE:
lstrcpyA(szBuf2,"CAP_DEVICEONLINE");
break;
case CAP_AUTOSCAN:
lstrcpyA(szBuf2,"CAP_AUTOSCAN");
break;
case CAP_THUMBNAILSENABLED:
lstrcpyA(szBuf2,"CAP_THUMBNAILSENABLED");
break;
case CAP_DUPLEX:
lstrcpyA(szBuf2,"CAP_DUPLEX");
break;
case CAP_DUPLEXENABLED:
lstrcpyA(szBuf2,"CAP_DUPLEXENABLED");
break;
case CAP_ENABLEDSUIONLY:
lstrcpyA(szBuf2,"CAP_ENABLEDSUIONLY");
break;
case CAP_CUSTOMDSDATA:
lstrcpyA(szBuf2,"CAP_CUSTOMDSDATA");
break;
case CAP_ENDORSER:
lstrcpyA(szBuf2,"CAP_ENDORSER");
break;
case CAP_JOBCONTROL:
lstrcpyA(szBuf2,"CAP_JOBCONTROL");
break;
case ICAP_AUTOBRIGHT:
lstrcpyA(szBuf2,"ICAP_AUTOBRIGHT");
break;
case ICAP_BRIGHTNESS:
lstrcpyA(szBuf2,"ICAP_BRIGHTNESS");
break;
case ICAP_CONTRAST:
lstrcpyA(szBuf2,"ICAP_CONTRAST");
break;
case ICAP_CUSTHALFTONE:
lstrcpyA(szBuf2,"ICAP_CUSTHALFTONE");
break;
case ICAP_EXPOSURETIME:
lstrcpyA(szBuf2,"ICAP_EXPOSURETIME");
break;
case ICAP_FILTER:
lstrcpyA(szBuf2,"ICAP_FILTER");
break;
case ICAP_FLASHUSED:
lstrcpyA(szBuf2,"ICAP_FLASHUSED");
break;
case ICAP_GAMMA:
lstrcpyA(szBuf2,"ICAP_GAMMA");
break;
case ICAP_HALFTONES:
lstrcpyA(szBuf2,"ICAP_HALFTONES");
break;
case ICAP_HIGHLIGHT:
lstrcpyA(szBuf2,"ICAP_HIGHLIGHT");
break;
case ICAP_IMAGEFILEFORMAT:
lstrcpyA(szBuf2,"ICAP_IMAGEFILEFORMAT");
break;
case ICAP_LAMPSTATE:
lstrcpyA(szBuf2,"ICAP_LAMPSTATE");
break;
case ICAP_LIGHTSOURCE:
lstrcpyA(szBuf2,"ICAP_LIGHTSOURCE");
break;
case ICAP_ORIENTATION:
lstrcpyA(szBuf2,"ICAP_ORIENTATION");
break;
case ICAP_PHYSICALWIDTH:
lstrcpyA(szBuf2,"ICAP_PHYSICALWIDTH");
break;
case ICAP_PHYSICALHEIGHT:
lstrcpyA(szBuf2,"ICAP_PHYSICALHEIGHT");
break;
case ICAP_SHADOW:
lstrcpyA(szBuf2,"ICAP_SHADOW");
break;
case ICAP_FRAMES:
lstrcpyA(szBuf2,"ICAP_FRAMES");
break;
case ICAP_XNATIVERESOLUTION:
lstrcpyA(szBuf2,"ICAP_XNATIVERESOLUTION");
break;
case ICAP_YNATIVERESOLUTION:
lstrcpyA(szBuf2,"ICAP_YNATIVERESOLUTION");
break;
case ICAP_XRESOLUTION:
lstrcpyA(szBuf2,"ICAP_XRESOLUTION");
break;
case ICAP_YRESOLUTION:
lstrcpyA(szBuf2,"ICAP_YRESOLUTION");
break;
case ICAP_MAXFRAMES:
lstrcpyA(szBuf2,"ICAP_MAXFRAMES");
break;
case ICAP_TILES:
lstrcpyA(szBuf2,"ICAP_TILES");
break;
case ICAP_BITORDER:
lstrcpyA(szBuf2,"ICAP_BITORDER");
break;
case ICAP_CCITTKFACTOR:
lstrcpyA(szBuf2,"ICAP_CCITTKFACTOR");
break;
case ICAP_LIGHTPATH:
lstrcpyA(szBuf2,"ICAP_LIGHTPATH");
break;
case ICAP_PIXELFLAVOR:
lstrcpyA(szBuf2,"ICAP_PIXELFLAVOR");
break;
case ICAP_PLANARCHUNKY:
lstrcpyA(szBuf2,"ICAP_PLANARCHUNKY");
break;
case ICAP_ROTATION:
lstrcpyA(szBuf2,"ICAP_ROTATION");
break;
case ICAP_SUPPORTEDSIZES:
lstrcpyA(szBuf2,"ICAP_SUPPORTEDSIZES");
break;
case ICAP_THRESHOLD:
lstrcpyA(szBuf2,"ICAP_THRESHOLD");
break;
case ICAP_XSCALING:
lstrcpyA(szBuf2,"ICAP_XSCALING");
break;
case ICAP_YSCALING:
lstrcpyA(szBuf2,"ICAP_YSCALING");
break;
case ICAP_BITORDERCODES:
lstrcpyA(szBuf2,"ICAP_BITORDERCODES");
break;
case ICAP_PIXELFLAVORCODES:
lstrcpyA(szBuf2,"ICAP_PIXELFLAVORCODES");
break;
case ICAP_JPEGPIXELTYPE:
lstrcpyA(szBuf2,"ICAP_JPEGPIXELTYPE");
break;
case ICAP_TIMEFILL:
lstrcpyA(szBuf2,"ICAP_TIMEFILL");
break;
case ICAP_BITDEPTH:
lstrcpyA(szBuf2,"ICAP_BITDEPTH");
break;
case ICAP_BITDEPTHREDUCTION:
lstrcpyA(szBuf2,"ICAP_BITDEPTHREDUCTION");
break;
case ICAP_UNDEFINEDIMAGESIZE:
lstrcpyA(szBuf2,"ICAP_UNDEFINEDIMAGESIZE");
break;
case ICAP_IMAGEDATASET:
lstrcpyA(szBuf2,"ICAP_IMAGEDATASET");
break;
case ICAP_EXTIMAGEINFO:
lstrcpyA(szBuf2,"ICAP_EXTIMAGEINFO");
break;
case ICAP_MINIMUMHEIGHT:
lstrcpyA(szBuf2,"ICAP_MINIMUMHEIGHT");
break;
case ICAP_MINIMUMWIDTH:
lstrcpyA(szBuf2,"ICAP_MINIMUMWIDTH");
break;
default:
lstrcpyA(szBuf2,"(undefined or new CAP)");
break;
}
DBG_TRC(("DAT_CAPABILITY operation, %s on CAP = %s (%x)",szBuf,szBuf2,((TW_CAPABILITY*)pData)->Cap));
}
}
}
CWiaDataSrc *pDataSrc;
pDataSrc = (CWiaDataSrc *)hDS;
if (pDataSrc) {
return pDataSrc->DSEntry(AppId, DG, DT, MSG, pData);
}
return TWRC_FAILURE;
}
TW_UINT16 APIENTRY FindFirstImportDS(PIMPORT_DSINFO pDSInfo,PVOID *Context)
{
DBG_TRC(("FindFirstImportDS - CoInitialize"));
::CoInitialize(NULL);
if (!pDSInfo || pDSInfo->Size < sizeof(IMPORT_DSINFO) ||
!Context) {
g_twStatus.ConditionCode = TWCC_BADVALUE;
return TWRC_FAILURE;
}
HRESULT hr;
IWiaDevMgr *pWiaDevMgr;
TW_UINT16 twRc;
*Context = NULL;
g_twStatus.ConditionCode = TWCC_OPERATIONERROR;
//
// Presume guilty
//
twRc = TWRC_FAILURE;
//
// Get IWiaDevMgr interface
//
hr = CoCreateInstance(CLSID_WiaDevMgr, NULL,
CLSCTX_LOCAL_SERVER,
IID_IWiaDevMgr,
(void**)&pWiaDevMgr
);
if (SUCCEEDED(hr)) {
//
// Get IEnumWIA_DEV_INFO interface.
// This interface pointer will be saved as part
// of the find context.
//
IEnumWIA_DEV_INFO *pEnumDevInfo = NULL;
hr = pWiaDevMgr->EnumDeviceInfo(0, &pEnumDevInfo);
//
// We do not need the IWiaDevMgr interface anymore. The reference count
// on the IEnumWIA_DEV_INFO will keep the WIA Device Manager
// alive.
//
pWiaDevMgr->Release();
if (SUCCEEDED(hr)) {
//
// Make sure the current position is reset to the begining.
//
pEnumDevInfo->Reset();
//
// Create a new find context
//
PFINDCONTEXT pFindContext;
pFindContext = new FINDCONTEXT;
if (pFindContext) {
pFindContext->pEnumDevInfo = pEnumDevInfo;
pFindContext->Signature = FINDCONTEXT_SIGNATURE;
//
// This gets the first available data source
//
twRc = FindNextImportDS(pDSInfo, pFindContext);
if (TWRC_SUCCESS == twRc) {
*Context = pFindContext;
} else {
//
// The callers will not call CloseFindContext
// if FindFirstContext failed. For this reason
// we have to delete the find context here
//
delete pFindContext;
pFindContext = NULL;
}
} else {
//
// set TWAIN condition code to TWCC_LOWMEMORY
// because we failed to allocate pFindContext
//
g_twStatus.ConditionCode = TWCC_LOWMEMORY;
}
}
//
// release IEnumWIA_DEV_INFO interface when finished
//
/*
if (pEnumDevInfo) {
pEnumDevInfo->Release();
pEnumDevInfo = NULL;
if(*Context){
PFINDCONTEXT pFindContext;
pFindContext = (PFINDCONTEXT)*Context;
pFindContext->pEnumDevInfo = NULL;
}
}
*/
}
return twRc;
}
TW_UINT16 APIENTRY FindNextImportDS(PIMPORT_DSINFO pDSInfo,PVOID Context)
{
PFINDCONTEXT pFindContext;
pFindContext = (PFINDCONTEXT)Context;
if (!pDSInfo || pDSInfo->Size < sizeof(IMPORT_DSINFO) ||
!pFindContext || FINDCONTEXT_SIGNATURE != pFindContext->Signature ||
!pFindContext->pEnumDevInfo) {
g_twStatus.ConditionCode = TWCC_BADVALUE;
return TWRC_FAILURE;
}
HRESULT hr = S_OK;
TW_UINT16 twRc = TWRC_FAILURE;
g_twStatus.ConditionCode = TWCC_OPERATIONERROR;
IWiaPropertyStorage *piwps = NULL;
DWORD Count = 0;
while (S_OK == pFindContext->pEnumDevInfo->Next(1, &piwps, &Count)) {
PROPSPEC propSpec;
PROPVARIANT propVar;
propSpec.ulKind = PRSPEC_PROPID;
propSpec.propid = WIA_DIP_DEV_ID;
propVar.vt = VT_BSTR;
hr = piwps->ReadMultiple(1, &propSpec, &propVar);
if (SUCCEEDED(hr)) {
DBG_TRC(("Found Device ID %ws", propVar.bstrVal));
//
// LPOLESTR == LPWSTR. We have to convert the device id
// from UNICODE to ANSI
//
WideCharToMultiByte(CP_ACP, 0, propVar.bstrVal, -1,pDSInfo->DeviceName,
sizeof(pDSInfo->DeviceName) / sizeof(pDSInfo->DeviceName[0]),NULL, NULL);
//
// Remember this or lose memory.
//
SysFreeString(propVar.bstrVal);
//
// Get device type
//
pDSInfo->DeviceFlags &= ~DEVICE_FLAGS_DEVICETYPE;
PropVariantInit(&propVar);
propSpec.propid = WIA_DIP_DEV_TYPE;
hr = piwps->ReadMultiple(1, &propSpec, &propVar);
piwps->Release();
if (SUCCEEDED(hr)) {
switch (GET_STIDEVICE_TYPE(propVar.ulVal)) {
case StiDeviceTypeDigitalCamera:
pDSInfo->DeviceFlags |= DEVICETYPE_DIGITALCAMERA;
break;
case StiDeviceTypeScanner:
pDSInfo->DeviceFlags |= DEVICETYPE_SCANNER;
break;
case StiDeviceTypeStreamingVideo:
pDSInfo->DeviceFlags |= DEVICETYPE_STREAMINGVIDEO;
break;
default:
pDSInfo->DeviceFlags |= DEVICETYPE_UNKNOWN;
}
//
// All our data sources share the same load/unload function
//
pDSInfo->pfnLoadDS = LoadImportDS;
pDSInfo->pfnUnloadDS = UnloadImportDS;
return TWRC_SUCCESS;
} else {
DBG_TRC(("Unable to get DEV_TYPE, hr = %lx", hr));
pDSInfo->DeviceFlags |= DEVICETYPE_UNKNOWN;
}
}
//
// Keep looking
//
}
//
// We are out of data sources.
//
return TWRC_ENDOFLIST;
}
TW_UINT16 APIENTRY CloseFindContext(PVOID Context)
{
PFINDCONTEXT pFindContext;
pFindContext = (PFINDCONTEXT)Context;
if (!pFindContext || FINDCONTEXT_SIGNATURE != pFindContext->Signature) {
g_twStatus.ConditionCode = TWCC_BADVALUE;
return TWRC_FAILURE;
}
if (pFindContext->pEnumDevInfo) {
pFindContext->pEnumDevInfo->Release();
pFindContext->pEnumDevInfo = NULL;
}
delete pFindContext;
DBG_TRC(("CloseFindContext - CoUnIntialize()"));
::CoUninitialize();
return TWRC_SUCCESS;
}
TW_UINT16 APIENTRY LoadImportDS(LPCSTR DeviceName,DWORD DeviceFlags,HANDLE *phDS,
PFNIMPORTEDDSENTRY *pdsEntry)
{
DBG_TRC(("LoadImportDS - CoInitialize()"));
::CoInitialize(NULL);
if (!DeviceName || !phDS || !pdsEntry) {
g_twStatus.ConditionCode = TWCC_BADVALUE;
return TWRC_FAILURE;
}
*phDS = NULL;
*pdsEntry = NULL;
//
// Create Data source
//
CWiaDataSrc *pDS;
if (DEVICETYPE_DIGITALCAMERA == (DeviceFlags & DEVICE_FLAGS_DEVICETYPE)) {
pDS = new CWiaCameraDS;
} else if (DEVICETYPE_SCANNER == (DeviceFlags & DEVICE_FLAGS_DEVICETYPE)) {
pDS = new CWiaScannerDS;
} else if (DEVICETYPE_STREAMINGVIDEO == (DeviceFlags & DEVICE_FLAGS_DEVICETYPE)) {
pDS = new CWiaVideoDS;
} else {
//
// Unknown device type
//
g_twStatus.ConditionCode = TWCC_BUMMER;
return TWRC_FAILURE;
}
TW_UINT16 twCc = TWRC_SUCCESS;
if (pDS) {
//
// Initialize the data source
//
#ifdef UNICODE
WCHAR DeviceNameW[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, DeviceName, -1, DeviceNameW,sizeof(DeviceNameW) / sizeof(DeviceNameW[0]));
twCc = pDS->IWiaDataSrc(DeviceNameW);
#else
twCc = pDS->IWiaDataSrc(DeviceName);
#endif
if (TWCC_SUCCESS != twCc) {
delete pDS;
pDS = NULL;
g_twStatus.ConditionCode = twCc;
return TWRC_FAILURE;
}
*phDS = (HANDLE)pDS;
*pdsEntry = ImportedDSEntry;
return TWRC_SUCCESS;
} else {
g_twStatus.ConditionCode = TWCC_LOWMEMORY;
return TWRC_FAILURE;
}
}
TW_UINT16 APIENTRY UnloadImportDS(HANDLE hDS)
{
CWiaDataSrc *pDS;
pDS = (CWiaDataSrc *)hDS;
if (pDS) {
delete pDS;
DBG_TRC(("UnloadImportDS - CoUnInitialize()"));
::CoUninitialize();
return TWRC_SUCCESS;
}
g_twStatus.ConditionCode = TWCC_BUMMER;
return TWRC_FAILURE;
}
TW_UINT16 APIENTRY GetLoaderStatus(TW_STATUS *ptwStatus)
{
if (!ptwStatus) {
g_twStatus.ConditionCode = TWCC_BADVALUE;
return TWRC_FAILURE;
}
*ptwStatus = g_twStatus;
return TWRC_SUCCESS;
}
TW_UINT16 APIENTRY FindImportDSByDeviceName(PIMPORT_DSINFO pDSInfo,LPCSTR DeviceName)
{
if (!pDSInfo || pDSInfo->Size < sizeof(IMPORT_DSINFO) ||
!DeviceName) {
g_twStatus.ConditionCode = TWCC_BADVALUE;
return TWRC_FAILURE;
}
PVOID Context;
TW_UINT16 twRc = TWRC_ENDOFLIST;
if (TWRC_SUCCESS == FindFirstImportDS(pDSInfo, &Context)) {
do {
if (!_strcmpi(DeviceName, pDSInfo->DeviceName)) {
twRc = TWRC_SUCCESS;
break;
}
}while (TWRC_SUCCESS == FindNextImportDS(pDSInfo, Context));
CloseFindContext(Context);
}
return twRc;
}