📄 fakecam.cpp
字号:
pPrivateDeviceInfo->hFile = NULL;
}
Cleanup:
return hr;
}
//
// Deletes an item
//
HRESULT WiaMCamDeleteItem(MCAM_DEVICE_INFO *pDeviceInfo, MCAM_ITEM_INFO *pItem)
{
DBG_FN("WiaMCamDeleteItem");
HRESULT hr = S_OK;
BOOL ret;
//
// Locals
//
DWORD dwFileAttr = 0;
PTSTR ptszFullName = NULL;
REQUIRE_ARGS(!pDeviceInfo || !pItem, hr, "WiaMCamDeleteItem");
ptszFullName = (PTSTR) pItem->pPrivateStorage;
dwFileAttr = GetFileAttributes(ptszFullName);
REQUIRE_FILEIO(dwFileAttr != -1, hr, "WiaMCamDeleteItem", "GetFileAttributes failed");
dwFileAttr |= FILE_ATTRIBUTE_HIDDEN;
ret = SetFileAttributes(ptszFullName, dwFileAttr);
REQUIRE_FILEIO(ret, hr, "WiaMCamDeleteItem", "SetFileAttributes failed");
wiauDbgTrace("WiaMCamDeleteItem", "File %" WIAU_DEBUG_TSTR " is now hidden", ptszFullName);
Cleanup:
return hr;
}
//
// Sets the protection for an item
//
HRESULT WiaMCamSetItemProt(MCAM_DEVICE_INFO *pDeviceInfo, MCAM_ITEM_INFO *pItem, BOOL bReadOnly)
{
DBG_FN("WiaMCamSetItemProt");
HRESULT hr = S_OK;
BOOL ret;
//
// Locals
//
DWORD dwFileAttr = 0;
PTSTR ptszFullName = NULL;
REQUIRE_ARGS(!pDeviceInfo || !pItem, hr, "WiaMCamSetItemProt");
ptszFullName = (PTSTR) pItem->pPrivateStorage;
dwFileAttr = GetFileAttributes(ptszFullName);
REQUIRE_FILEIO(dwFileAttr != -1, hr, "WiaMCamSetItemProt", "GetFileAttributes failed");
if (bReadOnly)
dwFileAttr |= FILE_ATTRIBUTE_READONLY;
else
dwFileAttr &= ~FILE_ATTRIBUTE_READONLY;
ret = SetFileAttributes(ptszFullName, dwFileAttr);
REQUIRE_FILEIO(ret, hr, "WiaMCamSetItemProt", "SetFileAttributes failed");
wiauDbgTrace("WiaMCamSetItemProt", "Protection on file %" WIAU_DEBUG_TSTR " set to %d", ptszFullName, bReadOnly);
Cleanup:
return hr;
}
//
// Captures a new image
//
HRESULT WiaMCamTakePicture(MCAM_DEVICE_INFO *pDeviceInfo, MCAM_ITEM_INFO **ppItem)
{
DBG_FN("WiaMCamTakePicture");
HRESULT hr = S_OK;
REQUIRE_ARGS(!pDeviceInfo || !ppItem, hr, "WiaMCamTakePicture");
*ppItem = NULL;
Cleanup:
return hr;
}
//
// See if the camera is active
//
HRESULT WiaMCamStatus(MCAM_DEVICE_INFO *pDeviceInfo)
{
DBG_FN("WiaMCamStatus");
HRESULT hr = S_OK;
REQUIRE_ARGS(!pDeviceInfo, hr, "WiaMCamStatus");
//
// 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;
Cleanup:
return hr;
}
//
// Reset the camera
//
HRESULT WiaMCamReset(MCAM_DEVICE_INFO *pDeviceInfo)
{
DBG_FN("WiaMCamReset");
HRESULT hr = S_OK;
REQUIRE_ARGS(!pDeviceInfo, hr, "WiaMCamReset");
Cleanup:
return hr;
}
////////////////////////////////
//
// Helper functions
//
////////////////////////////////
//
// This function pretends to open a camera. A real driver
// would call CreateDevice.
//
HRESULT FakeCamOpen(PTSTR ptszPortName, MCAM_DEVICE_INFO *pDeviceInfo)
{
DBG_FN("FakeCamOpen");
HRESULT hr = S_OK;
BOOL ret = FALSE;
//
// Locals
//
FAKECAM_DEVICE_INFO *pPrivateDeviceInfo = NULL;
DWORD dwFileAttr = 0;
PTSTR ptszRootPath = NULL;
UINT uiRootPathSize = 0;
TCHAR tszPathTemplate[] = TEXT("%userprofile%\\image");
//
// Get a pointer to the private storage, so we can put the
// directory name there
//
pPrivateDeviceInfo = (UNALIGNED FAKECAM_DEVICE_INFO *) pDeviceInfo->pPrivateStorage;
ptszRootPath = pPrivateDeviceInfo->tszRootPath;
uiRootPathSize = sizeof(pPrivateDeviceInfo->tszRootPath) / sizeof(pPrivateDeviceInfo->tszRootPath[0]);
//
// Unless the port name is set to something other than COMx,
// LPTx, or AUTO, use %userprofile%\image as the search directory.
// Since driver runs in LOCAL SERVICE context, %userprofile% points to profile
// of LOCAL SERVICE account, like "Documents and Settings\Local Service"
//
if (_tcsstr(ptszPortName, TEXT("COM")) ||
_tcsstr(ptszPortName, TEXT("LPT")) ||
CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, ptszPortName, -1, TEXT("AUTO"), -1) == CSTR_EQUAL)
{
DWORD dwResult = ExpandEnvironmentStrings(tszPathTemplate, ptszRootPath, uiRootPathSize);
if (dwResult == 0 || dwResult > uiRootPathSize)
{
wiauDbgError("WiaMCamOpen", "ExpandEnvironmentStrings failed");
hr = E_FAIL;
goto Cleanup;
}
}
else
{
lstrcpyn(ptszRootPath, ptszPortName, uiRootPathSize);
}
wiauDbgTrace("Open", "Image directory path is %" WIAU_DEBUG_TSTR, ptszRootPath);
dwFileAttr = GetFileAttributes(ptszRootPath);
if (dwFileAttr == -1)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
{
hr = S_OK;
ret = CreateDirectory(ptszRootPath, NULL);
REQUIRE_FILEIO(ret, hr, "Open", "CreateDirectory failed");
}
else
{
wiauDbgErrorHr(hr, "Open", "GetFileAttributes failed");
goto Cleanup;
}
}
Cleanup:
return hr;
}
/*++
Routine Name: CheckEexifSignature (local, used only by SearchDir below)
Routine Description: checks the first 4 BYTEs in the specified file for a JPEG EEXIF 2.0 signature
Arguments: the file name path
Return Value: S_OK if the file appears to be a valid EEXIF 2.0, S_FALSE if not
Last Error: -
++*/
HRESULT
CheckEexifSignature(
IN LPCTSTR szFileName
)
{
//
// Check if this file is not an older format JFIF (we cannot read these) or any other file that we cannot read.
// Open temporarily the file and look for the 0xFF 0xD8 0xFF 0xE1 at the beginning of the file
// (this is the first identifier for an EEXIF file; JFIFs use as the 4th character 0xE0 instead).
// For better safety (avoid loading an invalid file) all first 6 BYTEs from the file are read.
//
HRESULT hr = S_FALSE;
HANDLE hFile = INVALID_HANDLE_VALUE;
const BYTE EexifHdr[] = {0xFF, 0xD8, 0xFF, 0xE1};
const int nEexifHdrSize = sizeof(EexifHdr) + 2;
BYTE tempBuf[nEexifHdrSize];
ULONG nBytesRead = 0;
hFile = CreateFile(szFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if(INVALID_HANDLE_VALUE != hFile)
{
if(ReadFile(hFile, tempBuf, nEexifHdrSize, &nBytesRead, NULL))
{
if(nBytesRead == nEexifHdrSize)
{
if(!memcmp(tempBuf, EexifHdr, sizeof(EexifHdr)))
{
//
// This appears to be a valid EEXIF file:
//
hr = S_OK;
}
}
}
if(hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(hFile);
}
}
return hr;
}
//
// This function searches a directory on the hard drive for
// items.
//
HRESULT SearchDir(FAKECAM_DEVICE_INFO *pPrivateDeviceInfo, MCAM_ITEM_INFO *pParent, PTSTR ptszPath)
{
DBG_FN("SearchDir");
HRESULT hr = S_OK;
//
// Locals
//
HANDLE hFind = NULL;
WIN32_FIND_DATA FindData;
const cchTempStrSize = MAX_PATH;
TCHAR tszTempStr[cchTempStrSize] = TEXT("");
TCHAR tszFullName[MAX_PATH] = TEXT("");;
MCAM_ITEM_INFO *pFolder = NULL;
MCAM_ITEM_INFO *pImage = NULL;
REQUIRE_ARGS(!pPrivateDeviceInfo || !ptszPath, hr, "SearchDir");
//
// Search for folders first
//
//
// Make sure search path fits into the buffer and gets zero-terminated
//
if (_sntprintf(tszTempStr, cchTempStrSize, _T("%s\\*"), ptszPath) < 0)
{
wiauDbgError("SearchDir", "Too long path for search");
hr = E_FAIL;
goto Cleanup;
}
tszTempStr[cchTempStrSize - 1] = 0;
wiauDbgTrace("SearchDir", "Searching directory %" WIAU_DEBUG_TSTR, tszTempStr);
memset(&FindData, 0, sizeof(FindData));
hFind = FindFirstFile(tszTempStr, &FindData);
if (hFind == INVALID_HANDLE_VALUE)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
{
hr = S_OK;
wiauDbgWarning("SearchDir", "Directory %" WIAU_DEBUG_TSTR " is empty", tszTempStr);
goto Cleanup;
}
else
{
wiauDbgErrorHr(hr, "SearchDir", "FindFirstFile failed");
goto Cleanup;
}
}
while (hr == S_OK)
{
if ((FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
(FindData.cFileName[0] != L'.'))
{
hr = MakeFullName(tszFullName, sizeof(tszFullName) / sizeof(tszFullName[0]),
ptszPath, FindData.cFileName);
REQUIRE_SUCCESS(hr, "SearchDir", "MakeFullName failed");
hr = CreateFolder(pPrivateDeviceInfo, pParent, &FindData, &pFolder, tszFullName);
REQUIRE_SUCCESS(hr, "SearchDir", "CreateFolder failed");
hr = AddItem(pPrivateDeviceInfo, pFolder);
REQUIRE_SUCCESS(hr, "SearchDir", "AddItem failed");
hr = SearchDir(pPrivateDeviceInfo, pFolder, tszFullName);
REQUIRE_SUCCESS(hr, "SearchDir", "Recursive SearchDir failed");
}
memset(&FindData, 0, sizeof(FindData));
if (!FindNextFile(hFind, &FindData))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
if (hr != HRESULT_FROM_WIN32(ERROR_NO_MORE_FILES))
{
wiauDbgErrorHr(hr, "SearchDir", "FindNextFile failed");
goto Cleanup;
}
}
}
FindClose(hFind);
hr = S_OK;
//
// Search next for JPEGs
//
// Note: only EEXIF files are supported (JFIF files are not)
//
//
// Make sure search path fits into the buffer and gets zero-terminated
//
if (_sntprintf(tszTempStr, cchTempStrSize, _T("%s\\*.jpg"), ptszPath) < 0)
{
wiauDbgError("SearchDir", "Too long path for search");
hr = E_FAIL;
goto Cleanup;
}
tszTempStr[cchTempStrSize - 1] = 0;
memset(&FindData, 0, sizeof(FindData));
hFind = FindFirstFile(tszTempStr, &FindData);
if (hFind == INVALID_HANDLE_VALUE)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
{
hr = S_OK;
wiauDbgWarning("SearchDir", "No JPEGs in directory %" WIAU_DEBUG_TSTR, tszTempStr);
goto Cleanup;
}
else
{
wiauDbgErrorHr(hr, "SearchDir", "FindFirstFile failed");
goto Cleanup;
}
}
while (hr == S_OK)
{
if (!(FindData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
{
hr = MakeFullName(tszFullName, sizeof(tszFullName) / sizeof(tszFullName[0]),
ptszPath, FindData.cFileName);
REQUIRE_SUCCESS(hr, "SearchDir", "MakeFullName failed");
//
// Check if this *.jpg file is not an older format JFIF (we cannot read these).
// Open temporarily the file and look for the 0xFF 0xD8 0xFF 0xE1 at the beginning of the file
// (this is the first identifier for an EEXIF file; JFIFs use as the 4th character 0xE0 instead).
//
if(S_OK == CheckEexifSignature(tszFullName))
{
//
// This is EEXIF, proceed:
//
hr = CreateImage(pPrivateDeviceInfo, pParent, &FindData, &pImage, tszFullName);
REQUIRE_SUCCESS(hr, "SearchDir", "CreateImage failed");
hr = AddItem(pPrivateDeviceInfo, pImage);
REQUIRE_SUCCESS(hr, "SearchDir", "AddItem failed");
hr = SearchForAttachments(pPrivateDeviceInfo, pImage, tszFullName);
REQUIRE_SUCCESS(hr, "SearchDir", "SearchForAttachments failed");
if(hr == S_OK)
{
pImage->bHasAttachments = TRUE;
}
hr = S_OK;
}
}
memset(&FindData, 0, sizeof(FindData));
if (!FindNextFile(hFind, &FindData))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
if (hr != HRESULT_FROM_WIN32(ERROR_NO_MORE_FILES))
{
wiauDbgErrorHr(hr, "SearchDir", "FindNextFile failed");
goto Cleanup;
}
}
}
FindClose(hFind);
hr = S_OK;
//
// ISSUE-10/18/2000-davepar Do the same for other image types
//
Cleanup:
return hr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -