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.
 
 
 
 
 
 

338 lines
11 KiB

#include "precomp.h"
//
// WIA data callback implementation
//
STDMETHODIMP_(ULONG) CWiaDataCallback::AddRef()
{
InterlockedIncrement((LONG*)&m_Ref);
return m_Ref;
}
STDMETHODIMP_(ULONG) CWiaDataCallback::Release()
{
if (!InterlockedDecrement((LONG*)&m_Ref)) {
m_Ref++;
delete this;
return(ULONG) 0;
}
return m_Ref;
}
STDMETHODIMP CWiaDataCallback::QueryInterface(REFIID iid, void **ppv)
{
if (!ppv)
return E_INVALIDARG;
*ppv = NULL;
if (IID_IUnknown == iid) {
*ppv = (IUnknown*)this;
AddRef();
return S_OK;
} else if (IID_IWiaDataCallback == iid) {
*ppv = (IWiaDataCallback *)this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
HRESULT CWiaDataCallback::Initialize(HWND hWndOwner,BOOL bShowProgress)
{
m_hwndOwner = hWndOwner;
if (bShowProgress) {
if (NULL == m_pProgDlg) {
m_pProgDlg = new CProgressDlg();
if (!m_pProgDlg) {
return E_OUTOFMEMORY;
}
m_pProgDlg->Initialize(g_hInstance, IDD_PROGRESSDLG);
}
//
// Preload progress title strings
//
m_pszXferFromDevice = LoadResourceString(IDS_PROGRESS_XFER_FROM_DEVICE);
m_pszProcessingData = LoadResourceString(IDS_PROGRESS_PROCESSING_DATA);
m_pszXferToClient = LoadResourceString(IDS_PROGRESS_XFER_TO_CLIENT);
m_bSetTitle = FALSE;
if (!m_pszXferFromDevice || !m_pszProcessingData || !m_pszXferToClient) {
return HRESULT_FROM_WIN32(GetLastError());
}
if (m_pProgDlg->DoModeless(m_hwndOwner, (LPARAM)m_pProgDlg)) {
m_pProgDlg->SetRange(0, 100);
m_pProgDlg->SetPos(0);
m_lCurrentTextUpdate = TITLE_TRANSFERTOCLIENT;
m_pProgDlg->SetTitle(m_pszXferToClient);
} else {
DBG_ERR(("DoModeless Failed to create Progress Dialog"));
}
}
return S_OK;
}
#define WIADSMSG_PROGRESS MSG_USER + 0
STDMETHODIMP CWiaDataCallback::BandedDataCallback(LONG lMessage,LONG lStatus,LONG lPercentComplete,
LONG lOffset,LONG Length,LONG lReserved,
LONG lResLength,BYTE *pData)
{
HRESULT hr = S_OK;
switch (lMessage) {
case IT_MSG_FILE_PREVIEW_DATA_HEADER: // we do nothing with file preview header data
break;
case IT_MSG_DATA_HEADER:
{
PWIA_DATA_CALLBACK_HEADER pHeader = NULL;
pHeader = (PWIA_DATA_CALLBACK_HEADER)pData;
if(pHeader->guidFormatID == WiaImgFmt_MEMORYBMP){
DBG_TRC(("pHeader->guidFormatID = WiaImgFmt_MEMORYBMP"));
m_bBitmapData = TRUE;
} else if(pHeader->guidFormatID == WiaImgFmt_MEMORYBMP){
DBG_TRC(("pHeader->guidFormatID = WiaImgFmt_RAWRGB"));
m_bBitmapData = FALSE;
} else {
DBG_TRC(("pHeader->guidFormatID = (unknown)"));
m_bBitmapData = TRUE;
}
m_MemBlockSize = pHeader->lBufferSize;
DBG_TRC(("CWiaDataCallback::BandedDataCallback(), IT_MSG_DATA_HEADER Reports"));
DBG_TRC(("pHeader->lBufferSize = %d",pHeader->lBufferSize));
DBG_TRC(("pHeader->lPageCount = %d",pHeader->lPageCount));
DBG_TRC(("pHeader->lSize = %d",pHeader->lSize));
//
// if we get a lbuffer size of zero, allocate one for us,
// and maintain the size.
//
DBG_TRC(("MemBlockSize = %d",pHeader->lBufferSize));
if(m_MemBlockSize <= 0){
m_MemBlockSize = (520288 * 2);
DBG_WRN(("CWiaDataCallback::BandedDataCallback(), adjusting MemBlockSize to %d",m_MemBlockSize));
}
if (m_hImage) {
GlobalFree(m_hImage);
m_hImage = NULL;
m_pImage = NULL;
m_ImageSize = 0;
m_SizeTransferred = 0;
}
m_SizeTransferred = 0;
//
// allocate the buffer
//
m_hImage = (HGLOBAL)GlobalAlloc(GHND, m_MemBlockSize);
hr = E_OUTOFMEMORY;
if (m_hImage) {
hr = S_OK;
}
break;
}
case IT_MSG_FILE_PREVIEW_DATA: // we do nothing with file preview data
break;
case IT_MSG_DATA:
{
m_SizeTransferred += Length;
if((LONG)m_SizeTransferred >= m_MemBlockSize){
m_MemBlockSize += (Length * MEMORY_BLOCK_FACTOR);
//
// process allocation into a temp handle, and fail, if allocation
// fails.
//
HGLOBAL hTempMemory = (HGLOBAL)GlobalReAlloc(m_hImage,m_MemBlockSize,LMEM_MOVEABLE);
if(hTempMemory){
m_hImage = hTempMemory;
} else {
if(m_hImage){
GlobalFree(m_hImage);
m_hImage = NULL;
}
return E_OUTOFMEMORY;
}
}
//
// lock memory down
//
m_pImage = (BYTE*)GlobalLock(m_hImage);
if (m_pImage) {
DBG_TRC(("Copying %d into m_pImage (m_hImage = 0x%X, m_pImage = 0x%X) buffer",Length,m_hImage,m_pImage));
memcpy(m_pImage + lOffset, pData, Length);
//
// unlock memory
//
GlobalUnlock(m_hImage);
} else {
DBG_ERR(("Could not lock down m_hImage memory block"));
}
/*
if (Length == 40) {
BITMAPINFOHEADER* pbmi = NULL;
pbmi = (BITMAPINFOHEADER*)pData;
DBG_TRC(("CWiaDataCallback::BandedDataCallback(), Reported BITMAPINFOHEADER from IT_MSG_DATA"));
DBG_TRC(("pbmi->biSize = %d",pbmi->biSize));
DBG_TRC(("pbmi->biSizeImage = %d",pbmi->biSizeImage));
DBG_TRC(("pbmi->biBitCount = %d",pbmi->biBitCount));
DBG_TRC(("pbmi->biClrImportant = %d",pbmi->biClrImportant));
DBG_TRC(("pbmi->biClrUsed = %d",pbmi->biClrUsed));
DBG_TRC(("pbmi->biCompression = %d",pbmi->biCompression));
DBG_TRC(("pbmi->biHeight = %d",pbmi->biHeight));
DBG_TRC(("pbmi->biWidth = %d",pbmi->biWidth));
DBG_TRC(("pbmi->biPlanes = %d",pbmi->biPlanes));
DBG_TRC(("pbmi->biXPelsPerMeter = %d",pbmi->biXPelsPerMeter));
DBG_TRC(("pbmi->biYPelsPerMeter = %d",pbmi->biYPelsPerMeter));
}
*/
if (m_pProgDlg) {
m_lCurrentTextUpdate = TITLE_TRANSFERTOCLIENT;
if(m_lLastTextUpdate != m_lCurrentTextUpdate){
m_lLastTextUpdate = m_lCurrentTextUpdate;
m_pProgDlg->SetTitle(m_pszXferToClient);
}
m_pProgDlg->SetPos(lPercentComplete);
}
}
break;
case IT_MSG_STATUS:
if (m_pProgDlg) {
if (lStatus & IT_STATUS_TRANSFER_FROM_DEVICE) {
m_lCurrentTextUpdate = TITLE_FROMDEVICE;
if(m_lLastTextUpdate != m_lCurrentTextUpdate){
m_lLastTextUpdate = m_lCurrentTextUpdate;
m_pProgDlg->SetTitle(m_pszXferFromDevice);
}
} else if (lStatus & IT_STATUS_PROCESSING_DATA) {
m_lCurrentTextUpdate = TITLE_PROCESSINGDATA;
if(m_lLastTextUpdate != m_lCurrentTextUpdate){
m_lLastTextUpdate = m_lCurrentTextUpdate;
m_pProgDlg->SetTitle(m_pszProcessingData);
}
} else if (lStatus & IT_STATUS_TRANSFER_TO_CLIENT) {
m_lCurrentTextUpdate = TITLE_TRANSFERTOCLIENT;
if(m_lLastTextUpdate != m_lCurrentTextUpdate){
m_lLastTextUpdate = m_lCurrentTextUpdate;
m_pProgDlg->SetTitle(m_pszXferToClient);
}
}
m_pProgDlg->SetPos(lPercentComplete);
}
break;
case IT_MSG_TERMINATION:
if (m_pProgDlg) {
delete m_pProgDlg;
m_pProgDlg = NULL;
}
break;
default:
break;
}
//
// check for user cancel operation
//
if (m_pProgDlg && m_pProgDlg->CheckCancelled()) {
hr = S_FALSE;
}
//
// transfer failed, or user pressed cancel
//
if (FAILED(hr) || S_FALSE == hr) {
if(FAILED(hr)){
DBG_ERR(("CWiaDataCallback::BandedDataCallback(), The transfer failed"));
} else {
DBG_WRN(("CWiaDataCallback::BandedDataCallback(), The user pressed cancel"));
}
if (m_pProgDlg) {
delete m_pProgDlg;
m_pProgDlg = NULL;
}
}
//
// save last hr
//
m_hrLast = hr;
return hr;
}
HRESULT CWiaDataCallback::GetImage(HGLOBAL *phImage,ULONG *pImageSize)
{
if (!phImage)
return E_INVALIDARG;
if (pImageSize)
*pImageSize = 0;
*phImage = NULL;
if (SUCCEEDED(m_hrLast)) {
if (m_bBitmapData) {
//
// we need to adjust any headers, because the height and image size information
// could be incorrect. (this will handle infinite page length devices)
//
BITMAPINFOHEADER *pbmh = NULL;
pbmh = (BITMAPINFOHEADER*)GlobalLock(m_hImage);
if (pbmh) {
// only fix the BITMAPINFOHEADER if height needs to be calculated
if (pbmh->biHeight == 0) {
LONG lPaletteSize = pbmh->biClrUsed * sizeof(RGBQUAD);
LONG lWidthBytes = CalculateWidthBytes(pbmh->biWidth,pbmh->biBitCount);
pbmh->biSizeImage = m_SizeTransferred - lPaletteSize - sizeof(BITMAPINFOHEADER);
pbmh->biHeight = -(LONG)(pbmh->biSizeImage/lWidthBytes); // 0 also means upside down
pbmh->biXPelsPerMeter = 0; // zero out
pbmh->biYPelsPerMeter = 0; // zero out
}
m_lImageHeight = abs(pbmh->biHeight);
m_lImageWidth = abs(pbmh->biWidth);
GlobalUnlock(m_hImage);
}
}
if (pImageSize){
*pImageSize = m_SizeTransferred;
}
*phImage = m_hImage;
//
// reset internal variables, for next data transfer
//
m_hImage = NULL;
m_pImage = NULL;
m_SizeTransferred = 0;
DBG_TRC(("CWiaDataCallback::GetImage(), Returned 0x%X (HANDLE pointer)",*phImage));
}
return m_hrLast;
}
LONG CWiaDataCallback::CalculateWidthBytes(LONG lWidthPixels,LONG lbpp)
{
LONG lWidthBytes = 0;
lWidthBytes = (lWidthPixels * lbpp) + 31;
lWidthBytes = ((lWidthBytes/8) & 0xfffffffc);
return lWidthBytes;
}