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.
 
 
 
 
 
 

1569 lines
45 KiB

/**************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORP., 2001
*
* TITLE: FSCam.cpp
*
* VERSION: 1.0
*
* DATE: 15 Nov, 2000
*
* DESCRIPTION:
* File System Device object function implementations.
*
***************************************************************************/
#include "pch.h"
#include "private.h"
#include "gdiplus.h"
#ifdef USE_SHELLAPI
#include "shlguid.h"
#include "shlobj.h"
#endif
using namespace Gdiplus;
// extern FORMAT_INFO *g_FormatInfo;
// extern UINT g_NumFormatInfo;
//
// Constructor
//
FakeCamera::FakeCamera() :
m_NumImages(0),
m_NumItems(0),
m_hFile(NULL),
m_pIWiaLog(NULL),
m_FormatInfo(NULL),
m_NumFormatInfo(0)
{
}
//
// Destructor
//
FakeCamera::~FakeCamera()
{
if( m_pIWiaLog )
m_pIWiaLog->Release();
}
ULONG FakeCamera::GetImageTypeFromFilename(WCHAR *pFilename, UINT *pFormatCode)
{
WCHAR *pExt;
pExt = wcsrchr(pFilename, L'.');
if( pExt )
{
for(UINT i=0; i<m_NumFormatInfo; i++)
{
if( CSTR_EQUAL == CompareString(LOCALE_SYSTEM_DEFAULT,
NORM_IGNORECASE,
pExt+1,
-1,
m_FormatInfo[i].ExtensionString,
-1))
{
*pFormatCode = i;
return (m_FormatInfo[i].ItemType);
}
}
}
*pFormatCode = 0;
return (m_FormatInfo[0].ItemType);
}
HRESULT GetClsidOfEncoder(REFGUID guidFormatID, CLSID *pClsid = 0)
{
UINT nCodecs = -1;
ImageCodecInfo *pCodecs = 0;
HRESULT hr;
if(!pClsid)
{
return S_FALSE;
}
if (nCodecs == -1)
{
UINT cbCodecs;
GetImageEncodersSize(&nCodecs, &cbCodecs);
if (nCodecs)
{
pCodecs = new ImageCodecInfo [cbCodecs];
if (!pCodecs)
{
return E_OUTOFMEMORY;
}
GetImageEncoders(nCodecs, cbCodecs, pCodecs);
}
}
hr = S_FALSE;
for (UINT i = 0; i < nCodecs; ++i)
{
if (pCodecs[i].FormatID == guidFormatID)
{
// *pClsid = pCodecs[i].Clsid;
memcpy((BYTE *)pClsid, (BYTE *)&(pCodecs[i].Clsid), sizeof(CLSID));
hr = S_OK;
}
}
if( pCodecs )
{
delete [] pCodecs;
}
return hr;
}
BOOL IsFormatSupportedByGDIPlus(REFGUID guidFormatID)
{
UINT nCodecs = -1;
ImageCodecInfo *pCodecs = 0;
BOOL bRet=FALSE;
UINT cbCodecs;
GetImageEncodersSize(&nCodecs, &cbCodecs);
if (nCodecs)
{
pCodecs = new ImageCodecInfo [cbCodecs];
GetImageEncoders(nCodecs, cbCodecs, pCodecs);
}
for (UINT i = 0; i < nCodecs; ++i)
{
if (pCodecs[i].FormatID == guidFormatID)
{
bRet=TRUE;
break;
}
}
if( pCodecs )
{
delete [] pCodecs;
}
return bRet;
}
//
// Initializes access to the camera
//
HRESULT FakeCamera::Open(LPWSTR pPortName)
{
StringCbCopyW(m_RootPath, sizeof(m_RootPath), pPortName);
HRESULT hr = S_OK;
DWORD FileAttr = 0;
if (-1 == (FileAttr = GetFileAttributes(m_RootPath)))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
{
hr = S_OK;
if (!CreateDirectory(m_RootPath, NULL))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("Open, CreateDirectory failed"));
WIAS_LHRESULT(m_pIWiaLog, hr);
return hr;
}
}
else
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("Open, GetFileAttributes failed %S, 0x%08x", m_RootPath, hr));
WIAS_LHRESULT(m_pIWiaLog, hr);
return hr;
}
}
WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL1,("Open, path set to %S", m_RootPath));
return hr;
}
//
// Closes the connection with the camera
//
HRESULT FakeCamera::Close()
{
HRESULT hr = S_OK;
return hr;
}
//
// Returns information about the camera
//
HRESULT FakeCamera::GetDeviceInfo(DEVICE_INFO *pDeviceInfo)
{
CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"FakeCamera::GetDeviceInfo");
HRESULT hr = S_OK;
//
// Build a list of all items available
//
//m_ItemHandles.RemoveAll();
hr = SearchDirEx(&m_ItemHandles, ROOT_ITEM_HANDLE, m_RootPath);
if (FAILED(hr))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetDeviceInfo, SearchDir failed"));
return hr;
}
pDeviceInfo->FirmwareVersion = SysAllocString(L"04.18.65");
// ISSUE-8/4/2000-davepar Put properties into an INI file
pDeviceInfo->PicturesTaken = m_NumImages;
pDeviceInfo->PicturesRemaining = 100 - pDeviceInfo->PicturesTaken;
pDeviceInfo->TotalItems = m_NumItems;
GetLocalTime(&pDeviceInfo->Time);
pDeviceInfo->ExposureMode = EXPOSUREMODE_MANUAL;
pDeviceInfo->ExposureComp = 0;
return hr;
}
//
// Frees the item info structure
//
VOID FakeCamera::FreeDeviceInfo(DEVICE_INFO *pDeviceInfo)
{
if (pDeviceInfo)
{
if (pDeviceInfo->FirmwareVersion)
{
SysFreeString(pDeviceInfo->FirmwareVersion);
pDeviceInfo->FirmwareVersion = NULL;
}
}
}
//
// This function searches a directory on the hard drive for
// items.
//
HRESULT FakeCamera::GetItemList(ITEM_HANDLE *pItemArray)
{
CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"FakeCamera::GetItemList");
HRESULT hr = S_OK;
memcpy(pItemArray, m_ItemHandles.GetData(), sizeof(ITEM_HANDLE) * m_NumItems);
return hr;
}
//
// This function searches a directory on the hard drive for
// items.
//
// ***NOTE:***
// This function assumes that one or more attachments
// associated with an image will be in the same folder
// as the image. So, for example, if an image is found
// in one folder and its attachment is found in a subfolder
// this algorithm will not associate the image with that
// attachment. This is not a serious limitation since
// all cameras store their attachments in the same
// folder as their image.
//
HRESULT FakeCamera::SearchDirEx(ITEM_HANDLE_ARRAY *pItemArray,
ITEM_HANDLE ParentHandle,
LPOLESTR Path)
{
CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"FakeCamera::SearchDirEx");
HRESULT hr = S_OK;
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA FindData;
WCHAR TempStr[MAX_PATH];
FSUSD_FILE_DATA *pFFD_array=NULL;
DWORD dwNumFilesInArray=0;
DWORD dwCurArraySize=0;
//
// Search for everything, except ".", "..", and hidden files, put them in pFFD_array
//
StringCchPrintfW(TempStr, ARRAYSIZE(TempStr), L"%s\\%s", Path, L"*");
WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("SearchDirEx, searching directory %S", TempStr));
memset(&FindData, 0, sizeof(FindData));
hFind = FindFirstFile(TempStr, &FindData);
if (hFind == INVALID_HANDLE_VALUE)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
{
WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchDir, empty directory %S", TempStr));
hr = S_OK;
}
else
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchDir, FindFirstFile failed"));
WIAS_LHRESULT(m_pIWiaLog, hr);
}
goto Cleanup;
}
pFFD_array = (FSUSD_FILE_DATA *)CoTaskMemAlloc(sizeof(FSUSD_FILE_DATA)*FFD_ALLOCATION_INCREMENT);
if( !pFFD_array )
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
dwCurArraySize = FFD_ALLOCATION_INCREMENT;
while (hr == S_OK)
{
if( wcscmp(FindData.cFileName, L".") &&
wcscmp(FindData.cFileName, L"..") &&
!(FindData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) )
{
pFFD_array[dwNumFilesInArray].dwFileAttributes = FindData.dwFileAttributes;
pFFD_array[dwNumFilesInArray].ftFileTime = FindData.ftLastWriteTime;
pFFD_array[dwNumFilesInArray].dwFileSize = FindData.nFileSizeLow;
pFFD_array[dwNumFilesInArray].dwProcessed = 0;
StringCchCopy(pFFD_array[dwNumFilesInArray].cFileName, ARRAYSIZE(pFFD_array[dwNumFilesInArray].cFileName), FindData.cFileName);
dwNumFilesInArray++;
if( (dwNumFilesInArray & (FFD_ALLOCATION_INCREMENT-1)) == (FFD_ALLOCATION_INCREMENT-1) )
{ // Time to allocate more memory
pFFD_array = (FSUSD_FILE_DATA *)CoTaskMemRealloc(pFFD_array, (sizeof(FSUSD_FILE_DATA)*(dwCurArraySize+FFD_ALLOCATION_INCREMENT)));
if( !pFFD_array )
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
dwCurArraySize += FFD_ALLOCATION_INCREMENT;
}
}
memset(&FindData, 0, sizeof(FindData));
if (!FindNextFile(hFind, &FindData))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
if (hr != HRESULT_FROM_WIN32(ERROR_NO_MORE_FILES))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchDir, FindNextFile failed"));
WIAS_LHRESULT(m_pIWiaLog, hr);
goto Cleanup;
}
}
}
FindClose(hFind);
hFind = INVALID_HANDLE_VALUE;
// Now that all names under current directory are in the array, do analysis on them
// 1. Find JPG images and their attachments
ULONG uImageType;
UINT nFormatCode;
ITEM_HANDLE ImageHandle;
for(DWORD i=0; i<dwNumFilesInArray; i++)
{
if( pFFD_array[i].dwProcessed )
continue;
if( !((pFFD_array[i].dwFileAttributes) & FILE_ATTRIBUTE_DIRECTORY))
{
uImageType = GetImageTypeFromFilename(pFFD_array[i].cFileName, &nFormatCode);
if( nFormatCode > m_NumFormatInfo )
{ // Something really weird happened
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("Aborting SearchDirEx, Format index overflow"));
hr = E_FAIL;
goto Cleanup;
}
if( m_FormatInfo[nFormatCode].FormatGuid == WiaImgFmt_JPEG )
{
// Add this item
hr = CreateItemEx(ParentHandle, &(pFFD_array[i]), &ImageHandle, nFormatCode);
if (FAILED(hr))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchDirEx, CreateImage failed"));
goto Cleanup;
}
if (!pItemArray->Add(ImageHandle))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchDir, Add failed"));
hr = E_OUTOFMEMORY;
goto Cleanup;
}
pFFD_array[i].dwProcessed = 1;
ImageHandle->bHasAttachments = FALSE;
m_NumImages ++;
StringCchPrintfW(TempStr, ARRAYSIZE(TempStr), L"%s\\%s", Path, pFFD_array[i].cFileName);
hr = SearchForAttachments(pItemArray, ImageHandle, TempStr, pFFD_array, dwNumFilesInArray);
if (FAILED(hr))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchDir, SearchForAttachments failed"));
goto Cleanup;
}
if (hr == S_OK)
{
ImageHandle->bHasAttachments = TRUE;
}
ImageHandle->bIsFolder = FALSE;
hr = S_OK;
}
}
} // end of JPEG images and attachments
// 2. For other items that are not processed.
for(i=0; i<dwNumFilesInArray; i++)
{
if( pFFD_array[i].dwProcessed )
continue;
if ((pFFD_array[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) // for folder
{
hr = CreateFolderEx(ParentHandle, &(pFFD_array[i]), &ImageHandle);
if (FAILED(hr))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchDirEx, CreateFolder failed"));
goto Cleanup;
}
if (!pItemArray->Add(ImageHandle))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchDirEx, Add failed"));
hr = E_OUTOFMEMORY;
goto Cleanup;
}
StringCchPrintfW(TempStr, ARRAYSIZE(TempStr), L"%s\\%s", Path, pFFD_array[i].cFileName);
hr = SearchDirEx(pItemArray, ImageHandle, TempStr);
if (FAILED(hr))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchDirEx, recursive SearchDir failed"));
goto Cleanup;
}
pFFD_array[i].dwProcessed = 1;
ImageHandle->bHasAttachments = FALSE;
ImageHandle->bIsFolder = TRUE;
}
else
{ // for files
uImageType = GetImageTypeFromFilename(pFFD_array[i].cFileName, &nFormatCode);
#ifdef GDIPLUS_CHECK
if( (ITEMTYPE_IMAGE == uImageType) &&
!IsFormatSupportedByGDIPlus(m_FormatInfo[nFormatCode].FormatGuid))
{
uImageType = ITEMTYPE_FILE; // Force to create non-image item
m_FormatInfo[nFormatCode].ItemType = uImageType;
m_FormatInfo[nFormatCode].FormatGuid = WiaImgFmt_UNDEFINED;
}
#endif
hr = CreateItemEx(ParentHandle, &(pFFD_array[i]), &ImageHandle, nFormatCode);
if (FAILED(hr))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchDirEx, CreateImage failed"));
goto Cleanup;
}
if (!pItemArray->Add(ImageHandle))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchDirEx, Add failed"));
hr = E_OUTOFMEMORY;
goto Cleanup;
}
pFFD_array[i].dwProcessed = 1;
ImageHandle->bHasAttachments = FALSE;
ImageHandle->bIsFolder = FALSE;
if(ITEMTYPE_IMAGE == uImageType)
{
m_NumImages ++;
}
hr = S_OK;
}
}
hr = S_OK;
Cleanup:
if( hFind != INVALID_HANDLE_VALUE )
FindClose(hFind);
if( pFFD_array )
CoTaskMemFree(pFFD_array);
return hr;
}
//
// Searches for attachments to an image item
//
inline BOOL CompareAttachmentStrings(WCHAR *pParentStr, WCHAR *pStr2)
{
WCHAR *pSlash = wcsrchr(pStr2, L'\\');
WCHAR *pStrTmp;
if( pSlash )
pStrTmp = pSlash+1;
else
pStrTmp = pStr2;
if( wcslen(pParentStr) == 8 && wcscmp(pParentStr+4, L"0000") > 0 && wcscmp(pParentStr+4, L"9999") < 0 )
{
if( wcslen(pStrTmp) < 8 )
return FALSE;
return (CSTR_EQUAL == CompareString( LOCALE_SYSTEM_DEFAULT, 0, pParentStr+4, 4, pStrTmp+4, 4) );
}
else
{
WCHAR pStr22[MAX_PATH];
StringCchCopyW(pStr22, ARRAYSIZE(pStr22), pStrTmp);
WCHAR *pDot = wcsrchr(pStr22, L'.');
if(pDot )
*pDot = L'\0';
return (CSTR_EQUAL == CompareString( LOCALE_SYSTEM_DEFAULT, 0, pParentStr, -1, pStr22, -1) );
}
}
HRESULT FakeCamera::SearchForAttachments(ITEM_HANDLE_ARRAY *pItemArray,
ITEM_HANDLE ParentHandle,
LPOLESTR Path,
FSUSD_FILE_DATA *pFFD_Current,
DWORD dwNumOfFiles)
{
CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"FakeCamera::SearchForAttachments");
HRESULT hr = S_FALSE;
int NumAttachments = 0;
//
// Attachment is defined as any non-image item whose extension is different than the parent but
// the filename is the same except the first 4 letters.
//
WCHAR TempStrParent[MAX_PATH];
WCHAR *pTemp;
pTemp = wcsrchr(Path, L'\\');
if (pTemp)
{
StringCchCopyW(TempStrParent, ARRAYSIZE(TempStrParent), pTemp+1);
}
else
{
StringCchCopyW(TempStrParent, ARRAYSIZE(TempStrParent), Path);
}
//
// Chop the extension
//
WCHAR *pDot = wcsrchr(TempStrParent, L'.');
if (pDot)
{
*(pDot) = L'\0';
}
else
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchForAttachments, filename did not contain a dot"));
return E_INVALIDARG;
}
ITEM_HANDLE NonImageHandle;
UINT nFormatCode;
ULONG uImageType;
for(DWORD i=0; i<dwNumOfFiles; i++)
{
if (!(pFFD_Current[i].dwProcessed) && !(pFFD_Current[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
nFormatCode=0;
uImageType = GetImageTypeFromFilename(pFFD_Current[i].cFileName, &nFormatCode);
if( (uImageType != ITEMTYPE_IMAGE) &&
CompareAttachmentStrings(TempStrParent, pFFD_Current[i].cFileName) )
{
hr = CreateItemEx(ParentHandle, &(pFFD_Current[i]), &NonImageHandle, nFormatCode);
if (FAILED(hr))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchForAttachments, CreateItemEx failed"));
return hr;
}
if (!pItemArray->Add(NonImageHandle))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SearchForAttachments, Add failed"));
return E_OUTOFMEMORY;
}
pFFD_Current[i].dwProcessed = 1;
NonImageHandle->bIsFolder = FALSE;
NumAttachments++;
}
}
} // end of FOR loop
if( NumAttachments > 0 )
hr = S_OK;
else
hr = S_FALSE;
return hr;
}
HRESULT FakeCamera::CreateFolderEx(ITEM_HANDLE ParentHandle,
FSUSD_FILE_DATA *pFindData,
ITEM_HANDLE *pFolderHandle)
{
CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"FakeCamera::CreateFolder");
HRESULT hr = S_OK;
if (!pFolderHandle)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateFolder, invalid arg"));
return E_INVALIDARG;
}
*pFolderHandle = new ITEM_INFO;
if (!*pFolderHandle)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateFolder, memory allocation failed"));
return E_OUTOFMEMORY;
}
//
// Initialize the ItemInfo structure
//
ITEM_INFO *pItemInfo = *pFolderHandle;
memset(pItemInfo, 0, sizeof(ITEM_INFO));
//
// Fill in the other item information
//
pItemInfo->Parent = ParentHandle;
pItemInfo->pName = SysAllocString(pFindData->cFileName);
memset(&pItemInfo->Time, 0, sizeof(SYSTEMTIME));
FILETIME ftLocalFileTime;
FileTimeToLocalFileTime(&pFindData->ftFileTime, &ftLocalFileTime);
if (!FileTimeToSystemTime(&ftLocalFileTime, &pItemInfo->Time))
WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateFolder, couldn't convert file time to system time"));
pItemInfo->Format = 0;
pItemInfo->bReadOnly = pFindData->dwFileAttributes & FILE_ATTRIBUTE_READONLY;
pItemInfo->bCanSetReadOnly = TRUE;
pItemInfo->bIsFolder = TRUE;
m_NumItems++;
WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,
("CreateFolder, created folder %S at 0x%08x under 0x%08x",
pFindData->cFileName, pItemInfo, ParentHandle));
return hr;
}
HRESULT FakeCamera::CreateItemEx(ITEM_HANDLE ParentHandle,
FSUSD_FILE_DATA *pFileData,
ITEM_HANDLE *pItemHandle,
UINT nFormatCode)
{
CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"FakeCamera::CreateNonImage");
HRESULT hr = S_OK;
if (!pItemHandle)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateNonImage, invalid arg"));
return E_INVALIDARG;
}
*pItemHandle = new ITEM_INFO;
if (!*pItemHandle )
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateNonImage, memory allocation failed"));
return E_OUTOFMEMORY;
}
//
// The name cannot contain a dot and the name needs to be unique
// wrt the parent image, so replace the dot with an underline character.
//
WCHAR TempStr[MAX_PATH];
StringCchCopyW(TempStr, ARRAYSIZE(TempStr), pFileData->cFileName);
//
// Initialize the ItemInfo structure
//
ITEM_INFO *pItemInfo = *pItemHandle;
memset(pItemInfo, 0, sizeof(ITEM_INFO));
pItemInfo->Format = nFormatCode;
if (nFormatCode) { // if known extension, it will be handled by the format code
WCHAR *pDot = wcsrchr(TempStr, L'.');
if (pDot)
*pDot = L'\0';
}
//
// Fill in the other item information
//
pItemInfo->Parent = ParentHandle;
pItemInfo->pName = SysAllocString(TempStr);
memset(&pItemInfo->Time, 0, sizeof(SYSTEMTIME));
FILETIME ftLocalFileTime;
FileTimeToLocalFileTime(&pFileData->ftFileTime, &ftLocalFileTime);
if (!FileTimeToSystemTime(&ftLocalFileTime, &pItemInfo->Time))
WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateNonImage, couldn't convert file time to system time"));
pItemInfo->Size = pFileData->dwFileSize;
pItemInfo->bReadOnly = pFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY;
pItemInfo->bCanSetReadOnly = TRUE;
pItemInfo->bIsFolder = FALSE;
m_NumItems++;
WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,
("CreateNonImage, created non-image %S at 0x%08x under 0x%08x",
pFileData->cFileName, pItemInfo, ParentHandle));
return hr;
}
//
// Construct the full path name of the item by traversing its parents
//
VOID FakeCamera::ConstructFullName(WCHAR *pFullName, ITEM_INFO *pItemInfo, BOOL bAddExt)
{
if (pItemInfo->Parent)
ConstructFullName(pFullName, pItemInfo->Parent, FALSE);
else
StringCchCopyW(pFullName, MAX_PATH, m_RootPath);
//
// If this item has attachments and we're creating the name for its children,
// don't add its name (it's a repeat of the child's name)
//
WCHAR *pTmp;
if( pItemInfo->Parent && pItemInfo->Parent->bHasAttachments )
{
pTmp = wcsrchr(pFullName, L'\\');
if( pTmp )
{
*pTmp = L'\0';
}
}
StringCchCatW(pFullName, MAX_PATH, L"\\");
StringCchCatW(pFullName, MAX_PATH, pItemInfo->pName);
if (bAddExt)
{
if( pItemInfo->Format > 0 && pItemInfo->Format < (INT)m_NumFormatInfo )
{
StringCchCatW(pFullName, MAX_PATH, L".");
StringCchCatW(pFullName, MAX_PATH, m_FormatInfo[pItemInfo->Format].ExtensionString);
}
}
}
//
// Frees the item info structure
//
VOID FakeCamera::FreeItemInfo(ITEM_INFO *pItemInfo)
{
if (pItemInfo)
{
if (pItemInfo->pName)
{
WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("FreeItemInfo, removing %S", pItemInfo->pName));
SysFreeString(pItemInfo->pName);
pItemInfo->pName = NULL;
}
if (!m_ItemHandles.Remove(pItemInfo))
WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("FreeItemInfo, couldn't remove handle from array"));
if (m_FormatInfo[pItemInfo->Format].ItemType == ITEMTYPE_IMAGE)
{
m_NumImages--;
}
m_NumItems--;
delete pItemInfo;
}
}
//
// Retrieves the thumbnail for an item
//
/*
HRESULT FakeCamera::GetNativeThumbnail(ITEM_HANDLE ItemHandle, int *pThumbSize, BYTE **ppThumb)
{
CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"FakeCamera::GetThumbnail");
HRESULT hr = S_OK;
if (!ppThumb)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetThumbnail, invalid arg"));
return E_INVALIDARG;
}
*ppThumb = NULL;
*pThumbSize = 0;
WCHAR FullName[MAX_PATH];
ConstructFullName(FullName, ItemHandle);
BYTE *pBuffer;
hr = ReadJpegHdr(FullName, &pBuffer);
if (FAILED(hr) || !pBuffer)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetThumbnail, ReadJpegHdr failed"));
return hr;
}
IFD ImageIfd, ThumbIfd;
BOOL bSwap;
hr = ReadExifJpeg(pBuffer, &ImageIfd, &ThumbIfd, &bSwap);
if (FAILED(hr))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetThumbnail, GetExifJpegDimen failed"));
delete []pBuffer;
return hr;
}
LONG ThumbOffset = 0;
for (int count = 0; count < ThumbIfd.Count; count++)
{
if (ThumbIfd.pEntries[count].Tag == TIFF_JPEG_DATA) {
ThumbOffset = ThumbIfd.pEntries[count].Offset;
}
else if (ThumbIfd.pEntries[count].Tag == TIFF_JPEG_LEN) {
*pThumbSize = ThumbIfd.pEntries[count].Offset;
}
}
if (!ThumbOffset || !*pThumbSize)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetThumbnail, thumbnail not found"));
return E_FAIL;
}
*ppThumb = new BYTE[*pThumbSize];
if (!*ppThumb)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetThumbnail, memory allocation failed"));
return E_OUTOFMEMORY;
}
memcpy(*ppThumb, pBuffer + APP1_OFFSET + ThumbOffset, *pThumbSize);
delete []pBuffer;
FreeIfd(&ImageIfd);
FreeIfd(&ThumbIfd);
return hr;
}
*/
HRESULT FakeCamera::CreateThumbnail(ITEM_HANDLE ItemHandle,
int *pThumbSize,
BYTE **ppThumb,
BMP_IMAGE_INFO *pBmpImageInfo)
{
CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"FSCamera::GetThumbnail");
HRESULT hr = S_OK;
GpStatus Status = Gdiplus::Ok;
SizeF gdipSize;
BYTE *pTempBuf=NULL;
CImageStream *pOutStream = NULL;
Image *pImage=NULL, *pThumbnail=NULL;
CLSID ClsidBmpEncoder;
INT iBmpHeadSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
ITEM_INFO *pItemInfo=NULL;
if (!ppThumb)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateThumbnail, invalid arg"));
return E_INVALIDARG;
}
*ppThumb = NULL;
*pThumbSize = 0;
if( S_OK != (hr=GetClsidOfEncoder(ImageFormatBMP, &ClsidBmpEncoder)))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateThumbnail, Cannot get Encode"));
hr = E_FAIL;
goto Cleanup;
}
WCHAR FullName[MAX_PATH];
ConstructFullName(FullName, ItemHandle);
pItemInfo = (ITEM_INFO *)ItemHandle;
pImage = new Image(FullName);
if( !pImage || Gdiplus::ImageTypeBitmap != pImage->GetType() )
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateThumbnail, Cannot get Full GDI+ Image for %S", FullName));
hr = E_FAIL;
goto Cleanup;
}
// Calculate Thumbnail size
Status = pImage->GetPhysicalDimension(&gdipSize);
if (Status != Gdiplus::Ok)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateThumbnail, Failed in GetPhysicalDimension"));
hr = E_FAIL;
goto Cleanup;
}
if( gdipSize.Width < 1.0 || gdipSize.Height < 1.0 )
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateThumbnail, PhysicalDimension abnormal"));
hr = E_FAIL;
goto Cleanup;
}
pItemInfo->Width = (LONG)gdipSize.Width;
pItemInfo->Height = (LONG)gdipSize.Height;
PixelFormat PixFmt = pImage->GetPixelFormat();
pItemInfo->Depth = (PixFmt & 0xFFFF) >> 8; // Cannot assume image is always 24bits/pixel
if( (pItemInfo->Depth) < 24 )
pItemInfo->Depth = 24;
pItemInfo->BitsPerChannel = 8;
pItemInfo->Channels = (pItemInfo->Depth)/(pItemInfo->BitsPerChannel);
if( gdipSize.Width > gdipSize.Height )
{
pBmpImageInfo->Width = 120;
pBmpImageInfo->Height = (INT)(gdipSize.Height*120.0/gdipSize.Width);
pBmpImageInfo->Height = (pBmpImageInfo->Height + 0x3) & (~0x3);
}
else
{
pBmpImageInfo->Height = 120;
pBmpImageInfo->Width = (INT)(gdipSize.Width*120.0/gdipSize.Height);
pBmpImageInfo->Width = (pBmpImageInfo->Width + 0x3 ) & (~0x3);
}
pThumbnail = pImage->GetThumbnailImage(pBmpImageInfo->Width,pBmpImageInfo->Height);
if( !pThumbnail || Gdiplus::ImageTypeBitmap != pThumbnail->GetType() )
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetThumbnail, Cannot get Thumbnail GDI+ Image"));
hr = E_FAIL;
goto Cleanup;
}
if( pImage )
{
delete pImage;
pImage=NULL;
}
#if 0
pThumbnail->Save(L"C:\\thumbdmp.bmp", &ClsidBmpEncoder, NULL);
#endif
//
// Ask GDI+ for the image dimensions, and fill in the
// passed structure
//
Status = pThumbnail->GetPhysicalDimension(&gdipSize);
if (Status != Gdiplus::Ok)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetThumbnail, Failed in GetPhysicalDimension"));
hr = E_FAIL;
goto Cleanup;
}
pBmpImageInfo->Width = (INT) gdipSize.Width;
pBmpImageInfo->Height = (INT) gdipSize.Height;
pBmpImageInfo->ByteWidth = (pBmpImageInfo->Width) << 2;
pBmpImageInfo->Size = pBmpImageInfo->ByteWidth * pBmpImageInfo->Height;
WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("GetThumbnail, W=%d H=%d", pBmpImageInfo->Width, pBmpImageInfo->Height));
if (pBmpImageInfo->Size == 0)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetThumbnail, Thumbnail size is zero"));
hr = E_FAIL;
goto Cleanup;
}
//
// See if the caller passed in a destination buffer, and make sure
// it is big enough.
//
if (*ppThumb) {
if (*pThumbSize < pBmpImageInfo->Size) {
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetThumbnail, Input Buffer too small"));
hr = E_INVALIDARG;
goto Cleanup;
}
}
//
// Otherwise allocate memory for a buffer
//
else
{
pTempBuf = new BYTE[pBmpImageInfo->Size];
if (!pTempBuf)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
*ppThumb = pTempBuf;
}
//
// Create output IStream
//
pOutStream = new CImageStream;
if (!pOutStream) {
hr = E_OUTOFMEMORY;
goto Cleanup;
}
hr = pOutStream->SetBuffer(*ppThumb, pBmpImageInfo->Size, SKIP_BOTHHDR);
if (FAILED(hr)) {
goto Cleanup;
}
//
// Write the Image to the output IStream in BMP format
//
pThumbnail->Save(pOutStream, &ClsidBmpEncoder, NULL);
// pack
DWORD i, k;
for(k=0, i=0; k<(DWORD)(pBmpImageInfo->Size); k+=4, i+=3)
{
(*ppThumb)[i] = (*ppThumb)[k];
(*ppThumb)[i+1] = (*ppThumb)[k+1];
(*ppThumb)[i+2] = (*ppThumb)[k+2];
}
*pThumbSize = ((pBmpImageInfo->Size)>>2)*3;
pBmpImageInfo->Size = *pThumbSize;
Cleanup:
if (FAILED(hr)) {
if (pTempBuf) {
delete []pTempBuf;
pTempBuf = NULL;
*ppThumb = NULL;
*pThumbSize = 0;
}
}
if (pOutStream)
{
pOutStream->Release();
}
if( pImage )
{
delete pImage;
}
if( pThumbnail )
{
delete pThumbnail;
}
return hr;
}
PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp)
{
BITMAP bmp;
PBITMAPINFO pbmi;
WORD cClrBits;
// Retrieve the bitmap's color format, width, and height.
if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))
{
return NULL;
}
// Convert the color format to a count of bits.
cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
if (cClrBits == 1)
cClrBits = 1;
else if (cClrBits <= 4)
cClrBits = 4;
else if (cClrBits <= 8)
cClrBits = 8;
else if (cClrBits <= 16)
cClrBits = 16;
else if (cClrBits <= 24)
cClrBits = 24;
else cClrBits = 32;
// Allocate memory for the BITMAPINFO structure. (This structure
// contains a BITMAPINFOHEADER structure and an array of RGBQUAD
// data structures.)
if (cClrBits != 24)
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * (1<< cClrBits));
// There is no RGBQUAD array for the 24-bit-per-pixel format.
else
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER));
if( !pbmi )
return NULL;
// Initialize the fields in the BITMAPINFO structure.
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = bmp.bmWidth;
pbmi->bmiHeader.biHeight = bmp.bmHeight;
pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
if (cClrBits < 24)
pbmi->bmiHeader.biClrUsed = (1<<cClrBits);
// If the bitmap is not compressed, set the BI_RGB flag.
pbmi->bmiHeader.biCompression = BI_RGB;
// Compute the number of bytes in the array of color
// indices and store the result in biSizeImage.
// For Windows NT/2000, the width must be DWORD aligned unless
// the bitmap is RLE compressed. This example shows this.
// For Windows 95/98, the width must be WORD aligned unless the
// bitmap is RLE compressed.
pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
* pbmi->bmiHeader.biHeight;
// Set biClrImportant to 0, indicating that all of the
// device colors are important.
pbmi->bmiHeader.biClrImportant = 0;
return pbmi;
}
HRESULT FakeCamera::CreateVideoThumbnail(ITEM_HANDLE ItemHandle,
int *pThumbSize,
BYTE **ppThumb,
BMP_IMAGE_INFO *pBmpImageInfo)
{
CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"FSCamera::CreateVideoThumbnail");
HRESULT hr = S_OK;
HBITMAP hBmp=NULL;
PBITMAPINFO pBMI=NULL;
BYTE *pTempBuf=NULL;
#ifdef USE_SHELLAPI
IShellFolder *pDesktop=NULL;
IShellFolder *pFolder=NULL;
ITEMIDLIST *pidlFolder=NULL;
ITEMIDLIST *pidlFile=NULL;
IExtractImage *pExtract=NULL;
SIZE rgSize;
WCHAR *wcsTmp, wcTemp;
DWORD dwPriority, dwFlags;
if (!ppThumb || !pThumbSize || !pBmpImageInfo)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateVideoThumbnail, invalid arg"));
return E_INVALIDARG;
}
*ppThumb = NULL;
*pThumbSize = 0;
WCHAR FullName[MAX_PATH];
ConstructFullName(FullName, ItemHandle);
// Calculate Thumbnail size, BUGBUG
rgSize.cx = 120;
rgSize.cy = 90;
// Get thumbnail using Shell APIs
hr = SHGetDesktopFolder(&pDesktop);
if( S_OK != hr || !pDesktop )
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateVideoThumbnail, Cannot open Desktop"));
goto Cleanup;
}
wcsTmp = wcsrchr(FullName, L'\\');
if( wcsTmp )
{
// wcTemp = *(wcsTmp+1);
*(wcsTmp) = NULL;
}
else
{
hr = E_INVALIDARG;
goto Cleanup;
}
hr = pDesktop->ParseDisplayName(NULL, NULL, FullName, NULL, &pidlFolder, NULL);
if( S_OK != hr || !pidlFolder )
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateVideoThumbnail, Cannot open IDL Folder=%S", FullName));
goto Cleanup;
}
hr = pDesktop->BindToObject(pidlFolder, NULL, IID_IShellFolder, (LPVOID *)&pFolder);
if( S_OK != hr || !pFolder )
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateVideoThumbnail, Cannot bind to Folder=%S", FullName));
goto Cleanup;
}
// *(wcsTmp+1) = wcTemp; // restore the char
hr = pFolder->ParseDisplayName(NULL, NULL, wcsTmp+1, NULL, &pidlFile, NULL);
if( S_OK != hr || !pidlFile )
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateVideoThumbnail, Cannot open IDL File=%S", wcsTmp+1));
goto Cleanup;
}
hr = pFolder->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST *)&pidlFile, IID_IExtractImage, NULL, (LPVOID *)&pExtract);
if( S_OK != hr || !pExtract )
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateVideoThumbnail, Cannot get extract pointer=%S, hr=0x%x", wcsTmp+1, hr));
goto Cleanup;
}
dwFlags = 0;
dwPriority=0;
hr = pExtract->GetLocation(FullName, MAX_PATH, &dwPriority, &rgSize, 0, &dwFlags);
if( S_OK != hr )
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateVideoThumbnail, Failed in GetLocation"));
goto Cleanup;
}
hr = pExtract->Extract(&hBmp);
#else
hBmp = (HBITMAP)LoadImage(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_VIDEO), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
if( !hBmp )
{
hr = HRESULT_FROM_WIN32(::GetLastError());
}
#endif // end of if use ShellAPI
if( S_OK != hr || !hBmp )
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateVideoThumbnail, Cannot extract Image hr=0x%x", hr));
goto Cleanup;
}
pBMI = CreateBitmapInfoStruct(hBmp);
if( !pBMI )
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateVideoThumbnail, Cannot create BitmapInfoStruct"));
goto Cleanup;
}
pBmpImageInfo->Width = pBMI->bmiHeader.biWidth;
pBmpImageInfo->Height = pBMI->bmiHeader.biHeight;
pBmpImageInfo->ByteWidth = ((pBMI->bmiHeader.biWidth * 24 + 31 ) & ~31 ) >> 3;
pBmpImageInfo->Size = pBMI->bmiHeader.biWidth * pBmpImageInfo->Height * 3;
//
// See if the caller passed in a destination buffer, and make sure
// it is big enough.
//
if (*ppThumb) {
if (*pThumbSize < pBmpImageInfo->Size) {
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateVideoThumbnail, Input Buffer too small"));
hr = E_INVALIDARG;
goto Cleanup;
}
}
//
// Otherwise allocate memory for a buffer
//
else
{
pTempBuf = new BYTE[(pBmpImageInfo->ByteWidth)*(pBmpImageInfo->Height)];
if (!pTempBuf)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
*ppThumb = pTempBuf;
*pThumbSize = pBmpImageInfo->Size;
}
//
// Create output buffer
//
if (!GetDIBits(GetDC(NULL), hBmp, 0, (WORD)pBMI->bmiHeader.biHeight, *ppThumb, pBMI, DIB_RGB_COLORS))
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CreateVideoThumbnail, Failed in GetDIBits"));
hr = E_FAIL;
goto Cleanup;
}
#if 0
// pack
DWORD i, k;
for(k=0, i=0; k<(DWORD)(pBmpImageInfo->Size); k+=4, i+=3)
{
pTempBuf[i] = pTempBuf[k];
pTempBuf[i+1] = pTempBuf[k+1];
pTempBuf[i+2] = pTempBuf[k+2];
}
#endif
Cleanup:
if (FAILED(hr)) {
if (pTempBuf) {
delete []pTempBuf;
pTempBuf = NULL;
*ppThumb = NULL;
*pThumbSize = 0;
}
}
if (pBMI)
LocalFree(pBMI);
#ifdef USE_SHELLAPI
if( pDesktop )
pDesktop->Release();
if( pFolder )
pFolder->Release();
if( pidlFolder )
CoTaskMemFree(pidlFolder);
if( pidlFile )
CoTaskMemFree(pidlFile);
if( pExtract )
pExtract->Release();
#endif
if( hBmp )
{
DeleteObject(hBmp);
}
return hr;
}
VOID FakeCamera::FreeThumbnail(BYTE *pThumb)
{
if (pThumb)
{
delete []pThumb;
pThumb = NULL;
}
}
//
// Retrieves the data for an item
//
HRESULT FakeCamera::GetItemData(ITEM_HANDLE ItemHandle, LONG lState,
BYTE *pBuf, DWORD lLength)
{
CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"FakeCamera::GetItemData");
HRESULT hr = S_OK;
if (lState & STATE_FIRST)
{
if (m_hFile != NULL)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetItemData, file handle is already open"));
return E_FAIL;
}
WCHAR FullName[MAX_PATH];
ConstructFullName(FullName, ItemHandle);
m_hFile = CreateFile(FullName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (m_hFile == INVALID_HANDLE_VALUE)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetItemData, CreateFile failed %S", FullName));
WIAS_LHRESULT(m_pIWiaLog, hr);
return hr;
}
}
if (!(lState & STATE_CANCEL))
{
DWORD Received = 0;
if (!ReadFile(m_hFile, pBuf, lLength, &Received, NULL))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetItemData, ReadFile failed"));
WIAS_LHRESULT(m_pIWiaLog, hr);
return hr;
}
if (lLength != Received)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetItemData, incorrect amount read %d", Received));
return E_FAIL;
}
Sleep(100);
}
if (lState & (STATE_LAST | STATE_CANCEL))
{
CloseHandle(m_hFile);
m_hFile = NULL;
}
return hr;
}
//
// Deletes an item
//
HRESULT FakeCamera::DeleteItem(ITEM_HANDLE ItemHandle)
{
CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"FakeCamera::DeleteItem");
HRESULT hr = S_OK;
DWORD dwErr = 0;
WCHAR FullName[MAX_PATH];
ConstructFullName(FullName, ItemHandle);
if( FILE_ATTRIBUTE_DIRECTORY & GetFileAttributes(FullName) )
{
dwErr = RemoveDirectory(FullName);
} else {
dwErr = DeleteFile(FullName);
}
if (!dwErr )
{
hr = HRESULT_FROM_WIN32(::GetLastError());
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("DeleteItem, DeleteFile failed %S", FullName));
WIAS_LHRESULT(m_pIWiaLog, hr);
}
return hr;
}
//
// Captures a new image
//
HRESULT FakeCamera::TakePicture(ITEM_HANDLE *pItemHandle)
{
CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"FakeCamera::TakePicture");
HRESULT hr = S_OK;
if (!pItemHandle)
{
WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("TakePicture, invalid arg"));
return E_INVALIDARG;
}
return hr;
}
//
// See if the camera is active
//
HRESULT
FakeCamera::Status()
{
HRESULT hr = S_OK;
//
// This sample device is always active, but your driver should contact the
// device and return S_FALSE if it's not ready.
//
// if (NotReady)
// return S_FALSE;
return hr;
}
//
// Reset the camera
//
HRESULT FakeCamera::Reset()
{
HRESULT hr = S_OK;
return hr;
}