|
|
/**************************************************************************
* * (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; }
|