📄 fakecam.cpp
字号:
/**************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORP., 2000
*
* TITLE: fakecam.cpp
*
* VERSION: 1.0
*
* DATE: 18 July, 2000
*
* DESCRIPTION:
* Fake Camera device implementation
*
* TODO: Every function in this file must be changed so that it actually
* talks to a real camera.
*
***************************************************************************/
#include "pch.h"
//
// Globals
//
HINSTANCE g_hInst;
GUID g_guidUnknownFormat;
//
// Initializes access to the camera and allocates the device info
// structure and private storage area
//
HRESULT WiaMCamInit(MCAM_DEVICE_INFO **ppDeviceInfo)
{
wiauDbgInit(g_hInst);
DBG_FN("WiaMCamInit");
HRESULT hr = S_OK;
//
// Locals
//
MCAM_DEVICE_INFO *pDeviceInfo = NULL;
FAKECAM_DEVICE_INFO *pPrivateDeviceInfo = NULL;
REQUIRE_ARGS(!ppDeviceInfo, hr, "WiaMCamInit");
*ppDeviceInfo = NULL;
//
// Allocate the MCAM_DEVICE_INFO structure
//
pDeviceInfo = new MCAM_DEVICE_INFO;
REQUIRE_ALLOC(pDeviceInfo, hr, "WiaMCamInit");
memset(pDeviceInfo, 0, sizeof(MCAM_DEVICE_INFO));
pDeviceInfo->iSize = sizeof(MCAM_DEVICE_INFO);
pDeviceInfo->iMcamVersion = MCAM_VERSION;
//
// Allocate the FAKECAM_DEVICE_INFO structure that the
// microdriver uses to store info
//
pPrivateDeviceInfo = new FAKECAM_DEVICE_INFO;
REQUIRE_ALLOC(pPrivateDeviceInfo, hr, "WiaMCamInit");
memset(pPrivateDeviceInfo, 0, sizeof(FAKECAM_DEVICE_INFO));
pDeviceInfo->pPrivateStorage = (BYTE *) pPrivateDeviceInfo;
Cleanup:
if (FAILED(hr)) {
if (pDeviceInfo) {
delete pDeviceInfo;
pDeviceInfo = NULL;
}
if (pPrivateDeviceInfo) {
delete pPrivateDeviceInfo;
pPrivateDeviceInfo = NULL;
}
}
*ppDeviceInfo = pDeviceInfo;
return hr;
}
//
// Frees any remaining structures held by the microdriver
//
HRESULT WiaMCamUnInit(MCAM_DEVICE_INFO *pDeviceInfo)
{
DBG_FN("WiaMCamUnInit");
HRESULT hr = S_OK;
if (pDeviceInfo)
{
//
// Free anything that was dynamically allocated in the MCAM_DEVICE_INFO
// structure
//
if (pDeviceInfo->pPrivateStorage) {
delete pDeviceInfo->pPrivateStorage;
pDeviceInfo->pPrivateStorage = NULL;
}
delete pDeviceInfo;
pDeviceInfo = NULL;
}
return hr;
}
//
// Open a connection to the device
//
HRESULT WiaMCamOpen(MCAM_DEVICE_INFO *pDeviceInfo, PWSTR pwszPortName)
{
DBG_FN("WiaMCamOpen");
HRESULT hr = S_OK;
BOOL ret;
//
// Locals
//
TCHAR tszTempStr[MAX_PATH] = TEXT("");
REQUIRE_ARGS(!pDeviceInfo || !pwszPortName, hr, "WiaMCamOpen");
//
// Convert the wide port string to a tstr
//
hr = wiauStrW2T(pwszPortName, tszTempStr, sizeof(tszTempStr));
REQUIRE_SUCCESS(hr, "WiaMCamOpen", "wiauStrW2T failed");
//
// Open the camera
//
hr = FakeCamOpen(tszTempStr, pDeviceInfo);
REQUIRE_SUCCESS(hr, "WiaMCamOpen", "FakeCamOpen failed");
Cleanup:
return hr;
}
//
// Closes the connection with the camera
//
HRESULT WiaMCamClose(MCAM_DEVICE_INFO *pDeviceInfo)
{
DBG_FN("WiaMCamClose");
HRESULT hr = S_OK;
REQUIRE_ARGS(!pDeviceInfo, hr, "WiaMCamClose");
//
// For a real camera, CloseHandle should be called here
//
Cleanup:
return hr;
}
//
// Returns information about the camera, the list of items on the camera,
// and starts monitoring events from the camera
//
HRESULT WiaMCamGetDeviceInfo(MCAM_DEVICE_INFO *pDeviceInfo, MCAM_ITEM_INFO **ppItemList)
{
DBG_FN("WiaMCamGetDeviceInfo");
HRESULT hr = S_OK;
//
// Locals
//
FAKECAM_DEVICE_INFO *pPrivateDeviceInfo = NULL;
PTSTR ptszRootPath = NULL;
REQUIRE_ARGS(!pDeviceInfo || !ppItemList || !pDeviceInfo->pPrivateStorage, hr, "WiaMCamGetDeviceInfo");
*ppItemList = NULL;
pPrivateDeviceInfo = (UNALIGNED FAKECAM_DEVICE_INFO *) pDeviceInfo->pPrivateStorage;
ptszRootPath = pPrivateDeviceInfo->tszRootPath;
//
// Build a list of all items available. The fields in the item info
// structure can either be filled in here, or for better performance
// wait until GetItemInfo is called.
//
hr = SearchDir(pPrivateDeviceInfo, NULL, ptszRootPath);
REQUIRE_SUCCESS(hr, "WiaMCamGetDeviceInfo", "SearchDir failed");
//
// Fill in the MCAM_DEVICE_INFO structure
//
//
// Firmware version should be retrieved from the device, converting
// to WSTR if necessary
//
pDeviceInfo->pwszFirmwareVer = L"04.18.65";
// ISSUE-8/4/2000-davepar Put properties into an INI file
pDeviceInfo->lPicturesTaken = pPrivateDeviceInfo->iNumImages;
pDeviceInfo->lPicturesRemaining = 100 - pDeviceInfo->lPicturesTaken;
pDeviceInfo->lTotalItems = pPrivateDeviceInfo->iNumItems;
GetLocalTime(&pDeviceInfo->Time);
// pDeviceInfo->lExposureMode = EXPOSUREMODE_MANUAL;
// pDeviceInfo->lExposureComp = 0;
*ppItemList = pPrivateDeviceInfo->pFirstItem;
Cleanup:
return hr;
}
//
// Called to retrieve an event from the device
//
HRESULT WiaMCamReadEvent(MCAM_DEVICE_INFO *pDeviceInfo, MCAM_EVENT_INFO **ppEventList)
{
DBG_FN("WiaMCamReadEvent");
HRESULT hr = S_OK;
return hr;
}
//
// Called when events are no longer needed
//
HRESULT WiaMCamStopEvents(MCAM_DEVICE_INFO *pDeviceInfo)
{
DBG_FN("WiaMCamStopEvents");
HRESULT hr = S_OK;
return hr;
}
//
// Fill in the item info structure
//
HRESULT WiaMCamGetItemInfo(MCAM_DEVICE_INFO *pDeviceInfo, MCAM_ITEM_INFO *pItemInfo)
{
DBG_FN("WiaMCamGetItemInfo");
HRESULT hr = S_OK;
//
// This is where the driver should fill in all the fields in the
// ITEM_INFO structure. For this fake driver, the fields are filled
// in by WiaMCamGetDeviceInfo because it's easier.
//
return hr;
}
//
// Frees the item info structure
//
HRESULT WiaMCamFreeItemInfo(MCAM_DEVICE_INFO *pDeviceInfo, MCAM_ITEM_INFO *pItemInfo)
{
DBG_FN("WiaMCamFreeItemInfo");
HRESULT hr = S_OK;
//
// Locals
//
FAKECAM_DEVICE_INFO *pPrivateDeviceInfo = NULL;
REQUIRE_ARGS(!pDeviceInfo || !pItemInfo || !pDeviceInfo->pPrivateStorage, hr, "WiaMCamFreeItemInfo");
if (pItemInfo->pPrivateStorage) {
PTSTR ptszFullName = (PTSTR) pItemInfo->pPrivateStorage;
wiauDbgTrace("WiaMCamFreeItemInfo", "Removing %" WIAU_DEBUG_TSTR, ptszFullName);
delete []ptszFullName;
ptszFullName = NULL;
pItemInfo->pPrivateStorage = NULL;
}
if (pItemInfo->pwszName)
{
delete []pItemInfo->pwszName;
pItemInfo->pwszName = NULL;
}
pPrivateDeviceInfo = (UNALIGNED FAKECAM_DEVICE_INFO *) pDeviceInfo->pPrivateStorage;
hr = RemoveItem(pPrivateDeviceInfo, pItemInfo);
REQUIRE_SUCCESS(hr, "WiaMCamFreeItemInfo", "RemoveItem failed");
if (IsImageType(pItemInfo->pguidFormat)) {
pPrivateDeviceInfo->iNumImages--;
}
pPrivateDeviceInfo->iNumItems--;
delete pItemInfo;
pItemInfo = NULL;
Cleanup:
return hr;
}
//
// Retrieves the thumbnail for an item
//
HRESULT WiaMCamGetThumbnail(MCAM_DEVICE_INFO *pDeviceInfo, MCAM_ITEM_INFO *pItem,
int *pThumbSize, BYTE **ppThumb)
{
DBG_FN("WiaMCamGetThumbnail");
HRESULT hr = S_OK;
//
// Locals
//
PTSTR ptszFullName = NULL;
BYTE *pBuffer = NULL;
LONG ThumbOffset = 0;
REQUIRE_ARGS(!pDeviceInfo || !pItem || !pThumbSize || !ppThumb, hr, "WiaMCamGetThumbnail");
*ppThumb = NULL;
*pThumbSize = 0;
ptszFullName = (PTSTR) pItem->pPrivateStorage;
hr = ReadJpegHdr(ptszFullName, &pBuffer);
REQUIRE_SUCCESS(hr, "WiaMCamGetThumbnail", "ReadJpegHdr failed");
IFD ImageIfd, ThumbIfd;
BOOL bSwap;
hr = ReadExifJpeg(pBuffer, &ImageIfd, &ThumbIfd, &bSwap);
REQUIRE_SUCCESS(hr, "WiaMCamGetThumbnail", "ReadExifJpeg failed");
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)
{
wiauDbgError("WiaMCamGetThumbnail", "Thumbnail not found");
hr = E_FAIL;
goto Cleanup;
}
*ppThumb = new BYTE[*pThumbSize];
REQUIRE_ALLOC(*ppThumb, hr, "WiaMCamGetThumbnail");
memcpy(*ppThumb, pBuffer + APP1_OFFSET + ThumbOffset, *pThumbSize);
Cleanup:
if (pBuffer) {
delete []pBuffer;
}
FreeIfd(&ImageIfd);
FreeIfd(&ThumbIfd);
return hr;
}
//
// Retrieves the data for an item
//
HRESULT WiaMCamGetItemData(MCAM_DEVICE_INFO *pDeviceInfo, MCAM_ITEM_INFO *pItem,
UINT uiState, BYTE *pBuf, DWORD dwLength)
{
DBG_FN("WiaMCamGetItemData");
HRESULT hr = S_OK;
BOOL ret;
//
// Locals
//
PTSTR ptszFullName = NULL;
FAKECAM_DEVICE_INFO *pPrivateDeviceInfo = NULL;
REQUIRE_ARGS(!pDeviceInfo || !pItem || !pDeviceInfo->pPrivateStorage, hr, "WiaMCamGetItemData");
pPrivateDeviceInfo = (UNALIGNED FAKECAM_DEVICE_INFO *) pDeviceInfo->pPrivateStorage;
if (uiState & MCAM_STATE_FIRST)
{
if (pPrivateDeviceInfo->hFile != NULL)
{
wiauDbgError("WiaMCamGetItemData", "File handle is already open");
hr = E_FAIL;
goto Cleanup;
}
ptszFullName = (PTSTR) pItem->pPrivateStorage;
wiauDbgTrace("WiaMCamGetItemData", "Opening %" WIAU_DEBUG_TSTR " for reading", ptszFullName);
pPrivateDeviceInfo->hFile = CreateFile(ptszFullName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
REQUIRE_FILEHANDLE(pPrivateDeviceInfo->hFile, hr, "WiaMCamGetItemData", "CreateFile failed");
}
if (!(uiState & MCAM_STATE_CANCEL))
{
DWORD dwReceived = 0;
if (!pPrivateDeviceInfo->hFile) {
wiauDbgError("WiaMCamGetItemData", "File handle is NULL");
hr = E_FAIL;
goto Cleanup;
}
if (!pBuf) {
wiauDbgError("WiaMCamGetItemData", "Data buffer is NULL");
hr = E_INVALIDARG;
goto Cleanup;
}
ret = ReadFile(pPrivateDeviceInfo->hFile, pBuf, dwLength, &dwReceived, NULL);
REQUIRE_FILEIO(ret, hr, "WiaMCamGetItemData", "ReadFile failed");
if (dwLength != dwReceived)
{
wiauDbgError("WiaMCamGetItemData", "Incorrect amount read %d", dwReceived);
hr = E_FAIL;
goto Cleanup;
}
Sleep(100);
}
if (uiState & (MCAM_STATE_LAST | MCAM_STATE_CANCEL))
{
if (!pPrivateDeviceInfo->hFile) {
wiauDbgError("WiaMCamGetItemData", "File handle is NULL");
hr = E_FAIL;
goto Cleanup;
}
CloseHandle(pPrivateDeviceInfo->hFile);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -