├── libcore ├── libcore.rc ├── stdafx.cpp ├── targetver.h ├── stdafx.h ├── resource.h ├── dllmain.cpp ├── libcore.cpp ├── libcore.vcxproj.filters ├── libcore.vcxproj ├── libcamerads.cpp └── libcameramf.cpp ├── camera-cmd ├── camera-cmd.rc ├── mediainfo.h ├── fnames.h ├── proppage.h ├── issyscam.h ├── flash.h ├── privacy.h ├── stdafx.cpp ├── stdafx.h ├── targetver.h ├── common.h ├── resource.h ├── appcontext.h ├── common.cpp ├── proppage.cpp ├── fnames.cpp ├── issyscam.cpp ├── mediainfo.cpp ├── camera-cmd.vcxproj.filters ├── privacy.cpp ├── flash.cpp ├── main.cpp └── camera-cmd.vcxproj ├── appveyor.yml ├── include ├── libcontextbase.h ├── libcore.h ├── sdktrace.h └── libcamera.h ├── LICENSE.md ├── win32-camera-tools.sln ├── README.md ├── .gitignore └── etw └── jytrace.h /libcore/libcore.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flowerinthenight/windows-camera-tools/HEAD/libcore/libcore.rc -------------------------------------------------------------------------------- /camera-cmd/camera-cmd.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flowerinthenight/windows-camera-tools/HEAD/camera-cmd/camera-cmd.rc -------------------------------------------------------------------------------- /camera-cmd/mediainfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | int DispatchMediaInfo(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext); -------------------------------------------------------------------------------- /camera-cmd/fnames.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | int DispatchFriendlyNames(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext); -------------------------------------------------------------------------------- /camera-cmd/proppage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | int DispatchPropertyPage(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext); -------------------------------------------------------------------------------- /camera-cmd/issyscam.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | int IsSystemCamera(wchar_t *pszFname, BOOL *pIsSysCam); 11 | int DispatchIsSystemCamera(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext); -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | 3 | branches: 4 | only: 5 | - master 6 | 7 | os: Visual Studio 2015 8 | 9 | install: 10 | - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 11 | 12 | build_script: 13 | - msbuild win32-camera-tools.sln /p:Platform=x86 14 | -------------------------------------------------------------------------------- /camera-cmd/flash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | int SetupFlash(wchar_t *pszFname, wchar_t *pszState, BOOL bSetFlash); 11 | int DispatchFlash(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext); -------------------------------------------------------------------------------- /camera-cmd/privacy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | int SetupPrivacy(wchar_t *pszFname, wchar_t *pszState, BOOL bSetPrivacy); 11 | int DispatchPrivacy(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext); -------------------------------------------------------------------------------- /libcore/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // libcore.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /camera-cmd/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // camera-cmd.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /camera-cmd/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | #define DEFAULT_ERROR -1 -------------------------------------------------------------------------------- /camera-cmd/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /libcore/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /camera-cmd/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | void ErrorCom(HRESULT hr, TCHAR *pszExtra); 15 | std::vector &split(const std::wstring &s, wchar_t delim, std::vector &elems); -------------------------------------------------------------------------------- /include/libcontextbase.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | class Context { 11 | public: 12 | Context() 13 | { 14 | InitializeCriticalSection(&m_csLock); 15 | } 16 | 17 | ~Context() 18 | { 19 | DeleteCriticalSection(&m_csLock); 20 | } 21 | 22 | public: 23 | CRITICAL_SECTION m_csLock; 24 | }; -------------------------------------------------------------------------------- /libcore/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | // Windows Header Files: 12 | #include 13 | 14 | #define M L"LIBCORE" 15 | -------------------------------------------------------------------------------- /libcore/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by libcore.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /camera-cmd/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by camera-cmd.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /camera-cmd/appcontext.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include "..\include\libcontextbase.h" 9 | 10 | class CContext : public Context { 11 | public: 12 | CContext() : 13 | m_subparamstart(0), 14 | m_pCmdSupported(NULL), 15 | m_argc(0), 16 | m_ppargv(NULL), 17 | m_cchlen(0) 18 | {} 19 | 20 | ~CContext() {} 21 | 22 | public: 23 | size_t m_subparamstart; 24 | BOOL *m_pCmdSupported; 25 | int m_argc; 26 | wchar_t **m_ppargv; 27 | size_t m_cchlen; 28 | }; -------------------------------------------------------------------------------- /libcore/dllmain.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #include "stdafx.h" 7 | #include 8 | #include "..\etw\jytrace.h" 9 | 10 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) 11 | { 12 | switch (dwReason) 13 | { 14 | case DLL_PROCESS_ATTACH: 15 | EventUnregisterJyTrace(); 16 | break; 17 | 18 | case DLL_PROCESS_DETACH: 19 | EventUnregisterJyTrace(); 20 | break; 21 | 22 | case DLL_THREAD_ATTACH: 23 | case DLL_THREAD_DETACH: 24 | break; 25 | } 26 | 27 | return TRUE; 28 | } -------------------------------------------------------------------------------- /camera-cmd/common.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #include "stdafx.h" 7 | #include "common.h" 8 | #include 9 | using namespace std; 10 | 11 | void ErrorCom(HRESULT hr, TCHAR *pszExtra) 12 | { 13 | _com_error err(hr); 14 | LPCTSTR szErrorText = err.ErrorMessage(); 15 | TCHAR szDump[MAX_PATH]; 16 | StringCchPrintf(szDump, 100, L"Error %s: %s (hr = 0x%x)\n", pszExtra, szErrorText, hr); 17 | _tprintf(szDump); 18 | } 19 | 20 | vector &split(const wstring &s, wchar_t delim, vector &elems) 21 | { 22 | wstringstream ss(s); 23 | wstring item; 24 | 25 | while (std::getline(ss, item, delim)) 26 | { 27 | elems.push_back(item); 28 | } 29 | 30 | return elems; 31 | } -------------------------------------------------------------------------------- /include/libcore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | _declspec(dllexport) void PrintComError(HRESULT hr, wchar_t *pszExtra); 14 | _declspec(dllexport) HRESULT GetComTextError(HRESULT hr, wchar_t *pszOut, DWORD *pcchLen); 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | template void SafeRelease(T **ppT) 20 | { 21 | if (*ppT) 22 | { 23 | (*ppT)->Release(); 24 | *ppT = NULL; 25 | } 26 | } 27 | 28 | #define SAFE_RELEASE(ptr) \ 29 | { \ 30 | if (ptr) \ 31 | { \ 32 | (ptr)->Release(); \ 33 | (ptr) = NULL; \ 34 | } \ 35 | } 36 | 37 | typedef int(*FnDispatchParam)(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext); 38 | 39 | typedef struct __ARG_DISPATCH_TABLE { 40 | wchar_t szParam[MAX_PATH]; 41 | FnDispatchParam pfnDispatch; 42 | } ARG_DISPATCH_TABLE, *PARG_DISPATCH_TABLE; -------------------------------------------------------------------------------- /libcore/libcore.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #include "stdafx.h" 7 | #include 8 | #include 9 | #include 10 | #include "..\include\libcore.h" 11 | 12 | _declspec(dllexport) void PrintComError(HRESULT hr, TCHAR *pszExtra) 13 | { 14 | _com_error err(hr); 15 | LPCTSTR szErrorText = err.ErrorMessage(); 16 | TCHAR szDump[MAX_PATH]; 17 | StringCchPrintf(szDump, 100, L"%s: %s (0x%x)\n", pszExtra, szErrorText, hr); 18 | OutputDebugString(szDump); 19 | } 20 | 21 | _declspec(dllexport) HRESULT GetComTextError(HRESULT hr, wchar_t *pszOut, DWORD *pcchLen) 22 | { 23 | if (!pcchLen) return E_INVALIDARG; 24 | if (*pcchLen < 1) return E_INVALIDARG; 25 | 26 | TCHAR szTrace[MAX_PATH]; 27 | _com_error err(hr); 28 | LPCTSTR szErrorText = err.ErrorMessage(); 29 | 30 | StringCchPrintf(szTrace, *pcchLen, L"%s (0x%x)", szErrorText, hr); 31 | 32 | return StringCchCopy(pszOut, *pcchLen, szTrace); 33 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Flowerinthenight. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /camera-cmd/proppage.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #include "stdafx.h" 7 | #include "proppage.h" 8 | #include "..\include\libcamera.h" 9 | #include "common.h" 10 | #include "appcontext.h" 11 | 12 | int DispatchPropertyPage(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext) 13 | { 14 | CContext *pCt = (CContext*)pContext; 15 | ICameraDs *pCamDs = NULL; 16 | HRESULT hr = E_FAIL; 17 | wchar_t szFname[MAX_PATH] = { 0 }; 18 | wstring wstrparam(pszSubParam); 19 | size_t fname = wstrparam.find(L"-fname:"); 20 | int retcode = DEFAULT_ERROR; 21 | 22 | if (fname != wstring::npos) 23 | { 24 | CopyMemory(szFname, &pszSubParam[fname + 7], ((pCt->m_cchlen - 1) - (fname + 7)) * sizeof(wchar_t)); 25 | 26 | hr = CreateCameraDsInstance(&pCamDs); 27 | 28 | if (SUCCEEDED(hr) && pCamDs) 29 | { 30 | hr = pCamDs->Initialize(szFname); 31 | 32 | if (SUCCEEDED(hr)) 33 | { 34 | hr = pCamDs->LaunchPropertiesFrame(); 35 | retcode = NOERROR; 36 | } 37 | 38 | pCamDs->Release(); 39 | } 40 | 41 | *pCt->m_pCmdSupported = TRUE; 42 | } 43 | 44 | return retcode; 45 | } -------------------------------------------------------------------------------- /include/sdktrace.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | 11 | #define FN __FUNCTION__ 12 | #define FL __FILE__ 13 | #define LN __LINE__ 14 | 15 | #define TL_ERROR TRACE_LEVEL_ERROR 16 | #define TL_INFO TRACE_LEVEL_INFORMATION 17 | 18 | #define KW_ENTRY 1 << 0 19 | #define KW_EXIT 1 << 1 20 | #define KW_INFO 1 << 2 21 | 22 | #if (NTDDI_VERSION > NTDDI_WINBLUE) 23 | // 24 | // New trace logging feature from Win10. 25 | // 26 | #include 27 | 28 | // 29 | // Short versions of the logging macros. See https://msdn.microsoft.com/en-us/library/windows/desktop/dn904631(v=vs.85).aspx. 30 | // 31 | #define TL_WRITE(p, ...) \ 32 | TraceLoggingWrite(p, "Jenkins", TraceLoggingValue(__FILE__, "FILE:"), TraceLoggingValue(__FUNCTIONW__, "FUNC:"), __VA_ARGS__) 33 | 34 | #define TL_VALUE TraceLoggingValue 35 | #define TL_WIDESTR TraceLoggingWideString 36 | #define TL_PTR TraceLoggingPointer 37 | #define TL_BOOL TraceLoggingBool 38 | #define TL_BOOLEAN TraceLoggingBoolean 39 | #define TL_HEXUINT32 TraceLoggingHexUInt32 40 | #define TL_WINERR TraceLoggingWinError 41 | #define TL_NTSTATUS TraceLoggingNTStatus 42 | #define TL_HR TraceLoggingHResult 43 | #endif -------------------------------------------------------------------------------- /camera-cmd/fnames.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #include "stdafx.h" 7 | #include "fnames.h" 8 | #include "..\include\libcamera.h" 9 | #include "common.h" 10 | #include "appcontext.h" 11 | 12 | int DispatchFriendlyNames(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext) 13 | { 14 | CContext *pCt = (CContext*)pContext; 15 | ICameraMf *pCamMf = NULL; 16 | HRESULT hr = E_FAIL; 17 | int retcode = DEFAULT_ERROR; 18 | 19 | hr = CreateCameraMfInstance(&pCamMf); 20 | 21 | if (SUCCEEDED(hr) && pCamMf) 22 | { 23 | wchar_t *pszNames = NULL; 24 | LONG cbSize = 0; 25 | 26 | hr = pCamMf->GetFriendlyNames(&pszNames, &cbSize); 27 | 28 | if (pszNames) 29 | { 30 | vector names; 31 | wstring wstrnames(pszNames); 32 | 33 | split(wstrnames, L';', names); 34 | 35 | if (names.size() > 0) 36 | { 37 | _tprintf(L"Available camera(s):\n"); 38 | 39 | for (int i = 0; i < names.size(); i++) 40 | { 41 | _tprintf(L"%d. %s\n", i + 1, names.at(i).c_str()); 42 | } 43 | 44 | retcode = names.size(); 45 | } 46 | 47 | free(pszNames); 48 | } 49 | 50 | pCamMf->Release(); 51 | } 52 | 53 | *pCt->m_pCmdSupported = TRUE; 54 | 55 | return retcode; 56 | } -------------------------------------------------------------------------------- /camera-cmd/issyscam.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #include "stdafx.h" 7 | #include "issyscam.h" 8 | #include 9 | #include "..\include\libcamera.h" 10 | #include "common.h" 11 | #include "appcontext.h" 12 | 13 | int IsSystemCamera(wchar_t *pszFname, BOOL *pIsSysCam) 14 | { 15 | CComPtr spCameraMf = nullptr; 16 | int retcode = DEFAULT_ERROR; 17 | HRESULT hr = S_OK; 18 | 19 | _tprintf(L"Checking if input is system camera.\n"); 20 | 21 | hr = CreateCameraMfInstance(&spCameraMf); 22 | 23 | if (SUCCEEDED(hr) && spCameraMf) 24 | { 25 | hr = spCameraMf->IsSystemCamera(pszFname, pIsSysCam, (LONG*)&retcode); 26 | 27 | if (SUCCEEDED(hr)) 28 | { 29 | *pIsSysCam 30 | ? _tprintf(L"\n%s is installed in the system (index = %d).\n", pszFname, retcode) 31 | : _tprintf(L"\n%s is not installed in the system.\n", pszFname); 32 | } 33 | else 34 | { 35 | ErrorCom(hr, L"IsSystemCamera"); 36 | retcode = DEFAULT_ERROR; 37 | } 38 | } 39 | 40 | return retcode; 41 | } 42 | 43 | int DispatchIsSystemCamera(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext) 44 | { 45 | CContext *pCt = (CContext*)pContext; 46 | wchar_t szFname[MAX_PATH] = { 0 }; 47 | int retcode = DEFAULT_ERROR; 48 | 49 | wstring wstrparam(pszSubParam); 50 | size_t fname = wstrparam.find(L"-fname:"); 51 | BOOL bIsSysCam = FALSE; 52 | 53 | if (fname != wstring::npos) 54 | { 55 | CopyMemory(szFname, &pszSubParam[fname + 7], ((pCt->m_cchlen - 1) - (fname + 7)) * sizeof(wchar_t)); 56 | 57 | retcode = IsSystemCamera(szFname, &bIsSysCam); 58 | 59 | *pCt->m_pCmdSupported = TRUE; 60 | } 61 | 62 | return retcode; 63 | } -------------------------------------------------------------------------------- /camera-cmd/mediainfo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #include "stdafx.h" 7 | #include "mediainfo.h" 8 | #include "..\include\libcamera.h" 9 | #include "common.h" 10 | #include "appcontext.h" 11 | 12 | int DispatchMediaInfo(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext) 13 | { 14 | CContext *pCt = (CContext*)pContext; 15 | ICameraMf *pCamMf = NULL; 16 | HRESULT hr = E_FAIL; 17 | LONG lCount = DEFAULT_ERROR /* this is our return value */; 18 | wchar_t szFname[MAX_PATH] = { 0 }; 19 | wstring wstrparam(pszSubParam); 20 | size_t fname = wstrparam.find(L"-fname:"); 21 | 22 | if (fname != wstring::npos) 23 | { 24 | CopyMemory(szFname, &pszSubParam[fname + 7], ((pCt->m_cchlen - 1) - (fname + 7)) * sizeof(wchar_t)); 25 | 26 | hr = CreateCameraMfInstance(&pCamMf); 27 | 28 | if (SUCCEEDED(hr) && pCamMf) 29 | { 30 | MFMEDIA_INFO *pInfo = NULL; 31 | 32 | hr = pCamMf->MfGetMediaInfo(szFname, &pInfo, &lCount); 33 | 34 | if (SUCCEEDED(hr) && lCount > 0 && pInfo) 35 | { 36 | for (int i = 0; i < lCount; i++) 37 | { 38 | _tprintf(L"Index: %d\n", pInfo[i].lIndex); 39 | _tprintf(L"Subtype: %s\n", pInfo[i].szSubtype); 40 | _tprintf(L"Resolution: %dx%d\n", pInfo[i].lResolutionX, pInfo[i].lResolutionY); 41 | _tprintf(L"Frame Rate: %d:%d\n", pInfo[i].lFrameRateNumerator, pInfo[i].lFrameRateDenominator); 42 | _tprintf(L"Pixel Aspect Ratio: %d:%d\n", pInfo[i].lPxAspectRatioNumerator, pInfo[i].lPxAspectRatioDenominator); 43 | _tprintf(L"Image Stride: %d\n\n", pInfo[i].lStride); 44 | } 45 | 46 | free(pInfo); 47 | } 48 | 49 | pCamMf->Release(); 50 | } 51 | 52 | *pCt->m_pCmdSupported = TRUE; 53 | } 54 | 55 | return lCount; 56 | } -------------------------------------------------------------------------------- /libcore/libcore.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | 46 | 47 | Resource Files 48 | 49 | 50 | -------------------------------------------------------------------------------- /win32-camera-tools.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcore", "libcore\libcore.vcxproj", "{15224FB4-1E37-445C-A9B2-F2EFAB56859E}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "include", "include", "{7B49661D-311A-4344-891E-EA3880E5614C}" 9 | ProjectSection(SolutionItems) = preProject 10 | include\libcamera.h = include\libcamera.h 11 | include\libcontextbase.h = include\libcontextbase.h 12 | include\libcore.h = include\libcore.h 13 | include\sdktrace.h = include\sdktrace.h 14 | EndProjectSection 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "camera-cmd", "camera-cmd\camera-cmd.vcxproj", "{6344A39D-F427-4E51-8C9C-F5A6A999637B}" 17 | ProjectSection(ProjectDependencies) = postProject 18 | {15224FB4-1E37-445C-A9B2-F2EFAB56859E} = {15224FB4-1E37-445C-A9B2-F2EFAB56859E} 19 | EndProjectSection 20 | EndProject 21 | Global 22 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 23 | Debug|x64 = Debug|x64 24 | Debug|x86 = Debug|x86 25 | Release|x64 = Release|x64 26 | Release|x86 = Release|x86 27 | EndGlobalSection 28 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 29 | {15224FB4-1E37-445C-A9B2-F2EFAB56859E}.Debug|x64.ActiveCfg = Debug|x64 30 | {15224FB4-1E37-445C-A9B2-F2EFAB56859E}.Debug|x64.Build.0 = Debug|x64 31 | {15224FB4-1E37-445C-A9B2-F2EFAB56859E}.Debug|x86.ActiveCfg = Debug|Win32 32 | {15224FB4-1E37-445C-A9B2-F2EFAB56859E}.Debug|x86.Build.0 = Debug|Win32 33 | {15224FB4-1E37-445C-A9B2-F2EFAB56859E}.Release|x64.ActiveCfg = Release|x64 34 | {15224FB4-1E37-445C-A9B2-F2EFAB56859E}.Release|x64.Build.0 = Release|x64 35 | {15224FB4-1E37-445C-A9B2-F2EFAB56859E}.Release|x86.ActiveCfg = Release|Win32 36 | {15224FB4-1E37-445C-A9B2-F2EFAB56859E}.Release|x86.Build.0 = Release|Win32 37 | {6344A39D-F427-4E51-8C9C-F5A6A999637B}.Debug|x64.ActiveCfg = Debug|x64 38 | {6344A39D-F427-4E51-8C9C-F5A6A999637B}.Debug|x64.Build.0 = Debug|x64 39 | {6344A39D-F427-4E51-8C9C-F5A6A999637B}.Debug|x86.ActiveCfg = Debug|Win32 40 | {6344A39D-F427-4E51-8C9C-F5A6A999637B}.Debug|x86.Build.0 = Debug|Win32 41 | {6344A39D-F427-4E51-8C9C-F5A6A999637B}.Release|x64.ActiveCfg = Release|x64 42 | {6344A39D-F427-4E51-8C9C-F5A6A999637B}.Release|x64.Build.0 = Release|x64 43 | {6344A39D-F427-4E51-8C9C-F5A6A999637B}.Release|x86.ActiveCfg = Release|Win32 44 | {6344A39D-F427-4E51-8C9C-F5A6A999637B}.Release|x86.Build.0 = Release|Win32 45 | EndGlobalSection 46 | GlobalSection(SolutionProperties) = preSolution 47 | HideSolutionNode = FALSE 48 | EndGlobalSection 49 | EndGlobal 50 | -------------------------------------------------------------------------------- /camera-cmd/camera-cmd.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files 61 | 62 | 63 | Source Files 64 | 65 | 66 | Source Files 67 | 68 | 69 | Source Files 70 | 71 | 72 | Source Files 73 | 74 | 75 | Source Files 76 | 77 | 78 | Source Files 79 | 80 | 81 | 82 | 83 | Resource Files 84 | 85 | 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build status](https://ci.appveyor.com/api/projects/status/1njgb2uftlijk7u2/branch/master?svg=true)](https://ci.appveyor.com/project/flowerinthenight/windows-camera-tools/branch/master) 2 | 3 | # windows-camera-tools 4 | 5 | A generic command line tool to control camera properties in Windows. The tool's name is `camera-cmd.exe`. You can also view the information below in command line by running `camera-cmd.exe` without arguments. 6 | 7 | ## Syntax 8 | 9 | ``` 10 | camera-cmd.exe option [parameters...] 11 | ``` 12 | 13 | ## Options 14 | 15 | ##### fnames 16 | 17 | Lists the available/attached camera(s) in the system. Returns the number of available camera(s) found if any, otherwise returns -1. 18 | 19 | ##### mediainfo 20 | 21 | ``` 22 | mediainfo -fname: 23 | ``` 24 | 25 | Lists media-related information of the provided camera name. Returns the number of information structures retrieved. `camera_friendly_name` is the friendly name of the camera device/driver. You can use the `fnames` option to get the available friendly names, or see Device Manager -> Imaging devices. 26 | 27 | ###### Example 28 | 29 | ``` 30 | camera-cmd.exe mediainfo -fname:Integrated Camera 31 | ``` 32 | 33 | ##### proppage 34 | 35 | ``` 36 | proppage -fname: 37 | ``` 38 | 39 | Opens the driver-provided (if any) extended property page(s). `camera_friendly_name` is the friendly name of the camera device/driver. You can use the `fnames` option to get the available friendly names, or see Device Manager -> Imaging devices. 40 | 41 | ###### Example 42 | 43 | ``` 44 | camera-cmd.exe proppage -fname:Integrated Camera 45 | ``` 46 | 47 | ##### issyscam 48 | 49 | ``` 50 | issyscam -fname: 51 | ``` 52 | 53 | Returns the index of the camera friendly name being queried. Returns -1 on failure, or when the camera is not found. `camera_friendly_name` is the friendly name of the camera device/driver. You can use the `fnames` option to get the available friendly names, or see Device Manager -> Imaging devices. 54 | 55 | ###### Example 56 | 57 | ``` 58 | camera-cmd.exe issyscam -fname:Integrated Camera 59 | ``` 60 | 61 | ##### privacy 62 | 63 | ``` 64 | privacy -fname: [-state:<0|1>] 65 | ``` 66 | 67 | Controls the camera privacy properties (if supported). `camera_friendly_name` is the friendly name of the camera device/driver. You can use the `fnames` option to get the available friendly names, or see Device Manager -> Imaging devices. Valid `-state:` values are 0 (disabled), and 1 (enabled). If only `-fname:...` is provided, returns the current state. If `-state:...` is provided after `fname:...`, sets the privacy state to the value provided. Returns 0 on success, -1 on failure. 68 | 69 | ###### Examples 70 | 71 | ``` 72 | camera-cmd.exe privacy -fname:Integrated Camera 73 | camera-cmd.exe privacy -fname:Integrated Camera -state:1 74 | ``` 75 | 76 | ##### flash 77 | 78 | ``` 79 | flash -fname: [-state:<0|1|2>] 80 | ``` 81 | 82 | Controls the camera flash properties (if supported). `camera_friendly_name` is the friendly name of the camera device/driver. You can use the `fnames` option to get the available friendly names, or see Device Manager -> Imaging devices. Valid `-state:` values are 0 (flash off), 1 (flash on), and 2 (auto-flash). If only `-fname:...` is provided, returns the current state. If `-state:...` is provided after `fname:...`, sets the flash state to the value provided. Returns 0 on success, -1 on failure. 83 | 84 | ###### Examples 85 | 86 | ``` 87 | camera-cmd.exe flash -fname:Integrated Camera 88 | camera-cmd.exe flash -fname:Integrated Camera -state:2 89 | ``` 90 | -------------------------------------------------------------------------------- /camera-cmd/privacy.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #include "stdafx.h" 7 | #include "privacy.h" 8 | #include 9 | #include "..\include\libcamera.h" 10 | #include "common.h" 11 | #include "appcontext.h" 12 | 13 | int SetupPrivacy(wchar_t *pszFname, wchar_t *pszState, BOOL bSetPrivacy) 14 | { 15 | CComPtr spCameraDs = nullptr; 16 | HRESULT hr = S_OK; 17 | int retcode = DEFAULT_ERROR; 18 | 19 | hr = CreateCameraDsInstance(&spCameraDs); 20 | 21 | if (SUCCEEDED(hr) && spCameraDs) 22 | { 23 | hr = spCameraDs->Initialize(pszFname); 24 | 25 | if (SUCCEEDED(hr)) 26 | { 27 | if (bSetPrivacy) 28 | { 29 | hr = spCameraDs->SetPrivacy(_wtol(pszState)); 30 | 31 | if (SUCCEEDED(hr)) 32 | { 33 | _tprintf(L"Output: Operation successful.\n"); 34 | retcode = NOERROR; 35 | } 36 | else 37 | { 38 | ErrorCom(hr, L"SetPrivacy"); 39 | retcode = DEFAULT_ERROR; 40 | } 41 | } 42 | else 43 | { 44 | LONG lValue = 0, lFlags = 0; 45 | 46 | hr = spCameraDs->GetPrivacy(&lValue, &lFlags); 47 | 48 | if (SUCCEEDED(hr)) 49 | { 50 | _tprintf(L"Output: Operation successful.\n"); 51 | _tprintf(L"Output: Current privacy settings: %d\n", lValue); 52 | _tprintf(L"Output: Current privacy flags: %x\n", lFlags); 53 | retcode = (int)lValue; 54 | } 55 | else 56 | { 57 | ErrorCom(hr, L"GetPrivacy"); 58 | retcode = DEFAULT_ERROR; 59 | } 60 | } 61 | 62 | spCameraDs->CloseInterfaces(); 63 | } 64 | else 65 | { 66 | ErrorCom(hr, L"Initialize"); 67 | retcode = DEFAULT_ERROR; 68 | } 69 | } 70 | 71 | return retcode; 72 | } 73 | 74 | int DispatchPrivacy(wchar_t *pszParams, wchar_t *pszSubParam, PVOID pContext) 75 | { 76 | CContext *pCt = (CContext*)pContext; 77 | BOOL bSetPrivacy = FALSE; 78 | wchar_t szFname[MAX_PATH] = { 0 }; 79 | wchar_t szState[10] = { 0 }; 80 | int retcode = DEFAULT_ERROR; 81 | 82 | wstring wstrparam(pszSubParam); 83 | size_t fname = wstrparam.find(L"-fname:"); 84 | size_t state = wstrparam.find(L"-state:"); 85 | 86 | if (fname != wstring::npos) 87 | { 88 | bSetPrivacy = (state == wstring::npos) ? FALSE : TRUE; 89 | 90 | if (state > fname) 91 | { 92 | if (bSetPrivacy) 93 | { 94 | _tprintf(L"\nSet privacy mode option selected.\n"); 95 | CopyMemory(szFname, &pszSubParam[fname + 7], ((state - 1) - (fname + 7)) * sizeof(wchar_t)); 96 | CopyMemory(szState, &pszSubParam[state + 7], ((pCt->m_cchlen - 1) - (state + 7)) * sizeof(wchar_t)); 97 | szState[1] = L'\0'; 98 | } 99 | else 100 | { 101 | _tprintf(L"\nGet privacy mode option selected.\n"); 102 | CopyMemory(szFname, &pszSubParam[fname + 7], ((pCt->m_cchlen - 1) - (fname + 7)) * sizeof(wchar_t)); 103 | } 104 | 105 | *pCt->m_pCmdSupported = TRUE; 106 | } 107 | 108 | if (*pCt->m_pCmdSupported == TRUE) 109 | { 110 | retcode = SetupPrivacy(szFname, szState, bSetPrivacy); 111 | } 112 | } 113 | 114 | return retcode; 115 | } -------------------------------------------------------------------------------- /camera-cmd/flash.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #include "stdafx.h" 7 | #include "flash.h" 8 | #include 9 | #include "..\include\libcamera.h" 10 | #include "common.h" 11 | #include "appcontext.h" 12 | 13 | int SetupFlash(wchar_t *pszFname, wchar_t *pszState, BOOL bSetFlash) 14 | { 15 | CComPtr spCameraDs = nullptr; 16 | int retcode = DEFAULT_ERROR; 17 | HRESULT hr = S_OK; 18 | 19 | hr = CreateCameraDsInstance(&spCameraDs); 20 | 21 | if (SUCCEEDED(hr) && spCameraDs) 22 | { 23 | hr = spCameraDs->Initialize(pszFname); 24 | 25 | if (SUCCEEDED(hr)) 26 | { 27 | if (bSetFlash) 28 | { 29 | int newstate = _wtoi(pszState); 30 | CameraFlashEnum newFlashVal; 31 | 32 | switch (newstate) 33 | { 34 | case 0: newFlashVal = CameraFlashOff; break; 35 | case 1: newFlashVal = CameraFlashOn; break; 36 | case 2: newFlashVal = CameraFlashAuto; break; 37 | default: newFlashVal = CameraFlashAuto; break; 38 | } 39 | 40 | hr = spCameraDs->SetFlash(newFlashVal); 41 | 42 | if (SUCCEEDED(hr)) 43 | { 44 | _tprintf(L"Output: Operation successful.\n"); 45 | retcode = NOERROR; 46 | } 47 | else 48 | { 49 | ErrorCom(hr, L"SetFlash"); 50 | retcode = DEFAULT_ERROR; 51 | } 52 | } 53 | else 54 | { 55 | CameraFlashEnum currFlash; 56 | LONG lFlags; 57 | 58 | hr = spCameraDs->GetFlash(&currFlash, &lFlags); 59 | 60 | if (SUCCEEDED(hr) && (currFlash >= -1 && currFlash <= CameraFlashCheckCount)) 61 | { 62 | _tprintf(L"Output: Operation successful.\n"); 63 | _tprintf(L"Output: Current flash settings: %d\n", currFlash); 64 | _tprintf(L"Output: Current flash flags: 0x%x\n", lFlags); 65 | retcode = (int)currFlash; 66 | } 67 | else 68 | { 69 | ErrorCom(hr, L"GetFlash"); 70 | retcode = DEFAULT_ERROR; 71 | } 72 | } 73 | 74 | spCameraDs->CloseInterfaces(); 75 | } 76 | else 77 | { 78 | ErrorCom(hr, L"Initialize"); 79 | retcode = DEFAULT_ERROR; 80 | } 81 | } 82 | 83 | return retcode; 84 | } 85 | 86 | int DispatchFlash(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext) 87 | { 88 | CContext *pCt = (CContext*)pContext; 89 | BOOL bSetFlash = FALSE; 90 | wchar_t szFname[MAX_PATH] = { 0 }; 91 | wchar_t szState[10] = { 0 }; 92 | int retcode = DEFAULT_ERROR; 93 | 94 | wstring wstrparam(pszSubParam); 95 | size_t fname = wstrparam.find(L"-fname:"); 96 | size_t state = wstrparam.find(L"-state:"); 97 | 98 | if (fname != wstring::npos) 99 | { 100 | bSetFlash = (state == wstring::npos) ? FALSE : TRUE; 101 | 102 | if (state > fname) 103 | { 104 | if (bSetFlash) 105 | { 106 | _tprintf(L"\nSet flash option selected.\n"); 107 | CopyMemory(szFname, &pszSubParam[fname + 7], ((state - 1) - (fname + 7)) * sizeof(wchar_t)); 108 | CopyMemory(szState, &pszSubParam[state + 7], ((pCt->m_cchlen - 1) - (state + 7)) * sizeof(wchar_t)); 109 | szState[1] = L'\0'; 110 | } 111 | else 112 | { 113 | _tprintf(L"\nGet flash option selected.\n"); 114 | CopyMemory(szFname, &pszSubParam[fname + 7], ((pCt->m_cchlen - 1) - (fname + 7)) * sizeof(wchar_t)); 115 | } 116 | 117 | *pCt->m_pCmdSupported = TRUE; 118 | } 119 | 120 | if (*pCt->m_pCmdSupported == TRUE) 121 | { 122 | retcode = SetupFlash(szFname, szState, bSetFlash); 123 | } 124 | } 125 | 126 | return retcode; 127 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | out/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | *.VC.db 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | 84 | # Visual Studio profiler 85 | *.psess 86 | *.vsp 87 | *.vspx 88 | *.sap 89 | 90 | # TFS 2012 Local Workspace 91 | $tf/ 92 | 93 | # Guidance Automation Toolkit 94 | *.gpState 95 | 96 | # ReSharper is a .NET coding add-in 97 | _ReSharper*/ 98 | *.[Rr]e[Ss]harper 99 | *.DotSettings.user 100 | 101 | # JustCode is a .NET coding add-in 102 | .JustCode 103 | 104 | # TeamCity is a build add-in 105 | _TeamCity* 106 | 107 | # DotCover is a Code Coverage Tool 108 | *.dotCover 109 | 110 | # NCrunch 111 | _NCrunch_* 112 | .*crunch*.local.xml 113 | nCrunchTemp_* 114 | 115 | # MightyMoose 116 | *.mm.* 117 | AutoTest.Net/ 118 | 119 | # Web workbench (sass) 120 | .sass-cache/ 121 | 122 | # Installshield output folder 123 | [Ee]xpress/ 124 | 125 | # DocProject is a documentation generator add-in 126 | DocProject/buildhelp/ 127 | DocProject/Help/*.HxT 128 | DocProject/Help/*.HxC 129 | DocProject/Help/*.hhc 130 | DocProject/Help/*.hhk 131 | DocProject/Help/*.hhp 132 | DocProject/Help/Html2 133 | DocProject/Help/html 134 | 135 | # Click-Once directory 136 | publish/ 137 | 138 | # Publish Web Output 139 | *.[Pp]ublish.xml 140 | *.azurePubxml 141 | # TODO: Comment the next line if you want to checkin your web deploy settings 142 | # but database connection strings (with potential passwords) will be unencrypted 143 | *.pubxml 144 | *.publishproj 145 | 146 | # NuGet Packages 147 | *.nupkg 148 | # The packages folder can be ignored because of Package Restore 149 | **/packages/* 150 | # except build/, which is used as an MSBuild target. 151 | !**/packages/build/ 152 | # Uncomment if necessary however generally it will be regenerated when needed 153 | #!**/packages/repositories.config 154 | 155 | # Windows Azure Build Output 156 | csx/ 157 | *.build.csdef 158 | 159 | # Windows Store app package directory 160 | AppPackages/ 161 | 162 | # Visual Studio cache files 163 | # files ending in .cache can be ignored 164 | *.[Cc]ache 165 | # but keep track of directories ending in .cache 166 | !*.[Cc]ache/ 167 | 168 | # Others 169 | ClientBin/ 170 | [Ss]tyle[Cc]op.* 171 | ~$* 172 | *~ 173 | *.dbmdl 174 | *.dbproj.schemaview 175 | *.pfx 176 | *.publishsettings 177 | node_modules/ 178 | orleans.codegen.cs 179 | 180 | # RIA/Silverlight projects 181 | Generated_Code/ 182 | 183 | # Backup & report files from converting an old project file 184 | # to a newer Visual Studio version. Backup files are not needed, 185 | # because we have git ;-) 186 | _UpgradeReport_Files/ 187 | Backup*/ 188 | UpgradeLog*.XML 189 | UpgradeLog*.htm 190 | 191 | # SQL Server files 192 | *.mdf 193 | *.ldf 194 | 195 | # Business Intelligence projects 196 | *.rdl.data 197 | *.bim.layout 198 | *.bim_*.settings 199 | 200 | # Microsoft Fakes 201 | FakesAssemblies/ 202 | 203 | # Node.js Tools for Visual Studio 204 | .ntvs_analysis.dat 205 | 206 | # Visual Studio 6 build log 207 | *.plg 208 | 209 | # Visual Studio 6 workspace options file 210 | *.opt 211 | 212 | # Visual Studio LightSwitch build output 213 | **/*.HTMLClient/GeneratedArtifacts 214 | **/*.DesktopClient/GeneratedArtifacts 215 | **/*.DesktopClient/ModelManifest.xml 216 | **/*.Server/GeneratedArtifacts 217 | **/*.Server/ModelManifest.xml 218 | _Pvt_Extensions 219 | -------------------------------------------------------------------------------- /include/libcamera.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define FOURCC_DMP(dw, a, b, c, d) \ 18 | { \ 19 | WORD hw = HIWORD(dw); \ 20 | WORD lw = LOWORD(dw); \ 21 | *a = (CHAR)HIBYTE(hw); \ 22 | *b = (CHAR)LOBYTE(hw); \ 23 | *c = (CHAR)HIBYTE(lw); \ 24 | *d = (CHAR)LOBYTE(lw); \ 25 | } 26 | 27 | struct __declspec(uuid("BE660B75-1315-4A97-8297-1E678E28953D")) IBufferLock; 28 | struct __declspec(uuid("91B64872-05C4-405F-9266-B7AAFF000A35")) ICameraDs; 29 | struct __declspec(uuid("5B57A953-D677-4073-B64B-78BD270E56CB")) ICameraMf; 30 | struct __declspec(uuid("9ADA3F32-E5F5-415E-A120-2AB0AAA700C0")) IWebcamWrapper; 31 | 32 | typedef HRESULT(CALLBACK *FrameCallback)(HRESULT hrStatus, 33 | DWORD dwStreamIndex, 34 | DWORD dwStreamFlags, 35 | LONGLONG llTimestamp, 36 | IMFSample *pSample 37 | ); 38 | 39 | typedef enum { 40 | CameraFlashOff = 0, 41 | CameraFlashOn, 42 | CameraFlashAuto, 43 | CameraFlashCheckCount, 44 | } CameraFlashEnum; 45 | 46 | struct IBufferLock : public IUnknown { 47 | virtual HRESULT LockBuffer(LONG lDefaultStride, DWORD dwHeightInPixels, BYTE **ppbScanLine0, LONG *plStride) = 0; 48 | virtual void UnlockBuffer() = 0; 49 | }; 50 | 51 | // 52 | // Our very simple COM-like wrapper interface for camera access using DirectShow interfaces. 53 | // 54 | struct ICameraDs : public IUnknown { 55 | virtual HRESULT Initialize(wchar_t *pszFriendlyName) = 0; 56 | virtual HRESULT IsSystemCamera(wchar_t *pszFriendlyName, PBOOL pbSysCam, wchar_t *pszDevPath, DWORD cchDevPathSize) = 0; 57 | virtual HRESULT SetPrivacy(LONG lNewValue) = 0; 58 | virtual HRESULT GetPrivacy(LONG *plValue, LONG *plFlags) = 0; 59 | virtual HRESULT SetBrightness(LONG lNewValue) = 0; 60 | virtual HRESULT GetBrightness(LONG *plValue, LONG *plFlags) = 0; 61 | virtual HRESULT SetContrast(LONG lNewValue) = 0; 62 | virtual HRESULT GetContrast(LONG *plValue, LONG *plFlags) = 0; 63 | virtual HRESULT SetSaturation(LONG lNewValue) = 0; 64 | virtual HRESULT GetSaturation(LONG *plValue, LONG *plFlags) = 0; 65 | virtual HRESULT SetExposure(LONG lNewValue) = 0; 66 | virtual HRESULT GetExposure(LONG *plValue, LONG *plFlags) = 0; 67 | virtual HRESULT SetFlash(CameraFlashEnum newValue) = 0; 68 | virtual HRESULT GetFlash(CameraFlashEnum *pValue, LONG *plFlags) = 0; 69 | virtual HRESULT GetBrightnessRange(LONG *plMin, LONG *plMax, LONG *plDelta, LONG *plDefault, LONG *plCaps) = 0; 70 | virtual HRESULT GetContrastRange(LONG *plMin, LONG *plMax, LONG *plDelta, LONG *plDefault, LONG *plCaps) = 0; 71 | virtual HRESULT GetSaturationRange(LONG *plMin, LONG *plMax, LONG *plDelta, LONG *plDefault, LONG *plCaps) = 0; 72 | virtual HRESULT GetExposureRange(LONG *plMin, LONG *plMax, LONG *plDelta, LONG *plDefault, LONG *plCaps) = 0; 73 | virtual HRESULT GetCameraProvider(wchar_t *pszFriendlyName, wchar_t *pszProvider, DWORD cchProvSize) = 0; 74 | virtual HRESULT DumpCameraInfo(wchar_t *pszFriendlyName) = 0; 75 | virtual HRESULT LaunchPropertiesFrame() = 0; 76 | virtual HRESULT CloseInterfaces() = 0; 77 | }; 78 | 79 | typedef struct __MFMEDIA_INFO { 80 | LONG lIndex; 81 | GUID subTypeGuid; 82 | wchar_t szSubtype[MAX_PATH]; 83 | LONG lResolutionX; 84 | LONG lResolutionY; 85 | LONG lStride; 86 | LONG lFrameRateNumerator; 87 | LONG lFrameRateDenominator; 88 | LONG lPxAspectRatioNumerator; 89 | LONG lPxAspectRatioDenominator; 90 | } MFMEDIA_INFO, *PMFMEDIA_INFO; 91 | 92 | // 93 | // Our very simple COM-like wrapper interface for camera access using Media Foundation interfaces. 94 | // 95 | struct ICameraMf : public IUnknown { 96 | virtual HRESULT Initialize(LONG lWidth, LONG lHeight, FrameCallback pfnFrameCallback) = 0; 97 | virtual HRESULT GetFriendlyNames(wchar_t **ppFriendlyNames, LONG *pcbSize) = 0; 98 | virtual HRESULT StartRenderAsync(wchar_t *pszFriendlyName) = 0; 99 | virtual HRESULT StopRenderAsync() = 0; 100 | virtual HRESULT IsSystemCamera(wchar_t *pszFriendlyName, PBOOL pbSystemCamera, LONG *pIndex) = 0; 101 | virtual HRESULT MfDumpCameraInfo(wchar_t *pszFriendlyName) = 0; 102 | virtual HRESULT MfGetMediaInfo(wchar_t *pszFriendlyName, MFMEDIA_INFO **ppInfo, LONG *pCount) = 0; 103 | }; 104 | 105 | #ifdef __cplusplus 106 | extern "C" { 107 | #endif 108 | 109 | _declspec(dllexport) HRESULT GetDefaultImageStride(IMFMediaType *pType, LONG *plStride); 110 | 111 | // 112 | // Factory functions. 113 | // 114 | _declspec(dllexport) HRESULT CreateBufferLockInstance(IMFMediaBuffer *pBuffer, IBufferLock **ppObj); 115 | _declspec(dllexport) HRESULT CreateCameraDsInstance(ICameraDs **ppObj); 116 | _declspec(dllexport) HRESULT CreateCameraMfInstance(ICameraMf **ppObj); 117 | _declspec(dllexport) HRESULT CreateWebcamWrapperInstance(IWebcamWrapper **ppObj); 118 | 119 | #ifdef __cplusplus 120 | } 121 | #endif -------------------------------------------------------------------------------- /camera-cmd/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #include "stdafx.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | using namespace std; 14 | #include 15 | #include 16 | #include 17 | #include "..\include\libcore.h" 18 | #include "..\include\libcamera.h" 19 | #include "appcontext.h" 20 | #include "flash.h" 21 | #include "privacy.h" 22 | #include "issyscam.h" 23 | #include "fnames.h" 24 | #include "mediainfo.h" 25 | #include "proppage.h" 26 | #include "common.h" 27 | #include "..\etw\jytrace.h" 28 | 29 | #pragma comment(lib, "..\\out\\libcore.lib") 30 | 31 | static CContext ct; 32 | 33 | int Help(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext) 34 | { 35 | CContext *pCt = (CContext*)pContext; 36 | 37 | _tprintf(L"Synopsis:\n\n"); 38 | _tprintf(L" camera-cmd.exe option \n\n"); 39 | _tprintf(L"Options:\n\n"); 40 | _tprintf(L" fnames\n\n"); 41 | _tprintf(L" Lists the available/attached camera(s) in the system. Returns\n"); 42 | _tprintf(L" the number of available camera(s) found if any, otherwise,\n"); 43 | _tprintf(L" returns -1.\n\n"); 44 | _tprintf(L" mediainfo\n\n"); 45 | _tprintf(L" Lists media-related information of the provided camera name.\n"); 46 | _tprintf(L" Returns the number of information structures retrieved.\n\n"); 47 | _tprintf(L" Supported parameters:\n\n"); 48 | _tprintf(L" -fname:\n\n"); 49 | _tprintf(L" camera_friendly_name\n\n"); 50 | _tprintf(L" Friendly name of the camera device/driver. You can use\n"); 51 | _tprintf(L" the 'fnames' parameter for the friendly name(s) or see\n"); 52 | _tprintf(L" Device Manager -> Imaging devices.\n\n"); 53 | _tprintf(L" Example:\n\n"); 54 | _tprintf(L" camera-cmd.exe mediainfo -fname:Integrated Camera\n\n"); 55 | _tprintf(L" proppage\n\n"); 56 | _tprintf(L" Opens the driver-provided (if any) extended property page(s).\n\n"); 57 | _tprintf(L" Supported parameters:\n\n"); 58 | _tprintf(L" -fname:\n\n"); 59 | _tprintf(L" camera_friendly_name\n\n"); 60 | _tprintf(L" Friendly name of the camera device/driver. You can use\n"); 61 | _tprintf(L" the 'fnames' parameter for the friendly name(s) or see\n"); 62 | _tprintf(L" Device Manager -> Imaging devices.\n\n"); 63 | _tprintf(L" Example:\n\n"); 64 | _tprintf(L" camera-cmd.exe proppage -fname:Integrated Camera\n\n"); 65 | _tprintf(L" issyscam\n\n"); 66 | _tprintf(L" Returns the index of the camera friendly name being queried.\n"); 67 | _tprintf(L" Returns -1 on failure, or when the camera is not found.\n\n"); 68 | _tprintf(L" Supported parameters:\n\n"); 69 | _tprintf(L" -fname:\n\n"); 70 | _tprintf(L" camera_friendly_name\n\n"); 71 | _tprintf(L" Friendly name of the camera device/driver. You can use\n"); 72 | _tprintf(L" the 'fnames' parameter for the friendly name(s) or see\n"); 73 | _tprintf(L" Device Manager -> Imaging devices.\n\n"); 74 | _tprintf(L" Example:\n\n"); 75 | _tprintf(L" camera-cmd.exe issyscam -fname:Integrated Camera\n\n"); 76 | _tprintf(L" privacy\n\n"); 77 | _tprintf(L" Controls the camera privacy properties. On query, it will\n"); 78 | _tprintf(L" return the current state. On set, it will return 0 on\n"); 79 | _tprintf(L" success, -1 on failure.\n\n"); 80 | _tprintf(L" Supported parameters:\n\n"); 81 | _tprintf(L" -fname:\n\n"); 82 | _tprintf(L" camera_friendly_name\n\n"); 83 | _tprintf(L" Friendly name of the camera device/driver. You can use\n"); 84 | _tprintf(L" the 'fnames' parameter for the friendly name(s) or see\n"); 85 | _tprintf(L" Device Manager -> Imaging devices.\n\n"); 86 | _tprintf(L" -state:<0|1>\n\n"); 87 | _tprintf(L" 0 - turn privacy mode off.\n"); 88 | _tprintf(L" 1 - turn privacy mode on.\n\n"); 89 | _tprintf(L" Examples:\n\n"); 90 | _tprintf(L" camera-cmd.exe privacy -fname:Integrated Camera\n"); 91 | _tprintf(L" camera-cmd.exe privacy -fname:Integrated Camera -state:1\n\n"); 92 | _tprintf(L" flash\n\n"); 93 | _tprintf(L" Controls the camera flash properties. On query, it will\n"); 94 | _tprintf(L" return the current state. On set, it will return 0 on\n"); 95 | _tprintf(L" success, -1 on failure.\n\n"); 96 | _tprintf(L" Supported parameters:\n\n"); 97 | _tprintf(L" -fname:\n\n"); 98 | _tprintf(L" camera_friendly_name\n\n"); 99 | _tprintf(L" Friendly name of the camera device/driver. You can use\n"); 100 | _tprintf(L" the 'fnames' parameter for the friendly name(s) or see\n"); 101 | _tprintf(L" Device Manager -> Imaging devices.\n\n"); 102 | _tprintf(L" -state:<0|1|2>\n\n"); 103 | _tprintf(L" 0 - turn camera flash off.\n"); 104 | _tprintf(L" 1 - turn camera flash on.\n"); 105 | _tprintf(L" 2 - set camera flash to auto flash.\n\n"); 106 | _tprintf(L" Examples:\n\n"); 107 | _tprintf(L" camera-cmd.exe flash -fname:Integrated Camera\n"); 108 | _tprintf(L" camera-cmd.exe flash -fname:Integrated Camera -state:2\n\n"); 109 | 110 | *pCt->m_pCmdSupported = TRUE; 111 | 112 | return NOERROR; 113 | } 114 | 115 | int Junk(wchar_t *pszParam, wchar_t *pszSubParam, PVOID pContext) 116 | { 117 | CContext *pCt = (CContext*)pContext; 118 | 119 | ICameraDs *pCamDs = NULL; 120 | HRESULT hr = E_FAIL; 121 | 122 | hr = CreateCameraDsInstance(&pCamDs); 123 | 124 | if (SUCCEEDED(hr) && pCamDs) 125 | { 126 | hr = pCamDs->Initialize(L"Integrated Camera"); 127 | hr = pCamDs->LaunchPropertiesFrame(); 128 | pCamDs->Release(); 129 | } 130 | 131 | *pCt->m_pCmdSupported = TRUE; 132 | 133 | return NOERROR; 134 | } 135 | 136 | static ARG_DISPATCH_TABLE pdt[] = { 137 | { L"junk", Junk }, 138 | { L"help", Help }, 139 | { L"fnames", DispatchFriendlyNames }, 140 | { L"mediainfo", DispatchMediaInfo }, 141 | { L"flash", DispatchFlash }, 142 | { L"privacy", DispatchPrivacy }, 143 | { L"issyscam", DispatchIsSystemCamera }, 144 | { L"proppage", DispatchPropertyPage }, 145 | }; 146 | 147 | // 148 | // Main entry. 149 | // 150 | int _tmain(int argc, _TCHAR* argv[]) 151 | { 152 | wchar_t szCtrl[MAX_PATH] = { 0 }; 153 | wchar_t szParam[MAX_PATH] = { 0 }; 154 | int retcode = DEFAULT_ERROR; 155 | BOOL bSupportedCmd = FALSE; 156 | HRESULT hr = S_OK; 157 | 158 | ct.m_pCmdSupported = &bSupportedCmd; 159 | ct.m_argc = argc; 160 | ct.m_ppargv = argv; 161 | 162 | hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); 163 | 164 | if (argc >= 2) 165 | { 166 | StringCchPrintf(szCtrl, MAX_PATH, L"%s", argv[1]); 167 | 168 | for (int itr = 0; itr < ARRAYSIZE(pdt); itr++) 169 | { 170 | if (_wcsicmp(szCtrl, pdt[itr].szParam) == 0) 171 | { 172 | for (int i = 2; i < argc; i++) 173 | { 174 | StringCchCat(szParam, MAX_PATH, argv[i]); 175 | StringCchCat(szParam, MAX_PATH, L" "); 176 | } 177 | 178 | StringCchLength(szParam, MAX_PATH, &ct.m_cchlen); 179 | 180 | // 181 | // Call dispatch function. 182 | // 183 | retcode = pdt[itr].pfnDispatch(pdt[itr].szParam, szParam, &ct); 184 | 185 | break; 186 | } 187 | } 188 | } 189 | 190 | CoUninitialize(); 191 | 192 | if (!bSupportedCmd) 193 | { 194 | _tprintf(L"\nCommand not supported.\n\n"); 195 | Help(NULL, NULL, &ct); 196 | } 197 | 198 | return retcode; 199 | } -------------------------------------------------------------------------------- /camera-cmd/camera-cmd.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {6344A39D-F427-4E51-8C9C-F5A6A999637B} 23 | Win32Proj 24 | cameracmd 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v140 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | $(SolutionDir)out\ 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Use 88 | Level3 89 | Disabled 90 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | true 92 | 93 | 94 | Console 95 | true 96 | 97 | 98 | 99 | 100 | Use 101 | Level3 102 | Disabled 103 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | true 105 | 106 | 107 | Console 108 | true 109 | 110 | 111 | 112 | 113 | Level3 114 | Use 115 | MaxSpeed 116 | true 117 | true 118 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 119 | true 120 | 121 | 122 | Console 123 | true 124 | true 125 | true 126 | 127 | 128 | 129 | 130 | Level3 131 | Use 132 | MaxSpeed 133 | true 134 | true 135 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 136 | true 137 | 138 | 139 | Console 140 | true 141 | true 142 | true 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | Create 169 | Create 170 | Create 171 | Create 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /libcore/libcore.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {15224FB4-1E37-445C-A9B2-F2EFAB56859E} 23 | Win32Proj 24 | libcore 25 | 8.1 26 | 27 | 28 | 29 | DynamicLibrary 30 | true 31 | v140 32 | Unicode 33 | 34 | 35 | DynamicLibrary 36 | false 37 | v140 38 | true 39 | Unicode 40 | 41 | 42 | DynamicLibrary 43 | true 44 | v140 45 | Unicode 46 | 47 | 48 | DynamicLibrary 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | $(SolutionDir)out\ 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Use 88 | Level3 89 | Disabled 90 | WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBCORE_EXPORTS;%(PreprocessorDefinitions) 91 | true 92 | 93 | 94 | Windows 95 | true 96 | 97 | 98 | 99 | 100 | Use 101 | Level3 102 | Disabled 103 | _DEBUG;_WINDOWS;_USRDLL;LIBCORE_EXPORTS;%(PreprocessorDefinitions) 104 | true 105 | 106 | 107 | Windows 108 | true 109 | 110 | 111 | 112 | 113 | Level3 114 | Use 115 | MaxSpeed 116 | true 117 | true 118 | WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBCORE_EXPORTS;%(PreprocessorDefinitions) 119 | true 120 | 121 | 122 | Windows 123 | true 124 | true 125 | true 126 | 127 | 128 | 129 | 130 | Level3 131 | Use 132 | MaxSpeed 133 | true 134 | true 135 | NDEBUG;_WINDOWS;_USRDLL;LIBCORE_EXPORTS;%(PreprocessorDefinitions) 136 | true 137 | 138 | 139 | Windows 140 | true 141 | true 142 | true 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | false 153 | 154 | 155 | false 156 | 157 | 158 | false 159 | 160 | 161 | false 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | Create 170 | Create 171 | Create 172 | Create 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /libcore/libcamerads.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #include "stdafx.h" 7 | #include "..\include\libcore.h" 8 | #include "..\include\libcamera.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "..\include\sdktrace.h" 17 | #include "..\etw\jytrace.h" 18 | 19 | #pragma comment(lib, "strmiids") 20 | #pragma comment(lib, "setupapi.lib") 21 | #pragma comment(lib, "mfplat.lib") 22 | 23 | // 24 | // NOTE: Clients should call CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) before using any functions in this class. 25 | // 26 | class CameraDs : public ICameraDs { 27 | public: 28 | CameraDs() : 29 | m_pVih2(NULL), 30 | m_pVideoProcAmp(NULL), 31 | m_pStrmConfig(NULL), 32 | m_pSrcFilter(NULL), 33 | m_pSampleGrabberFilter(NULL), 34 | m_pMediaCtrl(NULL), 35 | m_pGraphBldr(NULL), 36 | m_pCameraControl(NULL), 37 | m_pCapGraphBldr(NULL), 38 | m_pIKsControl(NULL), 39 | m_bInitialized(FALSE), 40 | m_lRefCount(0) 41 | { 42 | EventWriteInfoW(M, FL, FN, L"Constructed [this] CameraDs"); 43 | } 44 | 45 | virtual ~CameraDs() 46 | { 47 | // 48 | // DANGER: Sometimes, this can cause a crash especially when using smart pointers. Don't really know why. Better call 49 | // CloseInterfaces() manually before (auto)deleting this object. 50 | // 51 | CloseInterfaces(); 52 | } 53 | 54 | // 55 | // IUnknown methods 56 | // 57 | STDMETHODIMP QueryInterface(REFIID iid, void **ppv) 58 | { 59 | if ((iid == __uuidof(IUnknown)) || (iid == __uuidof(ICameraDs))) 60 | { 61 | *ppv = static_cast(this); 62 | } 63 | else 64 | { 65 | *ppv = NULL; 66 | return E_NOINTERFACE; 67 | } 68 | 69 | AddRef(); 70 | return S_OK; 71 | } 72 | 73 | STDMETHODIMP_(ULONG) AddRef() 74 | { 75 | return InterlockedIncrement(&m_lRefCount); 76 | } 77 | 78 | STDMETHODIMP_(ULONG) Release() 79 | { 80 | ULONG uCount = InterlockedDecrement(&m_lRefCount); 81 | 82 | if (uCount == 0) 83 | { 84 | EventWriteInfoW(M, FL, FN, L"Deleted [this] CameraDs"); 85 | delete this; 86 | } 87 | 88 | return uCount; 89 | } 90 | 91 | // 92 | // ICameraDs methods 93 | // 94 | HRESULT Initialize(wchar_t *pszFriendlyName) 95 | { 96 | HRESULT hr = S_OK; 97 | 98 | do 99 | { 100 | hr = FindCaptureDevice(pszFriendlyName); 101 | if (FAILED(hr)) break; 102 | 103 | hr = GetInterfaces(); 104 | if (FAILED(hr)) break; 105 | 106 | m_bInitialized = TRUE; 107 | } while (false); 108 | 109 | hr = m_bInitialized ? S_OK : E_FAIL; 110 | 111 | return hr; 112 | } 113 | 114 | HRESULT IsSystemCamera(wchar_t *pszFriendlyName, PBOOL pbSysCam, wchar_t *pszDevPath, DWORD cchDevPathSize) 115 | { 116 | IBaseFilter **ppSrcFilter = &m_pSrcFilter; 117 | HRESULT hr = S_OK; 118 | 119 | IBaseFilter *pSrc = NULL; 120 | IMoniker *pMoniker = NULL; 121 | ICreateDevEnum *pDevEnum = NULL; 122 | IEnumMoniker *pClassEnum = NULL; 123 | 124 | VARIANT varName; 125 | VARIANT varName2; 126 | 127 | if (!ppSrcFilter) return E_POINTER; 128 | 129 | // 130 | // Create the system device enumerator 131 | // 132 | hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void**)&pDevEnum); 133 | if (FAILED(hr)) return hr; 134 | 135 | // 136 | // Create an enumerator for the video capture devices 137 | // 138 | hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0); 139 | 140 | if (FAILED(hr)) 141 | { 142 | SAFE_RELEASE(pDevEnum); 143 | return hr; 144 | } 145 | 146 | // 147 | // If there are no enumerators for the requested type, then CreateClassEnumerator will succeed, 148 | // but pClassEnum will be NULL. 149 | // 150 | if (pClassEnum == NULL) 151 | { 152 | SAFE_RELEASE(pClassEnum); 153 | SAFE_RELEASE(pDevEnum); 154 | hr = E_FAIL; 155 | return hr; 156 | } 157 | 158 | // 159 | // Use the first video capture device on the device list. Note that if the Next() call succeeds but there are no 160 | // monikers, it will return S_FALSE (which is not a failure). Therefore, we check that the return code is S_OK 161 | // instead of using SUCCEEDED() macro. 162 | // 163 | pClassEnum->Reset(); 164 | 165 | ULONG cFetched; 166 | *pbSysCam = FALSE; 167 | 168 | while (hr = pClassEnum->Next(1, &pMoniker, &cFetched), hr == S_OK) 169 | { 170 | IPropertyBag *pPropBag = NULL; 171 | HRESULT hrTmp = E_FAIL; 172 | 173 | #pragma warning(suppress: 6387) 174 | hrTmp = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); 175 | if (FAILED(hrTmp)) 176 | { 177 | SAFE_RELEASE(pMoniker); 178 | continue; 179 | } 180 | 181 | VariantInit(&varName); 182 | VariantInit(&varName2); 183 | 184 | hrTmp = pPropBag->Read(L"FriendlyName", &varName, 0); 185 | if (FAILED(hrTmp)) 186 | { 187 | VariantClear(&varName); 188 | VariantClear(&varName2); 189 | SAFE_RELEASE(pPropBag); 190 | continue; 191 | } 192 | 193 | hrTmp = pPropBag->Read(L"DevicePath", &varName2, 0); 194 | if (FAILED(hrTmp)) 195 | { 196 | VariantClear(&varName); 197 | VariantClear(&varName2); 198 | SAFE_RELEASE(pPropBag); 199 | continue; 200 | } 201 | 202 | if (varName.bstrVal == NULL || varName2.bstrVal == NULL) 203 | { 204 | VariantClear(&varName); 205 | VariantClear(&varName2); 206 | SAFE_RELEASE(pPropBag); 207 | continue; 208 | } 209 | 210 | if (_wcsicmp(pszFriendlyName, varName.bstrVal) != 0) 211 | { 212 | VariantClear(&varName); 213 | VariantClear(&varName2); 214 | SAFE_RELEASE(pPropBag); 215 | continue; 216 | } 217 | 218 | EventWriteWideStrInfo(M, FL, FN, L"Name", varName.bstrVal); 219 | EventWriteWideStrInfo(M, FL, FN, L"DevPath", varName2.bstrVal); 220 | 221 | (void)StringCchCopy(pszDevPath, cchDevPathSize, varName2.bstrVal); 222 | 223 | VariantClear(&varName); 224 | VariantClear(&varName2); 225 | SAFE_RELEASE(pPropBag); 226 | 227 | *pbSysCam = TRUE; 228 | break; 229 | } 230 | 231 | SAFE_RELEASE(pClassEnum); 232 | SAFE_RELEASE(pDevEnum); 233 | SAFE_RELEASE(pMoniker); 234 | 235 | return hr; 236 | } 237 | 238 | HRESULT SetPrivacy(LONG lNewValue) 239 | { 240 | if (!m_bInitialized) return E_NOT_VALID_STATE; 241 | if (!m_pCameraControl) return E_POINTER; 242 | 243 | EventWriteNumberInfo(M, FL, FN, L"NewValue", lNewValue); 244 | 245 | return m_pCameraControl->Set(KSPROPERTY_CAMERACONTROL_PRIVACY, lNewValue, CameraControl_Flags_Manual); 246 | } 247 | 248 | HRESULT GetPrivacy(LONG *plValue, LONG *plFlags) 249 | { 250 | if (!m_bInitialized) return E_NOT_VALID_STATE; 251 | if (!m_pCameraControl) return E_POINTER; 252 | 253 | HRESULT hr = E_FAIL; 254 | 255 | // 256 | // Note: lValue will be valid only when hr = S_OK. 257 | // 258 | hr = m_pCameraControl->Get(KSPROPERTY_CAMERACONTROL_PRIVACY, plValue, plFlags); 259 | 260 | EventWriteNumberInfo(M, FL, FN, L"Value", *plValue); 261 | EventWriteHexInfo(M, FL, FN, L"Flags", *plFlags); 262 | EventWriteHexInfo(M, FL, FN, L"Status", hr); 263 | 264 | return hr; 265 | } 266 | 267 | HRESULT SetBrightness(LONG lNewValue) 268 | { 269 | if (!m_bInitialized) return E_NOT_VALID_STATE; 270 | return SetVideoProcAmpParameter(KSPROPERTY_VIDEOPROCAMP_BRIGHTNESS, lNewValue); 271 | } 272 | 273 | HRESULT GetBrightness(LONG *plValue, LONG *plFlags) 274 | { 275 | if (!m_bInitialized) return E_NOT_VALID_STATE; 276 | return GetVideoProcAmpParameter(KSPROPERTY_VIDEOPROCAMP_BRIGHTNESS, plValue, plFlags); 277 | } 278 | 279 | HRESULT SetContrast(LONG lNewValue) 280 | { 281 | if (!m_bInitialized) return E_NOT_VALID_STATE; 282 | return SetVideoProcAmpParameter(KSPROPERTY_VIDEOPROCAMP_CONTRAST, lNewValue); 283 | } 284 | 285 | HRESULT GetContrast(LONG *plValue, LONG *plFlags) 286 | { 287 | if (!m_bInitialized) return E_NOT_VALID_STATE; 288 | return GetVideoProcAmpParameter(KSPROPERTY_VIDEOPROCAMP_CONTRAST, plValue, plFlags); 289 | } 290 | 291 | HRESULT SetSaturation(LONG lNewValue) 292 | { 293 | if (!m_bInitialized) return E_NOT_VALID_STATE; 294 | return SetVideoProcAmpParameter(KSPROPERTY_VIDEOPROCAMP_SATURATION, lNewValue); 295 | } 296 | 297 | HRESULT GetSaturation(LONG *plValue, LONG *plFlags) 298 | { 299 | if (!m_bInitialized) return E_NOT_VALID_STATE; 300 | return GetVideoProcAmpParameter(KSPROPERTY_VIDEOPROCAMP_SATURATION, plValue, plFlags); 301 | } 302 | 303 | HRESULT SetExposure(LONG lNewValue) 304 | { 305 | if (!m_bInitialized) return E_NOT_VALID_STATE; 306 | if (!m_pCameraControl) return E_POINTER; 307 | 308 | return m_pCameraControl->Set(KSPROPERTY_CAMERACONTROL_EXPOSURE, lNewValue, KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL); 309 | } 310 | 311 | HRESULT GetExposure(LONG *plValue, LONG *plFlags) 312 | { 313 | if (!m_bInitialized) return E_NOT_VALID_STATE; 314 | if (!m_pCameraControl) return E_POINTER; 315 | 316 | HRESULT hr = E_FAIL; 317 | 318 | // 319 | // Note: lValue will be valid only when hr = S_OK. For exposure, negative values are still valid values. 320 | // 321 | hr = m_pCameraControl->Get(KSPROPERTY_CAMERACONTROL_EXPOSURE, plValue, plFlags); 322 | 323 | EventWriteNumberInfo(M, FL, FN, L"Value", *plValue); 324 | EventWriteHexInfo(M, FL, FN, L"Flags", *plFlags); 325 | EventWriteHexInfo(M, FL, FN, L"Status", hr); 326 | 327 | return hr; 328 | } 329 | 330 | HRESULT SetFlash(CameraFlashEnum newValue) 331 | { 332 | if (!m_bInitialized) return E_NOT_VALID_STATE; 333 | if (!m_pIKsControl) return E_POINTER; 334 | 335 | HRESULT hr = E_FAIL; 336 | 337 | if (m_pIKsControl) 338 | { 339 | ULONG cbRet = 0; 340 | 341 | KSPROPERTY ksProp; 342 | ksProp.Set = PROPSETID_VIDCAP_CAMERACONTROL_FLASH; 343 | ksProp.Id = KSPROPERTY_CAMERACONTROL_FLASH_PROPERTY_ID; 344 | ksProp.Flags = KSPROPERTY_TYPE_SET; 345 | 346 | KSPROPERTY_CAMERACONTROL_FLASH_S ksPropFlash; 347 | ZeroMemory(&ksPropFlash, sizeof(ksPropFlash)); 348 | 349 | switch (newValue) 350 | { 351 | case CameraFlashOff: 352 | ksPropFlash.Flash = KSPROPERTY_CAMERACONTROL_FLASH_OFF; 353 | break; 354 | case CameraFlashOn: 355 | ksPropFlash.Flash = KSPROPERTY_CAMERACONTROL_FLASH_ON; 356 | break; 357 | case CameraFlashAuto: 358 | ksPropFlash.Flash = KSPROPERTY_CAMERACONTROL_FLASH_AUTO; 359 | break; 360 | default: 361 | ksPropFlash.Flash = KSPROPERTY_CAMERACONTROL_FLASH_AUTO; 362 | break; 363 | } 364 | 365 | ksPropFlash.Capabilities = (newValue == CameraFlashAuto) 366 | ? KSPROPERTY_CAMERACONTROL_FLASH_FLAGS_AUTO 367 | : KSPROPERTY_CAMERACONTROL_FLASH_FLAGS_MANUAL; 368 | 369 | hr = m_pIKsControl->KsProperty(&ksProp, sizeof(ksProp), (LPVOID)&ksPropFlash, sizeof(ksPropFlash), &cbRet); 370 | } 371 | 372 | return hr; 373 | } 374 | 375 | HRESULT GetFlash(CameraFlashEnum *pValue, LONG *plFlags) 376 | { 377 | if (!m_bInitialized) return E_NOT_VALID_STATE; 378 | if (!m_pIKsControl) return E_POINTER; 379 | 380 | HRESULT hr = E_FAIL; 381 | 382 | if (m_pIKsControl) 383 | { 384 | ULONG cbRet = 0; 385 | 386 | KSPROPERTY ksProp; 387 | ksProp.Set = PROPSETID_VIDCAP_CAMERACONTROL_FLASH; 388 | ksProp.Id = KSPROPERTY_CAMERACONTROL_FLASH_PROPERTY_ID; 389 | ksProp.Flags = KSPROPERTY_TYPE_GET; 390 | 391 | KSPROPERTY_CAMERACONTROL_FLASH_S ksPropFlash; 392 | ZeroMemory(&ksPropFlash, sizeof(ksPropFlash)); 393 | 394 | hr = m_pIKsControl->KsProperty(&ksProp, sizeof(ksProp), (LPVOID)&ksPropFlash, sizeof(ksPropFlash), &cbRet); 395 | 396 | if (SUCCEEDED(hr)) 397 | { 398 | switch (ksPropFlash.Flash) 399 | { 400 | case KSPROPERTY_CAMERACONTROL_FLASH_OFF: 401 | *pValue = CameraFlashOff; 402 | break; 403 | 404 | case KSPROPERTY_CAMERACONTROL_FLASH_ON: 405 | *pValue = CameraFlashOn; 406 | break; 407 | 408 | case KSPROPERTY_CAMERACONTROL_FLASH_AUTO: 409 | *pValue = CameraFlashAuto; 410 | break; 411 | } 412 | 413 | *plFlags = (LONG)ksPropFlash.Capabilities; 414 | } 415 | } 416 | 417 | return hr; 418 | } 419 | 420 | HRESULT GetBrightnessRange(LONG *plMin, LONG *plMax, LONG *plDelta, LONG *plDefault, LONG *plCaps) 421 | { 422 | if (!m_bInitialized) return E_NOT_VALID_STATE; 423 | return GetVideoProcAmpParameterRange(KSPROPERTY_VIDEOPROCAMP_BRIGHTNESS, plMin, plMax, plDelta, plDefault, plCaps); 424 | } 425 | 426 | HRESULT GetContrastRange(LONG *plMin, LONG *plMax, LONG *plDelta, LONG *plDefault, LONG *plCaps) 427 | { 428 | if (!m_bInitialized) return E_NOT_VALID_STATE; 429 | return GetVideoProcAmpParameterRange(KSPROPERTY_VIDEOPROCAMP_CONTRAST, plMin, plMax, plDelta, plDefault, plCaps); 430 | } 431 | 432 | HRESULT GetSaturationRange(LONG *plMin, LONG *plMax, LONG *plDelta, LONG *plDefault, LONG *plCaps) 433 | { 434 | if (!m_bInitialized) return E_NOT_VALID_STATE; 435 | return GetVideoProcAmpParameterRange(KSPROPERTY_VIDEOPROCAMP_SATURATION, plMin, plMax, plDelta, plDefault, plCaps); 436 | } 437 | 438 | HRESULT GetExposureRange(LONG *plMin, LONG *plMax, LONG *plDelta, LONG *plDefault, LONG *plCaps) 439 | { 440 | if (!m_bInitialized) return E_NOT_VALID_STATE; 441 | if (!m_pCameraControl) return E_POINTER; 442 | 443 | HRESULT hr = E_FAIL; 444 | 445 | // 446 | // Note: lValue will be valid only when hr = S_OK. For exposure, negative values are still valid values. 447 | // 448 | return m_pCameraControl->GetRange(CameraControl_Exposure, plMin, plMax, plDelta, plDefault, plCaps); 449 | } 450 | 451 | HRESULT GetCameraProvider(wchar_t *pszFriendlyName, wchar_t *pszProvider, DWORD cchProvSize) 452 | { 453 | HDEVINFO hDevInfo; 454 | DWORD dwItr = 0; 455 | HRESULT hrReturn = E_FAIL; 456 | SP_DEVINFO_DATA sDeviceInfoData; 457 | wchar_t szProperty[MAX_PATH]; 458 | 459 | hDevInfo = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES); 460 | if (hDevInfo == INVALID_HANDLE_VALUE) return E_FAIL; 461 | 462 | sDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 463 | 464 | while (TRUE) 465 | { 466 | if (SetupDiEnumDeviceInfo(hDevInfo, dwItr, &sDeviceInfoData) == FALSE) break; 467 | 468 | dwItr++; 469 | 470 | HRESULT hr = GetDeviceRegistryPropertyString( 471 | hDevInfo, 472 | &sDeviceInfoData, 473 | SPDRP_FRIENDLYNAME, 474 | szProperty, MAX_PATH); 475 | 476 | if (FAILED(hr)) continue; 477 | 478 | if (_wcsicmp(szProperty, pszFriendlyName) != 0) continue; 479 | 480 | hr = GetDeviceRegistryPropertyString(hDevInfo, &sDeviceInfoData, SPDRP_MFG, szProperty, MAX_PATH); 481 | 482 | if (SUCCEEDED(hr)) 483 | { 484 | (void)StringCchCopy(pszProvider, cchProvSize, szProperty); 485 | hrReturn = S_OK; 486 | break; 487 | } 488 | } 489 | 490 | return hrReturn; 491 | } 492 | 493 | HRESULT DumpCameraInfo(wchar_t *pszFriendlyName) 494 | { 495 | IBaseFilter **ppSrcFilter = &m_pSrcFilter; 496 | HRESULT hr = S_OK; 497 | 498 | IBaseFilter *pSrc = NULL; 499 | IMoniker *pMoniker = NULL; 500 | ICreateDevEnum *pDevEnum = NULL; 501 | IEnumMoniker *pClassEnum = NULL; 502 | ICaptureGraphBuilder2 *pCapGraphBuilder2 = NULL; 503 | IAMStreamConfig *pStreamConf = NULL; 504 | BOOL bDeviceFound = TRUE; 505 | VARIANT varName; 506 | VARIANT varName2; 507 | 508 | if (!ppSrcFilter) return E_POINTER; 509 | 510 | do 511 | { 512 | // 513 | // Create the system device enumerator 514 | // 515 | hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void**)&pDevEnum); 516 | if (FAILED(hr)) return hr; 517 | 518 | // 519 | // Create an enumerator for the video capture devices 520 | // 521 | hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0); 522 | 523 | if (FAILED(hr)) 524 | { 525 | PrintComError(hr, L"CreateClassEnumerator"); 526 | break; 527 | } 528 | 529 | // 530 | // If there are no enumerators for the requested type, then CreateClassEnumerator will succeed, 531 | // but pClassEnum will be NULL. 532 | // 533 | if (pClassEnum == NULL) 534 | { 535 | hr = E_OUTOFMEMORY; 536 | break; 537 | } 538 | 539 | // 540 | // Use the first video capture device on the device list. Note that if the Next() call succeeds but there are no 541 | // monikers, it will return S_FALSE (which is not a failure). Therefore, we check that the return code is S_OK 542 | // instead of using SUCCEEDED() macro. 543 | // 544 | (void)pClassEnum->Reset(); 545 | ULONG cFetched; 546 | 547 | while (hr = pClassEnum->Next(1, &pMoniker, &cFetched), hr == S_OK) 548 | { 549 | IPropertyBag *pPropBag = NULL; 550 | HRESULT hrTmp = E_FAIL; 551 | 552 | #pragma warning(suppress: 6387) 553 | hrTmp = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); 554 | 555 | if (FAILED(hrTmp)) 556 | { 557 | SAFE_RELEASE(pMoniker); 558 | continue; 559 | } 560 | 561 | VariantInit(&varName); 562 | VariantInit(&varName2); 563 | 564 | hrTmp = pPropBag->Read(L"FriendlyName", &varName, 0); 565 | 566 | if (FAILED(hrTmp)) 567 | { 568 | VariantClear(&varName); 569 | VariantClear(&varName2); 570 | SAFE_RELEASE(pPropBag); 571 | continue; 572 | } 573 | 574 | hrTmp = pPropBag->Read(L"DevicePath", &varName2, 0); 575 | 576 | if (FAILED(hrTmp)) 577 | { 578 | VariantClear(&varName); 579 | VariantClear(&varName2); 580 | SAFE_RELEASE(pPropBag); 581 | continue; 582 | } 583 | 584 | if (varName.bstrVal == NULL || varName2.bstrVal == NULL) 585 | { 586 | VariantClear(&varName); 587 | VariantClear(&varName2); 588 | SAFE_RELEASE(pPropBag); 589 | continue; 590 | } 591 | 592 | if (_wcsicmp(pszFriendlyName, varName.bstrVal) != 0) 593 | { 594 | VariantClear(&varName); 595 | VariantClear(&varName2); 596 | SAFE_RELEASE(pPropBag); 597 | continue; 598 | } 599 | 600 | VariantClear(&varName); 601 | VariantClear(&varName2); 602 | SAFE_RELEASE(pPropBag); 603 | 604 | bDeviceFound = TRUE; 605 | break; 606 | } 607 | 608 | if (bDeviceFound) 609 | { 610 | #pragma warning(suppress: 6387) 611 | hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSrc); 612 | 613 | if (FAILED(hr) || pSrc == NULL) 614 | { 615 | EventWriteHresultError(M, FL, FN, L"BindToObject", hr); 616 | } 617 | 618 | *ppSrcFilter = pSrc; 619 | 620 | hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void**)&pCapGraphBuilder2); 621 | 622 | if (FAILED(hr)) 623 | { 624 | EventWriteHresultError(M, FL, FN, L"CoCreateInstance_CLSID_CaptureGraphBuilder2", hr); 625 | break; 626 | } 627 | 628 | hr = pCapGraphBuilder2->FindInterface(&PIN_CATEGORY_CAPTURE, 0, m_pSrcFilter, IID_IAMStreamConfig, (void**)&pStreamConf); 629 | 630 | if (FAILED(hr)) 631 | { 632 | EventWriteHresultError(M, FL, FN, L"FindInterface_IID_IAMStreamConfig", hr); 633 | break; 634 | } 635 | 636 | LONG lWidth[256], lHeight[256]; 637 | int iCount = 0, iSize = 0, iFormat; 638 | 639 | hr = pStreamConf->GetNumberOfCapabilities(&iCount, &iSize); 640 | if (SUCCEEDED(hr)) 641 | { 642 | if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) 643 | { 644 | for (iFormat = 0; iFormat < iCount; iFormat++) 645 | { 646 | VIDEO_STREAM_CONFIG_CAPS scc; 647 | AM_MEDIA_TYPE *pmtConf; 648 | 649 | hr = pStreamConf->GetStreamCaps(iFormat, &pmtConf, (BYTE*)&scc); 650 | if (SUCCEEDED(hr)) 651 | { 652 | m_pVih2 = (VIDEOINFOHEADER*)pmtConf->pbFormat; 653 | 654 | if (m_pVih2->bmiHeader.biHeight && m_pVih2->bmiHeader.biWidth) 655 | { 656 | CHAR c1, c2, c3, c4; 657 | FOURCC_DMP(m_pVih2->bmiHeader.biCompression, &c1, &c2, &c3, &c4); 658 | 659 | UINT32 nume = 0, deno = 0; 660 | MFAverageTimePerFrameToFrameRate(m_pVih2->AvgTimePerFrame, &nume, &deno); 661 | } 662 | 663 | DeleteMediaType(pmtConf); 664 | } 665 | } 666 | } 667 | } 668 | } 669 | else 670 | { 671 | hr = E_FAIL; 672 | } 673 | } while (false); 674 | 675 | SAFE_RELEASE(pMoniker); 676 | SAFE_RELEASE(pStreamConf); 677 | SAFE_RELEASE(pCapGraphBuilder2); 678 | SAFE_RELEASE(pClassEnum); 679 | SAFE_RELEASE(pDevEnum); 680 | 681 | return hr; 682 | } 683 | 684 | HRESULT LaunchPropertiesFrame() 685 | { 686 | if (!m_bInitialized) return E_NOT_VALID_STATE; 687 | 688 | HRESULT hr = E_FAIL; 689 | 690 | if (m_pSrcFilter) 691 | { 692 | ISpecifyPropertyPages *pProp = NULL; 693 | 694 | hr = m_pSrcFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp); 695 | 696 | if (SUCCEEDED(hr)) 697 | { 698 | // 699 | // Get the filter's name and IUnknown pointer. 700 | // 701 | FILTER_INFO filterInfo; 702 | 703 | hr = m_pSrcFilter->QueryFilterInfo(&filterInfo); 704 | 705 | IUnknown *pFilterUnk = NULL; 706 | 707 | m_pSrcFilter->QueryInterface(IID_IUnknown, (void **)&pFilterUnk); 708 | 709 | // 710 | // Show the property page. 711 | // 712 | CAUUID caGUID; 713 | 714 | pProp->GetPages(&caGUID); 715 | pProp->Release(); 716 | 717 | hr = OleCreatePropertyFrame( 718 | NULL, // Parent window 719 | 0, 0, // Reserved 720 | filterInfo.achName, // Caption for the dialog box 721 | 1, // Number of objects (just the filter) 722 | &pFilterUnk, // Array of object pointers. 723 | caGUID.cElems, // Number of property pages 724 | caGUID.pElems, // Array of property page CLSIDs 725 | 0, // Locale identifier 726 | 0, NULL); // Reserved 727 | 728 | if (FAILED(hr)) 729 | { 730 | EventWriteHresultError(M, FL, FN, L"HrError OleCreatePropertyFrame", hr); 731 | } 732 | 733 | // 734 | // Clean up. 735 | // 736 | if (pFilterUnk) pFilterUnk->Release(); 737 | if (filterInfo.pGraph) filterInfo.pGraph->Release(); 738 | CoTaskMemFree(caGUID.pElems); 739 | } 740 | } 741 | 742 | return hr; 743 | } 744 | 745 | HRESULT CloseInterfaces() 746 | { 747 | if (m_bInitialized) 748 | { 749 | // 750 | // Stop previewing data 751 | // 752 | if (m_pMediaCtrl) m_pMediaCtrl->StopWhenReady(); 753 | 754 | // 755 | // Relinquish ownership (IMPORTANT!) of the video window. 756 | // Failing to call put_Owner can lead to assert failures within 757 | // the video renderer, as it still assumes that it has a valid 758 | // parent window. 759 | // 760 | 761 | // 762 | // Release DirectShow interfaces 763 | // 764 | SAFE_RELEASE(m_pIKsControl); 765 | SAFE_RELEASE(m_pMediaCtrl); 766 | SAFE_RELEASE(m_pStrmConfig); 767 | SAFE_RELEASE(m_pGraphBldr); 768 | SAFE_RELEASE(m_pCapGraphBldr); 769 | SAFE_RELEASE(m_pSampleGrabberFilter); 770 | SAFE_RELEASE(m_pCameraControl); 771 | SAFE_RELEASE(m_pVideoProcAmp); 772 | SAFE_RELEASE(m_pSrcFilter); 773 | 774 | m_bInitialized = FALSE; 775 | } 776 | 777 | return S_OK; 778 | } 779 | 780 | private: 781 | HRESULT SetVideoProcAmpParameter(LONG lProperty, LONG lValue) 782 | { 783 | if (!m_pVideoProcAmp) return E_POINTER; 784 | return m_pVideoProcAmp->Set(lProperty, lValue, KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL); 785 | } 786 | 787 | HRESULT GetVideoProcAmpParameter(LONG lProperty, LONG *plValue, LONG *plFlags) 788 | { 789 | if (!m_pVideoProcAmp) return E_POINTER; 790 | return m_pVideoProcAmp->Get(lProperty, plValue, plFlags); 791 | } 792 | 793 | HRESULT GetVideoProcAmpParameterRange(LONG lProperty, LONG *plMin, LONG *plMax, LONG *plDelta, LONG *plDefault, LONG *plFlags) 794 | { 795 | if (!m_pVideoProcAmp) return E_POINTER; 796 | return m_pVideoProcAmp->GetRange(lProperty, plMin, plMax, plDelta, plDefault, plFlags); 797 | } 798 | 799 | HRESULT FindCaptureDevice(wchar_t *pszFriendlyName) 800 | { 801 | IBaseFilter **ppSrcFilter = &m_pSrcFilter; 802 | HRESULT hr = S_OK; 803 | int iNumVidList = 0; 804 | 805 | IBaseFilter *pSrc = NULL; 806 | IMoniker* pMoniker = NULL; 807 | ICreateDevEnum *pDevEnum = NULL; 808 | IEnumMoniker *pClassEnum = NULL; 809 | 810 | BOOL bDeviceFound = FALSE; 811 | VARIANT varName; 812 | VARIANT varName2; 813 | 814 | if (!ppSrcFilter) return E_POINTER; 815 | 816 | // 817 | // Create the system device enumerator 818 | // 819 | hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void**)&pDevEnum); 820 | if (FAILED(hr)) return hr; 821 | 822 | // 823 | // Create an enumerator for the video capture devices 824 | // 825 | hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0); 826 | if (FAILED(hr)) 827 | { 828 | SAFE_RELEASE(pDevEnum); 829 | return hr; 830 | } 831 | 832 | // 833 | // If there are no enumerators for the requested type, then CreateClassEnumerator will succeed, 834 | // but pClassEnum will be NULL. 835 | // 836 | if (pClassEnum == NULL) 837 | { 838 | SAFE_RELEASE(pClassEnum); 839 | SAFE_RELEASE(pDevEnum); 840 | hr = E_FAIL; 841 | return hr; 842 | } 843 | 844 | // 845 | // Use the first video capture device on the device list. Note that if the Next() call succeeds but there are no 846 | // monikers, it will return S_FALSE (which is not a failure). Therefore, we check that the return code is S_OK 847 | // instead of using SUCCEEDED() macro. 848 | // 849 | pClassEnum->Reset(); 850 | ULONG cFetched; 851 | 852 | while (hr = pClassEnum->Next(1, &pMoniker, &cFetched), hr == S_OK) 853 | { 854 | IPropertyBag *pPropBag = NULL; 855 | HRESULT result = E_FAIL; 856 | 857 | #pragma warning(suppress: 6387) 858 | result = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); 859 | if (FAILED(result)) 860 | { 861 | SAFE_RELEASE(pMoniker); 862 | continue; 863 | } 864 | 865 | VariantInit(&varName); 866 | VariantInit(&varName2); 867 | 868 | result = pPropBag->Read(L"FriendlyName", &varName, 0); 869 | if (FAILED(result)) 870 | { 871 | VariantClear(&varName); 872 | VariantClear(&varName2); 873 | SAFE_RELEASE(pPropBag); 874 | continue; 875 | } 876 | 877 | result = pPropBag->Read(L"DevicePath", &varName2, 0); 878 | if (FAILED(result)) 879 | { 880 | VariantClear(&varName); 881 | VariantClear(&varName2); 882 | SAFE_RELEASE(pPropBag); 883 | continue; 884 | } 885 | 886 | if (varName.bstrVal == NULL || varName2.bstrVal == NULL) 887 | { 888 | VariantClear(&varName); 889 | VariantClear(&varName2); 890 | SAFE_RELEASE(pPropBag); 891 | continue; 892 | } 893 | 894 | if (_wcsicmp(pszFriendlyName, varName.bstrVal) != 0) 895 | { 896 | VariantClear(&varName); 897 | VariantClear(&varName2); 898 | SAFE_RELEASE(pPropBag); 899 | continue; 900 | } 901 | 902 | VariantClear(&varName); 903 | VariantClear(&varName2); 904 | SAFE_RELEASE(pPropBag); 905 | 906 | bDeviceFound = TRUE; 907 | break; 908 | } 909 | 910 | SAFE_RELEASE(pClassEnum); 911 | SAFE_RELEASE(pDevEnum); 912 | 913 | if (bDeviceFound) 914 | { 915 | #pragma warning(suppress: 6387) 916 | hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSrc); 917 | 918 | if (FAILED(hr)) 919 | { 920 | EventWriteHresultError(M, FL, FN, L"BindToObject", hr); 921 | } 922 | 923 | *ppSrcFilter = pSrc; 924 | 925 | hr = m_pSrcFilter->QueryInterface(IID_IAMCameraControl, (void**)&m_pCameraControl); 926 | 927 | if (hr != S_OK) 928 | { 929 | m_pCameraControl = NULL; 930 | } 931 | 932 | hr = m_pSrcFilter->QueryInterface(IID_IAMVideoProcAmp, (void**)&m_pVideoProcAmp); 933 | 934 | if (hr != S_OK) 935 | { 936 | m_pVideoProcAmp = NULL; 937 | } 938 | 939 | hr = m_pSrcFilter->QueryInterface(IID_IKsControl, (void**)&m_pIKsControl); 940 | 941 | if (hr != S_OK) 942 | { 943 | m_pIKsControl = NULL; 944 | } 945 | } 946 | else 947 | { 948 | hr = E_FAIL; 949 | } 950 | 951 | SAFE_RELEASE(pMoniker); 952 | 953 | return hr; 954 | } 955 | 956 | HRESULT GetInterfaces() 957 | { 958 | HRESULT hr = S_OK; 959 | 960 | hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void**)&m_pGraphBldr); 961 | 962 | if (FAILED(hr)) 963 | { 964 | return hr; 965 | } 966 | 967 | // 968 | // Create the capture graph builder 969 | // 970 | hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void**)&m_pCapGraphBldr); 971 | 972 | if (FAILED(hr)) 973 | { 974 | return hr; 975 | } 976 | 977 | // 978 | // Obtain interfaces for media control and Video Window 979 | // 980 | hr = m_pGraphBldr->QueryInterface(IID_IMediaControl, (LPVOID*)&m_pMediaCtrl); 981 | 982 | if (FAILED(hr)) 983 | { 984 | m_pMediaCtrl = NULL; 985 | return hr; 986 | } 987 | 988 | hr = m_pCapGraphBldr->FindInterface(&PIN_CATEGORY_CAPTURE, 0, m_pSrcFilter, IID_IAMStreamConfig, (void**)&m_pStrmConfig); 989 | 990 | if (FAILED(hr)) 991 | { 992 | m_pStrmConfig = NULL; 993 | return hr; 994 | } 995 | 996 | return hr; 997 | } 998 | 999 | HRESULT GetDeviceRegistryPropertyString( 1000 | HDEVINFO hDeviceInfoSet, 1001 | PSP_DEVINFO_DATA pDeviceInfoData, 1002 | DWORD dwProperty, 1003 | wchar_t *pszText, 1004 | DWORD cchTextSize) 1005 | { 1006 | BOOL bStatus = FALSE; 1007 | DWORD dwDataType; 1008 | DWORD dwDataSize; 1009 | BYTE* pData; 1010 | 1011 | if (pszText == NULL) return E_POINTER; 1012 | 1013 | pData = NULL; 1014 | dwDataSize = 0; 1015 | 1016 | while (TRUE) 1017 | { 1018 | bStatus = SetupDiGetDeviceRegistryProperty( 1019 | hDeviceInfoSet, 1020 | pDeviceInfoData, 1021 | dwProperty, 1022 | &dwDataType, 1023 | pData, 1024 | dwDataSize, 1025 | &dwDataSize); 1026 | 1027 | if (bStatus || GetLastError() != ERROR_INSUFFICIENT_BUFFER) break; 1028 | 1029 | if (pData) delete[] pData; 1030 | 1031 | pData = new BYTE[dwDataSize]; 1032 | } 1033 | 1034 | if (bStatus && pData) 1035 | { 1036 | if (dwDataType == REG_EXPAND_SZ || dwDataType == REG_MULTI_SZ || dwDataType == REG_SZ) 1037 | { 1038 | StringCchCopy(pszText, cchTextSize, (wchar_t*)pData); 1039 | } 1040 | } 1041 | 1042 | if (pData) delete[] pData; 1043 | 1044 | return (bStatus && pData) ? S_OK : E_FAIL; 1045 | } 1046 | 1047 | void FreeMediaType(AM_MEDIA_TYPE& mt) 1048 | { 1049 | if (mt.cbFormat != 0) 1050 | { 1051 | CoTaskMemFree((PVOID)mt.pbFormat); 1052 | mt.cbFormat = 0; 1053 | mt.pbFormat = NULL; 1054 | } 1055 | 1056 | SAFE_RELEASE(mt.pUnk); 1057 | } 1058 | 1059 | void DeleteMediaType(AM_MEDIA_TYPE *pmt) 1060 | { 1061 | if (pmt) 1062 | { 1063 | FreeMediaType(*pmt); 1064 | CoTaskMemFree(pmt); 1065 | pmt = NULL; 1066 | } 1067 | } 1068 | 1069 | private: 1070 | IBaseFilter *m_pSrcFilter; 1071 | IGraphBuilder *m_pGraphBldr; 1072 | ICaptureGraphBuilder2 *m_pCapGraphBldr; 1073 | IAMCameraControl *m_pCameraControl; 1074 | IAMVideoProcAmp *m_pVideoProcAmp; 1075 | IMediaControl *m_pMediaCtrl; 1076 | IAMStreamConfig *m_pStrmConfig; 1077 | IBaseFilter *m_pSampleGrabberFilter; 1078 | IKsControl *m_pIKsControl; 1079 | VIDEOINFOHEADER *m_pVih2; 1080 | BOOL m_bInitialized; 1081 | LONG m_lRefCount; 1082 | }; 1083 | 1084 | // 1085 | // Our exported CameraDs factory function. 1086 | // 1087 | _declspec(dllexport) HRESULT CreateCameraDsInstance(ICameraDs **ppObj) 1088 | { 1089 | if (ppObj == NULL) return E_POINTER; 1090 | 1091 | ICameraDs *pObj = new (std::nothrow) CameraDs(); 1092 | 1093 | if (pObj == NULL) return E_OUTOFMEMORY; 1094 | 1095 | *ppObj = pObj; 1096 | 1097 | (*ppObj)->AddRef(); 1098 | 1099 | return S_OK; 1100 | } -------------------------------------------------------------------------------- /etw/jytrace.h: -------------------------------------------------------------------------------- 1 | //**********************************************************************` 2 | //* This is an include file generated by Message Compiler. *` 3 | //* *` 4 | //* Copyright (c) Microsoft Corporation. All Rights Reserved. *` 5 | //**********************************************************************` 6 | #pragma once 7 | #include 8 | #include 9 | #include "evntprov.h" 10 | // 11 | // Initial Defs 12 | // 13 | #if !defined(ETW_INLINE) 14 | #define ETW_INLINE DECLSPEC_NOINLINE __inline 15 | #endif 16 | 17 | #if defined(__cplusplus) 18 | extern "C" { 19 | #endif 20 | 21 | // 22 | // Allow Diasabling of code generation 23 | // 24 | #ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION 25 | #if !defined(McGenDebug) 26 | #define McGenDebug(a,b) 27 | #endif 28 | 29 | 30 | #if !defined(MCGEN_TRACE_CONTEXT_DEF) 31 | #define MCGEN_TRACE_CONTEXT_DEF 32 | typedef struct _MCGEN_TRACE_CONTEXT 33 | { 34 | TRACEHANDLE RegistrationHandle; 35 | TRACEHANDLE Logger; 36 | ULONGLONG MatchAnyKeyword; 37 | ULONGLONG MatchAllKeyword; 38 | ULONG Flags; 39 | ULONG IsEnabled; 40 | UCHAR Level; 41 | UCHAR Reserve; 42 | USHORT EnableBitsCount; 43 | PULONG EnableBitMask; 44 | const ULONGLONG* EnableKeyWords; 45 | const UCHAR* EnableLevel; 46 | } MCGEN_TRACE_CONTEXT, *PMCGEN_TRACE_CONTEXT; 47 | #endif 48 | 49 | #if !defined(MCGEN_LEVEL_KEYWORD_ENABLED_DEF) 50 | #define MCGEN_LEVEL_KEYWORD_ENABLED_DEF 51 | FORCEINLINE 52 | BOOLEAN 53 | McGenLevelKeywordEnabled( 54 | _In_ PMCGEN_TRACE_CONTEXT EnableInfo, 55 | _In_ UCHAR Level, 56 | _In_ ULONGLONG Keyword 57 | ) 58 | { 59 | // 60 | // Check if the event Level is lower than the level at which 61 | // the channel is enabled. 62 | // If the event Level is 0 or the channel is enabled at level 0, 63 | // all levels are enabled. 64 | // 65 | 66 | if ((Level <= EnableInfo->Level) || // This also covers the case of Level == 0. 67 | (EnableInfo->Level == 0)) { 68 | 69 | // 70 | // Check if Keyword is enabled 71 | // 72 | 73 | if ((Keyword == (ULONGLONG)0) || 74 | ((Keyword & EnableInfo->MatchAnyKeyword) && 75 | ((Keyword & EnableInfo->MatchAllKeyword) == EnableInfo->MatchAllKeyword))) { 76 | return TRUE; 77 | } 78 | } 79 | 80 | return FALSE; 81 | 82 | } 83 | #endif 84 | 85 | #if !defined(MCGEN_EVENT_ENABLED_DEF) 86 | #define MCGEN_EVENT_ENABLED_DEF 87 | FORCEINLINE 88 | BOOLEAN 89 | McGenEventEnabled( 90 | _In_ PMCGEN_TRACE_CONTEXT EnableInfo, 91 | _In_ PCEVENT_DESCRIPTOR EventDescriptor 92 | ) 93 | { 94 | 95 | return McGenLevelKeywordEnabled(EnableInfo, EventDescriptor->Level, EventDescriptor->Keyword); 96 | 97 | } 98 | #endif 99 | 100 | 101 | // 102 | // EnableCheckMacro 103 | // 104 | #ifndef MCGEN_ENABLE_CHECK 105 | #define MCGEN_ENABLE_CHECK(Context, Descriptor) (Context.IsEnabled && McGenEventEnabled(&Context, &Descriptor)) 106 | #endif 107 | 108 | #if !defined(MCGEN_CONTROL_CALLBACK) 109 | #define MCGEN_CONTROL_CALLBACK 110 | 111 | DECLSPEC_NOINLINE __inline 112 | VOID 113 | __stdcall 114 | McGenControlCallbackV2( 115 | _In_ LPCGUID SourceId, 116 | _In_ ULONG ControlCode, 117 | _In_ UCHAR Level, 118 | _In_ ULONGLONG MatchAnyKeyword, 119 | _In_ ULONGLONG MatchAllKeyword, 120 | _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData, 121 | _Inout_opt_ PVOID CallbackContext 122 | ) 123 | /*++ 124 | 125 | Routine Description: 126 | 127 | This is the notification callback for Vista. 128 | 129 | Arguments: 130 | 131 | SourceId - The GUID that identifies the session that enabled the provider. 132 | 133 | ControlCode - The parameter indicates whether the provider 134 | is being enabled or disabled. 135 | 136 | Level - The level at which the event is enabled. 137 | 138 | MatchAnyKeyword - The bitmask of keywords that the provider uses to 139 | determine the category of events that it writes. 140 | 141 | MatchAllKeyword - This bitmask additionally restricts the category 142 | of events that the provider writes. 143 | 144 | FilterData - The provider-defined data. 145 | 146 | CallbackContext - The context of the callback that is defined when the provider 147 | called EtwRegister to register itself. 148 | 149 | Remarks: 150 | 151 | ETW calls this function to notify provider of enable/disable 152 | 153 | --*/ 154 | { 155 | PMCGEN_TRACE_CONTEXT Ctx = (PMCGEN_TRACE_CONTEXT)CallbackContext; 156 | ULONG Ix; 157 | #ifndef MCGEN_PRIVATE_ENABLE_CALLBACK_V2 158 | UNREFERENCED_PARAMETER(SourceId); 159 | UNREFERENCED_PARAMETER(FilterData); 160 | #endif 161 | 162 | if (Ctx == NULL) { 163 | return; 164 | } 165 | 166 | switch (ControlCode) { 167 | 168 | case EVENT_CONTROL_CODE_ENABLE_PROVIDER: 169 | Ctx->Level = Level; 170 | Ctx->MatchAnyKeyword = MatchAnyKeyword; 171 | Ctx->MatchAllKeyword = MatchAllKeyword; 172 | Ctx->IsEnabled = EVENT_CONTROL_CODE_ENABLE_PROVIDER; 173 | 174 | for (Ix = 0; Ix < Ctx->EnableBitsCount; Ix += 1) { 175 | if (McGenLevelKeywordEnabled(Ctx, Ctx->EnableLevel[Ix], Ctx->EnableKeyWords[Ix]) != FALSE) { 176 | Ctx->EnableBitMask[Ix >> 5] |= (1 << (Ix % 32)); 177 | } else { 178 | Ctx->EnableBitMask[Ix >> 5] &= ~(1 << (Ix % 32)); 179 | } 180 | } 181 | break; 182 | 183 | case EVENT_CONTROL_CODE_DISABLE_PROVIDER: 184 | Ctx->IsEnabled = EVENT_CONTROL_CODE_DISABLE_PROVIDER; 185 | Ctx->Level = 0; 186 | Ctx->MatchAnyKeyword = 0; 187 | Ctx->MatchAllKeyword = 0; 188 | if (Ctx->EnableBitsCount > 0) { 189 | RtlZeroMemory(Ctx->EnableBitMask, (((Ctx->EnableBitsCount - 1) / 32) + 1) * sizeof(ULONG)); 190 | } 191 | break; 192 | 193 | default: 194 | break; 195 | } 196 | 197 | #ifdef MCGEN_PRIVATE_ENABLE_CALLBACK_V2 198 | // 199 | // Call user defined callback 200 | // 201 | MCGEN_PRIVATE_ENABLE_CALLBACK_V2( 202 | SourceId, 203 | ControlCode, 204 | Level, 205 | MatchAnyKeyword, 206 | MatchAllKeyword, 207 | FilterData, 208 | CallbackContext 209 | ); 210 | #endif 211 | 212 | return; 213 | } 214 | 215 | #endif 216 | #endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION 217 | //+ 218 | // Provider JyTrace Event Count 25 219 | //+ 220 | EXTERN_C __declspec(selectany) const GUID ProviderJyTrace = {0x277c604b, 0x1962, 0x47fa, {0x93, 0x07, 0x7c, 0xe0, 0x85, 0x5d, 0xfe, 0xa6}}; 221 | 222 | // 223 | // Channel 224 | // 225 | #define ProviderJyTrace_CHANNEL_Application 0x9 226 | // 227 | // Keyword 228 | // 229 | #define KeywordFunctionEntryExit 0x1 230 | #define KeywordGeneric 0x2 231 | 232 | // 233 | // Event Descriptors 234 | // 235 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR FunctionEntry = {0x65, 0x0, 0x0, 0x5, 0x0, 0x0, 0x1}; 236 | #define FunctionEntry_value 0x65 237 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR FunctionExit = {0x66, 0x0, 0x0, 0x5, 0x0, 0x0, 0x1}; 238 | #define FunctionExit_value 0x66 239 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR InfoW = {0x67, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2}; 240 | #define InfoW_value 0x67 241 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ErrorW = {0x68, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2}; 242 | #define ErrorW_value 0x68 243 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR InfoA = {0x69, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2}; 244 | #define InfoA_value 0x69 245 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ErrorA = {0x6a, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2}; 246 | #define ErrorA_value 0x6a 247 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR WideStrInfo = {0x6b, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2}; 248 | #define WideStrInfo_value 0x6b 249 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR WideStrError = {0x6c, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2}; 250 | #define WideStrError_value 0x6c 251 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR AnsiStrInfo = {0x6d, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2}; 252 | #define AnsiStrInfo_value 0x6d 253 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR AnsiStrError = {0x6e, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2}; 254 | #define AnsiStrError_value 0x6e 255 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR HresultError = {0x6f, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2}; 256 | #define HresultError_value 0x6f 257 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR LastError = {0x70, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2}; 258 | #define LastError_value 0x70 259 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR PointerInfo = {0x71, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2}; 260 | #define PointerInfo_value 0x71 261 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR PointerError = {0x72, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2}; 262 | #define PointerError_value 0x72 263 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NumberInfo = {0x73, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2}; 264 | #define NumberInfo_value 0x73 265 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NumberError = {0x74, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2}; 266 | #define NumberError_value 0x74 267 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR HexInfo = {0x75, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2}; 268 | #define HexInfo_value 0x75 269 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR HexError = {0x76, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2}; 270 | #define HexError_value 0x76 271 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR BoolInfo = {0x77, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2}; 272 | #define BoolInfo_value 0x77 273 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR BoolError = {0x78, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2}; 274 | #define BoolError_value 0x78 275 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR GuidInfo = {0x79, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2}; 276 | #define GuidInfo_value 0x79 277 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR GuidError = {0x7a, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2}; 278 | #define GuidError_value 0x7a 279 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR FloatInfo = {0x7b, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2}; 280 | #define FloatInfo_value 0x7b 281 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR FloatError = {0x7c, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2}; 282 | #define FloatError_value 0x7c 283 | EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Simple = {0x7d, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2}; 284 | #define Simple_value 0x7d 285 | 286 | // 287 | // Note on Generate Code from Manifest Windows Vista and above 288 | // 289 | //Structures : are handled as a size and pointer pairs. The macro for the event will have an extra 290 | //parameter for the size in bytes of the structure. Make sure that your structures have no extra padding. 291 | // 292 | //Strings: There are several cases that can be described in the manifest. For array of variable length 293 | //strings, the generated code will take the count of characters for the whole array as an input parameter. 294 | // 295 | //SID No support for array of SIDs, the macro will take a pointer to the SID and use appropriate 296 | //GetLengthSid function to get the length. 297 | // 298 | 299 | // 300 | // Allow Diasabling of code generation 301 | // 302 | #ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION 303 | 304 | // 305 | // Globals 306 | // 307 | 308 | 309 | // 310 | // Event Enablement Bits 311 | // 312 | 313 | EXTERN_C __declspec(selectany) DECLSPEC_CACHEALIGN ULONG JyTraceEnableBits[1]; 314 | EXTERN_C __declspec(selectany) const ULONGLONG JyTraceKeywords[3] = {0x1, 0x2, 0x2}; 315 | EXTERN_C __declspec(selectany) const UCHAR JyTraceLevels[3] = {5, 5, 2}; 316 | EXTERN_C __declspec(selectany) MCGEN_TRACE_CONTEXT ProviderJyTrace_Context = {0, 0, 0, 0, 0, 0, 0, 0, 3, JyTraceEnableBits, JyTraceKeywords, JyTraceLevels}; 317 | 318 | EXTERN_C __declspec(selectany) REGHANDLE JyTraceHandle = (REGHANDLE)0; 319 | 320 | #if !defined(McGenEventRegisterUnregister) 321 | #define McGenEventRegisterUnregister 322 | #pragma warning(push) 323 | #pragma warning(disable:6103) 324 | DECLSPEC_NOINLINE __inline 325 | ULONG __stdcall 326 | McGenEventRegister( 327 | _In_ LPCGUID ProviderId, 328 | _In_opt_ PENABLECALLBACK EnableCallback, 329 | _In_opt_ PVOID CallbackContext, 330 | _Inout_ PREGHANDLE RegHandle 331 | ) 332 | /*++ 333 | 334 | Routine Description: 335 | 336 | This function register the provider with ETW USER mode. 337 | 338 | Arguments: 339 | ProviderId - Provider Id to be register with ETW. 340 | 341 | EnableCallback - Callback to be used. 342 | 343 | CallbackContext - Context for this provider. 344 | 345 | RegHandle - Pointer to Registration handle. 346 | 347 | Remarks: 348 | 349 | If the handle != NULL will return ERROR_SUCCESS 350 | 351 | --*/ 352 | { 353 | ULONG Error; 354 | 355 | 356 | if (*RegHandle) { 357 | // 358 | // already registered 359 | // 360 | return ERROR_SUCCESS; 361 | } 362 | 363 | Error = EventRegister( ProviderId, EnableCallback, CallbackContext, RegHandle); 364 | 365 | return Error; 366 | } 367 | #pragma warning(pop) 368 | 369 | 370 | DECLSPEC_NOINLINE __inline 371 | ULONG __stdcall 372 | McGenEventUnregister(_Inout_ PREGHANDLE RegHandle) 373 | /*++ 374 | 375 | Routine Description: 376 | 377 | Unregister from ETW USER mode 378 | 379 | Arguments: 380 | RegHandle this is the pointer to the provider context 381 | Remarks: 382 | If Provider has not register RegHandle = NULL, 383 | return ERROR_SUCCESS 384 | --*/ 385 | { 386 | ULONG Error; 387 | 388 | 389 | if(!(*RegHandle)) { 390 | // 391 | // Provider has not registerd 392 | // 393 | return ERROR_SUCCESS; 394 | } 395 | 396 | Error = EventUnregister(*RegHandle); 397 | *RegHandle = (REGHANDLE)0; 398 | 399 | return Error; 400 | } 401 | #endif 402 | // 403 | // Register with ETW Vista + 404 | // 405 | #ifndef EventRegisterJyTrace 406 | #define EventRegisterJyTrace() McGenEventRegister(&ProviderJyTrace, McGenControlCallbackV2, &ProviderJyTrace_Context, &JyTraceHandle) 407 | #endif 408 | 409 | // 410 | // UnRegister with ETW 411 | // 412 | #ifndef EventUnregisterJyTrace 413 | #define EventUnregisterJyTrace() McGenEventUnregister(&JyTraceHandle) 414 | #endif 415 | 416 | // 417 | // Enablement check macro for FunctionEntry 418 | // 419 | 420 | #define EventEnabledFunctionEntry() ((JyTraceEnableBits[0] & 0x00000001) != 0) 421 | 422 | // 423 | // Event Macro for FunctionEntry 424 | // 425 | #define EventWriteFunctionEntry(Module, File, Function)\ 426 | EventEnabledFunctionEntry() ?\ 427 | Template_zss(JyTraceHandle, &FunctionEntry, Module, File, Function)\ 428 | : ERROR_SUCCESS\ 429 | 430 | // 431 | // Enablement check macro for FunctionExit 432 | // 433 | 434 | #define EventEnabledFunctionExit() ((JyTraceEnableBits[0] & 0x00000001) != 0) 435 | 436 | // 437 | // Event Macro for FunctionExit 438 | // 439 | #define EventWriteFunctionExit(Module, File, Function)\ 440 | EventEnabledFunctionExit() ?\ 441 | Template_zss(JyTraceHandle, &FunctionExit, Module, File, Function)\ 442 | : ERROR_SUCCESS\ 443 | 444 | // 445 | // Enablement check macro for InfoW 446 | // 447 | 448 | #define EventEnabledInfoW() ((JyTraceEnableBits[0] & 0x00000002) != 0) 449 | 450 | // 451 | // Event Macro for InfoW 452 | // 453 | #define EventWriteInfoW(Module, File, Function, Value)\ 454 | EventEnabledInfoW() ?\ 455 | Template_zssz(JyTraceHandle, &InfoW, Module, File, Function, Value)\ 456 | : ERROR_SUCCESS\ 457 | 458 | // 459 | // Enablement check macro for ErrorW 460 | // 461 | 462 | #define EventEnabledErrorW() ((JyTraceEnableBits[0] & 0x00000004) != 0) 463 | 464 | // 465 | // Event Macro for ErrorW 466 | // 467 | #define EventWriteErrorW(Module, File, Function, Value)\ 468 | EventEnabledErrorW() ?\ 469 | Template_zssz(JyTraceHandle, &ErrorW, Module, File, Function, Value)\ 470 | : ERROR_SUCCESS\ 471 | 472 | // 473 | // Enablement check macro for InfoA 474 | // 475 | 476 | #define EventEnabledInfoA() ((JyTraceEnableBits[0] & 0x00000002) != 0) 477 | 478 | // 479 | // Event Macro for InfoA 480 | // 481 | #define EventWriteInfoA(Module, File, Function, Value)\ 482 | EventEnabledInfoA() ?\ 483 | Template_zsss(JyTraceHandle, &InfoA, Module, File, Function, Value)\ 484 | : ERROR_SUCCESS\ 485 | 486 | // 487 | // Enablement check macro for ErrorA 488 | // 489 | 490 | #define EventEnabledErrorA() ((JyTraceEnableBits[0] & 0x00000004) != 0) 491 | 492 | // 493 | // Event Macro for ErrorA 494 | // 495 | #define EventWriteErrorA(Module, File, Function, Value)\ 496 | EventEnabledErrorA() ?\ 497 | Template_zsss(JyTraceHandle, &ErrorA, Module, File, Function, Value)\ 498 | : ERROR_SUCCESS\ 499 | 500 | // 501 | // Enablement check macro for WideStrInfo 502 | // 503 | 504 | #define EventEnabledWideStrInfo() ((JyTraceEnableBits[0] & 0x00000002) != 0) 505 | 506 | // 507 | // Event Macro for WideStrInfo 508 | // 509 | #define EventWriteWideStrInfo(Module, File, Function, Key, Value)\ 510 | EventEnabledWideStrInfo() ?\ 511 | Template_zsszz(JyTraceHandle, &WideStrInfo, Module, File, Function, Key, Value)\ 512 | : ERROR_SUCCESS\ 513 | 514 | // 515 | // Enablement check macro for WideStrError 516 | // 517 | 518 | #define EventEnabledWideStrError() ((JyTraceEnableBits[0] & 0x00000004) != 0) 519 | 520 | // 521 | // Event Macro for WideStrError 522 | // 523 | #define EventWriteWideStrError(Module, File, Function, Key, Value)\ 524 | EventEnabledWideStrError() ?\ 525 | Template_zsszz(JyTraceHandle, &WideStrError, Module, File, Function, Key, Value)\ 526 | : ERROR_SUCCESS\ 527 | 528 | // 529 | // Enablement check macro for AnsiStrInfo 530 | // 531 | 532 | #define EventEnabledAnsiStrInfo() ((JyTraceEnableBits[0] & 0x00000002) != 0) 533 | 534 | // 535 | // Event Macro for AnsiStrInfo 536 | // 537 | #define EventWriteAnsiStrInfo(Module, File, Function, Key, Value)\ 538 | EventEnabledAnsiStrInfo() ?\ 539 | Template_zsszs(JyTraceHandle, &AnsiStrInfo, Module, File, Function, Key, Value)\ 540 | : ERROR_SUCCESS\ 541 | 542 | // 543 | // Enablement check macro for AnsiStrError 544 | // 545 | 546 | #define EventEnabledAnsiStrError() ((JyTraceEnableBits[0] & 0x00000004) != 0) 547 | 548 | // 549 | // Event Macro for AnsiStrError 550 | // 551 | #define EventWriteAnsiStrError(Module, File, Function, Key, Value)\ 552 | EventEnabledAnsiStrError() ?\ 553 | Template_zsszs(JyTraceHandle, &AnsiStrError, Module, File, Function, Key, Value)\ 554 | : ERROR_SUCCESS\ 555 | 556 | // 557 | // Enablement check macro for HresultError 558 | // 559 | 560 | #define EventEnabledHresultError() ((JyTraceEnableBits[0] & 0x00000004) != 0) 561 | 562 | // 563 | // Event Macro for HresultError 564 | // 565 | #define EventWriteHresultError(Module, File, Function, Key, Value)\ 566 | EventEnabledHresultError() ?\ 567 | Template_zsszd(JyTraceHandle, &HresultError, Module, File, Function, Key, Value)\ 568 | : ERROR_SUCCESS\ 569 | 570 | // 571 | // Enablement check macro for LastError 572 | // 573 | 574 | #define EventEnabledLastError() ((JyTraceEnableBits[0] & 0x00000004) != 0) 575 | 576 | // 577 | // Event Macro for LastError 578 | // 579 | #define EventWriteLastError(Module, File, Function, Key, Value)\ 580 | EventEnabledLastError() ?\ 581 | Template_zsszq(JyTraceHandle, &LastError, Module, File, Function, Key, Value)\ 582 | : ERROR_SUCCESS\ 583 | 584 | // 585 | // Enablement check macro for PointerInfo 586 | // 587 | 588 | #define EventEnabledPointerInfo() ((JyTraceEnableBits[0] & 0x00000002) != 0) 589 | 590 | // 591 | // Event Macro for PointerInfo 592 | // 593 | #define EventWritePointerInfo(Module, File, Function, Key, Value)\ 594 | EventEnabledPointerInfo() ?\ 595 | Template_zsszp(JyTraceHandle, &PointerInfo, Module, File, Function, Key, Value)\ 596 | : ERROR_SUCCESS\ 597 | 598 | // 599 | // Enablement check macro for PointerError 600 | // 601 | 602 | #define EventEnabledPointerError() ((JyTraceEnableBits[0] & 0x00000004) != 0) 603 | 604 | // 605 | // Event Macro for PointerError 606 | // 607 | #define EventWritePointerError(Module, File, Function, Key, Value)\ 608 | EventEnabledPointerError() ?\ 609 | Template_zsszp(JyTraceHandle, &PointerError, Module, File, Function, Key, Value)\ 610 | : ERROR_SUCCESS\ 611 | 612 | // 613 | // Enablement check macro for NumberInfo 614 | // 615 | 616 | #define EventEnabledNumberInfo() ((JyTraceEnableBits[0] & 0x00000002) != 0) 617 | 618 | // 619 | // Event Macro for NumberInfo 620 | // 621 | #define EventWriteNumberInfo(Module, File, Function, Key, Value)\ 622 | EventEnabledNumberInfo() ?\ 623 | Template_zsszd(JyTraceHandle, &NumberInfo, Module, File, Function, Key, Value)\ 624 | : ERROR_SUCCESS\ 625 | 626 | // 627 | // Enablement check macro for NumberError 628 | // 629 | 630 | #define EventEnabledNumberError() ((JyTraceEnableBits[0] & 0x00000004) != 0) 631 | 632 | // 633 | // Event Macro for NumberError 634 | // 635 | #define EventWriteNumberError(Module, File, Function, Key, Value)\ 636 | EventEnabledNumberError() ?\ 637 | Template_zsszd(JyTraceHandle, &NumberError, Module, File, Function, Key, Value)\ 638 | : ERROR_SUCCESS\ 639 | 640 | // 641 | // Enablement check macro for HexInfo 642 | // 643 | 644 | #define EventEnabledHexInfo() ((JyTraceEnableBits[0] & 0x00000002) != 0) 645 | 646 | // 647 | // Event Macro for HexInfo 648 | // 649 | #define EventWriteHexInfo(Module, File, Function, Key, Value)\ 650 | EventEnabledHexInfo() ?\ 651 | Template_zsszq(JyTraceHandle, &HexInfo, Module, File, Function, Key, Value)\ 652 | : ERROR_SUCCESS\ 653 | 654 | // 655 | // Enablement check macro for HexError 656 | // 657 | 658 | #define EventEnabledHexError() ((JyTraceEnableBits[0] & 0x00000004) != 0) 659 | 660 | // 661 | // Event Macro for HexError 662 | // 663 | #define EventWriteHexError(Module, File, Function, Key, Value)\ 664 | EventEnabledHexError() ?\ 665 | Template_zsszq(JyTraceHandle, &HexError, Module, File, Function, Key, Value)\ 666 | : ERROR_SUCCESS\ 667 | 668 | // 669 | // Enablement check macro for BoolInfo 670 | // 671 | 672 | #define EventEnabledBoolInfo() ((JyTraceEnableBits[0] & 0x00000002) != 0) 673 | 674 | // 675 | // Event Macro for BoolInfo 676 | // 677 | #define EventWriteBoolInfo(Module, File, Function, Key, Value)\ 678 | EventEnabledBoolInfo() ?\ 679 | Template_zsszt(JyTraceHandle, &BoolInfo, Module, File, Function, Key, Value)\ 680 | : ERROR_SUCCESS\ 681 | 682 | // 683 | // Enablement check macro for BoolError 684 | // 685 | 686 | #define EventEnabledBoolError() ((JyTraceEnableBits[0] & 0x00000004) != 0) 687 | 688 | // 689 | // Event Macro for BoolError 690 | // 691 | #define EventWriteBoolError(Module, File, Function, Key, Value)\ 692 | EventEnabledBoolError() ?\ 693 | Template_zsszt(JyTraceHandle, &BoolError, Module, File, Function, Key, Value)\ 694 | : ERROR_SUCCESS\ 695 | 696 | // 697 | // Enablement check macro for GuidInfo 698 | // 699 | 700 | #define EventEnabledGuidInfo() ((JyTraceEnableBits[0] & 0x00000002) != 0) 701 | 702 | // 703 | // Event Macro for GuidInfo 704 | // 705 | #define EventWriteGuidInfo(Module, File, Function, Key, Value)\ 706 | EventEnabledGuidInfo() ?\ 707 | Template_zsszj(JyTraceHandle, &GuidInfo, Module, File, Function, Key, Value)\ 708 | : ERROR_SUCCESS\ 709 | 710 | // 711 | // Enablement check macro for GuidError 712 | // 713 | 714 | #define EventEnabledGuidError() ((JyTraceEnableBits[0] & 0x00000004) != 0) 715 | 716 | // 717 | // Event Macro for GuidError 718 | // 719 | #define EventWriteGuidError(Module, File, Function, Key, Value)\ 720 | EventEnabledGuidError() ?\ 721 | Template_zsszj(JyTraceHandle, &GuidError, Module, File, Function, Key, Value)\ 722 | : ERROR_SUCCESS\ 723 | 724 | // 725 | // Enablement check macro for FloatInfo 726 | // 727 | 728 | #define EventEnabledFloatInfo() ((JyTraceEnableBits[0] & 0x00000002) != 0) 729 | 730 | // 731 | // Event Macro for FloatInfo 732 | // 733 | #define EventWriteFloatInfo(Module, File, Function, Key, Value)\ 734 | EventEnabledFloatInfo() ?\ 735 | Template_zsszf(JyTraceHandle, &FloatInfo, Module, File, Function, Key, Value)\ 736 | : ERROR_SUCCESS\ 737 | 738 | // 739 | // Enablement check macro for FloatError 740 | // 741 | 742 | #define EventEnabledFloatError() ((JyTraceEnableBits[0] & 0x00000004) != 0) 743 | 744 | // 745 | // Event Macro for FloatError 746 | // 747 | #define EventWriteFloatError(Module, File, Function, Key, Value)\ 748 | EventEnabledFloatError() ?\ 749 | Template_zsszf(JyTraceHandle, &FloatError, Module, File, Function, Key, Value)\ 750 | : ERROR_SUCCESS\ 751 | 752 | // 753 | // Enablement check macro for Simple 754 | // 755 | 756 | #define EventEnabledSimple() ((JyTraceEnableBits[0] & 0x00000002) != 0) 757 | 758 | // 759 | // Event Macro for Simple 760 | // 761 | #define EventWriteSimple(Module, File, Function, Key, Value)\ 762 | EventEnabledSimple() ?\ 763 | Template_zzzzz(JyTraceHandle, &Simple, Module, File, Function, Key, Value)\ 764 | : ERROR_SUCCESS\ 765 | 766 | #endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION 767 | 768 | 769 | // 770 | // Allow Diasabling of code generation 771 | // 772 | #ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION 773 | 774 | // 775 | // Template Functions 776 | // 777 | // 778 | //Template from manifest : TemplateFunctionEntryExit 779 | // 780 | #ifndef Template_zss_def 781 | #define Template_zss_def 782 | ETW_INLINE 783 | ULONG 784 | Template_zss( 785 | _In_ REGHANDLE RegHandle, 786 | _In_ PCEVENT_DESCRIPTOR Descriptor, 787 | _In_opt_ PCWSTR _Arg0, 788 | _In_opt_ LPCSTR _Arg1, 789 | _In_opt_ LPCSTR _Arg2 790 | ) 791 | { 792 | #define ARGUMENT_COUNT_zss 3 793 | 794 | EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zss]; 795 | 796 | EventDataDescCreate(&EventData[0], 797 | (_Arg0 != NULL) ? _Arg0 : L"NULL", 798 | (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 799 | 800 | EventDataDescCreate(&EventData[1], 801 | (_Arg1 != NULL) ? _Arg1 : "NULL", 802 | (_Arg1 != NULL) ? (ULONG)((strlen(_Arg1) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 803 | 804 | EventDataDescCreate(&EventData[2], 805 | (_Arg2 != NULL) ? _Arg2 : "NULL", 806 | (_Arg2 != NULL) ? (ULONG)((strlen(_Arg2) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 807 | 808 | return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zss, EventData); 809 | } 810 | #endif 811 | 812 | // 813 | //Template from manifest : TemplateSingleWide 814 | // 815 | #ifndef Template_zssz_def 816 | #define Template_zssz_def 817 | ETW_INLINE 818 | ULONG 819 | Template_zssz( 820 | _In_ REGHANDLE RegHandle, 821 | _In_ PCEVENT_DESCRIPTOR Descriptor, 822 | _In_opt_ PCWSTR _Arg0, 823 | _In_opt_ LPCSTR _Arg1, 824 | _In_opt_ LPCSTR _Arg2, 825 | _In_opt_ PCWSTR _Arg3 826 | ) 827 | { 828 | #define ARGUMENT_COUNT_zssz 4 829 | 830 | EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zssz]; 831 | 832 | EventDataDescCreate(&EventData[0], 833 | (_Arg0 != NULL) ? _Arg0 : L"NULL", 834 | (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 835 | 836 | EventDataDescCreate(&EventData[1], 837 | (_Arg1 != NULL) ? _Arg1 : "NULL", 838 | (_Arg1 != NULL) ? (ULONG)((strlen(_Arg1) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 839 | 840 | EventDataDescCreate(&EventData[2], 841 | (_Arg2 != NULL) ? _Arg2 : "NULL", 842 | (_Arg2 != NULL) ? (ULONG)((strlen(_Arg2) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 843 | 844 | EventDataDescCreate(&EventData[3], 845 | (_Arg3 != NULL) ? _Arg3 : L"NULL", 846 | (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 847 | 848 | return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zssz, EventData); 849 | } 850 | #endif 851 | 852 | // 853 | //Template from manifest : TemplateSingleAnsi 854 | // 855 | #ifndef Template_zsss_def 856 | #define Template_zsss_def 857 | ETW_INLINE 858 | ULONG 859 | Template_zsss( 860 | _In_ REGHANDLE RegHandle, 861 | _In_ PCEVENT_DESCRIPTOR Descriptor, 862 | _In_opt_ PCWSTR _Arg0, 863 | _In_opt_ LPCSTR _Arg1, 864 | _In_opt_ LPCSTR _Arg2, 865 | _In_opt_ LPCSTR _Arg3 866 | ) 867 | { 868 | #define ARGUMENT_COUNT_zsss 4 869 | 870 | EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zsss]; 871 | 872 | EventDataDescCreate(&EventData[0], 873 | (_Arg0 != NULL) ? _Arg0 : L"NULL", 874 | (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 875 | 876 | EventDataDescCreate(&EventData[1], 877 | (_Arg1 != NULL) ? _Arg1 : "NULL", 878 | (_Arg1 != NULL) ? (ULONG)((strlen(_Arg1) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 879 | 880 | EventDataDescCreate(&EventData[2], 881 | (_Arg2 != NULL) ? _Arg2 : "NULL", 882 | (_Arg2 != NULL) ? (ULONG)((strlen(_Arg2) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 883 | 884 | EventDataDescCreate(&EventData[3], 885 | (_Arg3 != NULL) ? _Arg3 : "NULL", 886 | (_Arg3 != NULL) ? (ULONG)((strlen(_Arg3) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 887 | 888 | return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zsss, EventData); 889 | } 890 | #endif 891 | 892 | // 893 | //Template from manifest : TemplateKeyValueWide 894 | // 895 | #ifndef Template_zsszz_def 896 | #define Template_zsszz_def 897 | ETW_INLINE 898 | ULONG 899 | Template_zsszz( 900 | _In_ REGHANDLE RegHandle, 901 | _In_ PCEVENT_DESCRIPTOR Descriptor, 902 | _In_opt_ PCWSTR _Arg0, 903 | _In_opt_ LPCSTR _Arg1, 904 | _In_opt_ LPCSTR _Arg2, 905 | _In_opt_ PCWSTR _Arg3, 906 | _In_opt_ PCWSTR _Arg4 907 | ) 908 | { 909 | #define ARGUMENT_COUNT_zsszz 5 910 | 911 | EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zsszz]; 912 | 913 | EventDataDescCreate(&EventData[0], 914 | (_Arg0 != NULL) ? _Arg0 : L"NULL", 915 | (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 916 | 917 | EventDataDescCreate(&EventData[1], 918 | (_Arg1 != NULL) ? _Arg1 : "NULL", 919 | (_Arg1 != NULL) ? (ULONG)((strlen(_Arg1) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 920 | 921 | EventDataDescCreate(&EventData[2], 922 | (_Arg2 != NULL) ? _Arg2 : "NULL", 923 | (_Arg2 != NULL) ? (ULONG)((strlen(_Arg2) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 924 | 925 | EventDataDescCreate(&EventData[3], 926 | (_Arg3 != NULL) ? _Arg3 : L"NULL", 927 | (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 928 | 929 | EventDataDescCreate(&EventData[4], 930 | (_Arg4 != NULL) ? _Arg4 : L"NULL", 931 | (_Arg4 != NULL) ? (ULONG)((wcslen(_Arg4) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 932 | 933 | return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zsszz, EventData); 934 | } 935 | #endif 936 | 937 | // 938 | //Template from manifest : TemplateKeyValueAnsi 939 | // 940 | #ifndef Template_zsszs_def 941 | #define Template_zsszs_def 942 | ETW_INLINE 943 | ULONG 944 | Template_zsszs( 945 | _In_ REGHANDLE RegHandle, 946 | _In_ PCEVENT_DESCRIPTOR Descriptor, 947 | _In_opt_ PCWSTR _Arg0, 948 | _In_opt_ LPCSTR _Arg1, 949 | _In_opt_ LPCSTR _Arg2, 950 | _In_opt_ PCWSTR _Arg3, 951 | _In_opt_ LPCSTR _Arg4 952 | ) 953 | { 954 | #define ARGUMENT_COUNT_zsszs 5 955 | 956 | EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zsszs]; 957 | 958 | EventDataDescCreate(&EventData[0], 959 | (_Arg0 != NULL) ? _Arg0 : L"NULL", 960 | (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 961 | 962 | EventDataDescCreate(&EventData[1], 963 | (_Arg1 != NULL) ? _Arg1 : "NULL", 964 | (_Arg1 != NULL) ? (ULONG)((strlen(_Arg1) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 965 | 966 | EventDataDescCreate(&EventData[2], 967 | (_Arg2 != NULL) ? _Arg2 : "NULL", 968 | (_Arg2 != NULL) ? (ULONG)((strlen(_Arg2) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 969 | 970 | EventDataDescCreate(&EventData[3], 971 | (_Arg3 != NULL) ? _Arg3 : L"NULL", 972 | (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 973 | 974 | EventDataDescCreate(&EventData[4], 975 | (_Arg4 != NULL) ? _Arg4 : "NULL", 976 | (_Arg4 != NULL) ? (ULONG)((strlen(_Arg4) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 977 | 978 | return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zsszs, EventData); 979 | } 980 | #endif 981 | 982 | // 983 | //Template from manifest : TemplateKeyValueHresult 984 | // 985 | #ifndef Template_zsszd_def 986 | #define Template_zsszd_def 987 | ETW_INLINE 988 | ULONG 989 | Template_zsszd( 990 | _In_ REGHANDLE RegHandle, 991 | _In_ PCEVENT_DESCRIPTOR Descriptor, 992 | _In_opt_ PCWSTR _Arg0, 993 | _In_opt_ LPCSTR _Arg1, 994 | _In_opt_ LPCSTR _Arg2, 995 | _In_opt_ PCWSTR _Arg3, 996 | _In_ const signed int _Arg4 997 | ) 998 | { 999 | #define ARGUMENT_COUNT_zsszd 5 1000 | 1001 | EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zsszd]; 1002 | 1003 | EventDataDescCreate(&EventData[0], 1004 | (_Arg0 != NULL) ? _Arg0 : L"NULL", 1005 | (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1006 | 1007 | EventDataDescCreate(&EventData[1], 1008 | (_Arg1 != NULL) ? _Arg1 : "NULL", 1009 | (_Arg1 != NULL) ? (ULONG)((strlen(_Arg1) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 1010 | 1011 | EventDataDescCreate(&EventData[2], 1012 | (_Arg2 != NULL) ? _Arg2 : "NULL", 1013 | (_Arg2 != NULL) ? (ULONG)((strlen(_Arg2) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 1014 | 1015 | EventDataDescCreate(&EventData[3], 1016 | (_Arg3 != NULL) ? _Arg3 : L"NULL", 1017 | (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1018 | 1019 | EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const signed int) ); 1020 | 1021 | return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zsszd, EventData); 1022 | } 1023 | #endif 1024 | 1025 | // 1026 | //Template from manifest : TemplateKeyValueLastError 1027 | // 1028 | #ifndef Template_zsszq_def 1029 | #define Template_zsszq_def 1030 | ETW_INLINE 1031 | ULONG 1032 | Template_zsszq( 1033 | _In_ REGHANDLE RegHandle, 1034 | _In_ PCEVENT_DESCRIPTOR Descriptor, 1035 | _In_opt_ PCWSTR _Arg0, 1036 | _In_opt_ LPCSTR _Arg1, 1037 | _In_opt_ LPCSTR _Arg2, 1038 | _In_opt_ PCWSTR _Arg3, 1039 | _In_ const unsigned int _Arg4 1040 | ) 1041 | { 1042 | #define ARGUMENT_COUNT_zsszq 5 1043 | 1044 | EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zsszq]; 1045 | 1046 | EventDataDescCreate(&EventData[0], 1047 | (_Arg0 != NULL) ? _Arg0 : L"NULL", 1048 | (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1049 | 1050 | EventDataDescCreate(&EventData[1], 1051 | (_Arg1 != NULL) ? _Arg1 : "NULL", 1052 | (_Arg1 != NULL) ? (ULONG)((strlen(_Arg1) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 1053 | 1054 | EventDataDescCreate(&EventData[2], 1055 | (_Arg2 != NULL) ? _Arg2 : "NULL", 1056 | (_Arg2 != NULL) ? (ULONG)((strlen(_Arg2) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 1057 | 1058 | EventDataDescCreate(&EventData[3], 1059 | (_Arg3 != NULL) ? _Arg3 : L"NULL", 1060 | (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1061 | 1062 | EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const unsigned int) ); 1063 | 1064 | return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zsszq, EventData); 1065 | } 1066 | #endif 1067 | 1068 | // 1069 | //Template from manifest : TemplateKeyValuePtr 1070 | // 1071 | #ifndef Template_zsszp_def 1072 | #define Template_zsszp_def 1073 | ETW_INLINE 1074 | ULONG 1075 | Template_zsszp( 1076 | _In_ REGHANDLE RegHandle, 1077 | _In_ PCEVENT_DESCRIPTOR Descriptor, 1078 | _In_opt_ PCWSTR _Arg0, 1079 | _In_opt_ LPCSTR _Arg1, 1080 | _In_opt_ LPCSTR _Arg2, 1081 | _In_opt_ PCWSTR _Arg3, 1082 | _In_opt_ const void * _Arg4 1083 | ) 1084 | { 1085 | #define ARGUMENT_COUNT_zsszp 5 1086 | 1087 | EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zsszp]; 1088 | 1089 | EventDataDescCreate(&EventData[0], 1090 | (_Arg0 != NULL) ? _Arg0 : L"NULL", 1091 | (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1092 | 1093 | EventDataDescCreate(&EventData[1], 1094 | (_Arg1 != NULL) ? _Arg1 : "NULL", 1095 | (_Arg1 != NULL) ? (ULONG)((strlen(_Arg1) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 1096 | 1097 | EventDataDescCreate(&EventData[2], 1098 | (_Arg2 != NULL) ? _Arg2 : "NULL", 1099 | (_Arg2 != NULL) ? (ULONG)((strlen(_Arg2) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 1100 | 1101 | EventDataDescCreate(&EventData[3], 1102 | (_Arg3 != NULL) ? _Arg3 : L"NULL", 1103 | (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1104 | 1105 | EventDataDescCreate(&EventData[4], &_Arg4, sizeof(PVOID) ); 1106 | 1107 | return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zsszp, EventData); 1108 | } 1109 | #endif 1110 | 1111 | // 1112 | //Template from manifest : TemplateKeyValueBool 1113 | // 1114 | #ifndef Template_zsszt_def 1115 | #define Template_zsszt_def 1116 | ETW_INLINE 1117 | ULONG 1118 | Template_zsszt( 1119 | _In_ REGHANDLE RegHandle, 1120 | _In_ PCEVENT_DESCRIPTOR Descriptor, 1121 | _In_opt_ PCWSTR _Arg0, 1122 | _In_opt_ LPCSTR _Arg1, 1123 | _In_opt_ LPCSTR _Arg2, 1124 | _In_opt_ PCWSTR _Arg3, 1125 | _In_ const BOOL _Arg4 1126 | ) 1127 | { 1128 | #define ARGUMENT_COUNT_zsszt 5 1129 | 1130 | EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zsszt]; 1131 | 1132 | EventDataDescCreate(&EventData[0], 1133 | (_Arg0 != NULL) ? _Arg0 : L"NULL", 1134 | (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1135 | 1136 | EventDataDescCreate(&EventData[1], 1137 | (_Arg1 != NULL) ? _Arg1 : "NULL", 1138 | (_Arg1 != NULL) ? (ULONG)((strlen(_Arg1) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 1139 | 1140 | EventDataDescCreate(&EventData[2], 1141 | (_Arg2 != NULL) ? _Arg2 : "NULL", 1142 | (_Arg2 != NULL) ? (ULONG)((strlen(_Arg2) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 1143 | 1144 | EventDataDescCreate(&EventData[3], 1145 | (_Arg3 != NULL) ? _Arg3 : L"NULL", 1146 | (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1147 | 1148 | EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const BOOL) ); 1149 | 1150 | return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zsszt, EventData); 1151 | } 1152 | #endif 1153 | 1154 | // 1155 | //Template from manifest : TemplateKeyValueGuid 1156 | // 1157 | #ifndef Template_zsszj_def 1158 | #define Template_zsszj_def 1159 | ETW_INLINE 1160 | ULONG 1161 | Template_zsszj( 1162 | _In_ REGHANDLE RegHandle, 1163 | _In_ PCEVENT_DESCRIPTOR Descriptor, 1164 | _In_opt_ PCWSTR _Arg0, 1165 | _In_opt_ LPCSTR _Arg1, 1166 | _In_opt_ LPCSTR _Arg2, 1167 | _In_opt_ PCWSTR _Arg3, 1168 | _In_ LPCGUID _Arg4 1169 | ) 1170 | { 1171 | #define ARGUMENT_COUNT_zsszj 5 1172 | 1173 | EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zsszj]; 1174 | 1175 | EventDataDescCreate(&EventData[0], 1176 | (_Arg0 != NULL) ? _Arg0 : L"NULL", 1177 | (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1178 | 1179 | EventDataDescCreate(&EventData[1], 1180 | (_Arg1 != NULL) ? _Arg1 : "NULL", 1181 | (_Arg1 != NULL) ? (ULONG)((strlen(_Arg1) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 1182 | 1183 | EventDataDescCreate(&EventData[2], 1184 | (_Arg2 != NULL) ? _Arg2 : "NULL", 1185 | (_Arg2 != NULL) ? (ULONG)((strlen(_Arg2) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 1186 | 1187 | EventDataDescCreate(&EventData[3], 1188 | (_Arg3 != NULL) ? _Arg3 : L"NULL", 1189 | (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1190 | 1191 | EventDataDescCreate(&EventData[4], _Arg4, sizeof(GUID) ); 1192 | 1193 | return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zsszj, EventData); 1194 | } 1195 | #endif 1196 | 1197 | // 1198 | //Template from manifest : TemplateKeyValueFloat 1199 | // 1200 | #ifndef Template_zsszf_def 1201 | #define Template_zsszf_def 1202 | ETW_INLINE 1203 | ULONG 1204 | Template_zsszf( 1205 | _In_ REGHANDLE RegHandle, 1206 | _In_ PCEVENT_DESCRIPTOR Descriptor, 1207 | _In_opt_ PCWSTR _Arg0, 1208 | _In_opt_ LPCSTR _Arg1, 1209 | _In_opt_ LPCSTR _Arg2, 1210 | _In_opt_ PCWSTR _Arg3, 1211 | _In_ const float _Arg4 1212 | ) 1213 | { 1214 | #define ARGUMENT_COUNT_zsszf 5 1215 | 1216 | EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zsszf]; 1217 | 1218 | EventDataDescCreate(&EventData[0], 1219 | (_Arg0 != NULL) ? _Arg0 : L"NULL", 1220 | (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1221 | 1222 | EventDataDescCreate(&EventData[1], 1223 | (_Arg1 != NULL) ? _Arg1 : "NULL", 1224 | (_Arg1 != NULL) ? (ULONG)((strlen(_Arg1) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 1225 | 1226 | EventDataDescCreate(&EventData[2], 1227 | (_Arg2 != NULL) ? _Arg2 : "NULL", 1228 | (_Arg2 != NULL) ? (ULONG)((strlen(_Arg2) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); 1229 | 1230 | EventDataDescCreate(&EventData[3], 1231 | (_Arg3 != NULL) ? _Arg3 : L"NULL", 1232 | (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1233 | 1234 | EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const float) ); 1235 | 1236 | return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zsszf, EventData); 1237 | } 1238 | #endif 1239 | 1240 | // 1241 | //Template from manifest : TemplateNetSimple 1242 | // 1243 | #ifndef Template_zzzzz_def 1244 | #define Template_zzzzz_def 1245 | ETW_INLINE 1246 | ULONG 1247 | Template_zzzzz( 1248 | _In_ REGHANDLE RegHandle, 1249 | _In_ PCEVENT_DESCRIPTOR Descriptor, 1250 | _In_opt_ PCWSTR _Arg0, 1251 | _In_opt_ PCWSTR _Arg1, 1252 | _In_opt_ PCWSTR _Arg2, 1253 | _In_opt_ PCWSTR _Arg3, 1254 | _In_opt_ PCWSTR _Arg4 1255 | ) 1256 | { 1257 | #define ARGUMENT_COUNT_zzzzz 5 1258 | 1259 | EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zzzzz]; 1260 | 1261 | EventDataDescCreate(&EventData[0], 1262 | (_Arg0 != NULL) ? _Arg0 : L"NULL", 1263 | (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1264 | 1265 | EventDataDescCreate(&EventData[1], 1266 | (_Arg1 != NULL) ? _Arg1 : L"NULL", 1267 | (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1268 | 1269 | EventDataDescCreate(&EventData[2], 1270 | (_Arg2 != NULL) ? _Arg2 : L"NULL", 1271 | (_Arg2 != NULL) ? (ULONG)((wcslen(_Arg2) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1272 | 1273 | EventDataDescCreate(&EventData[3], 1274 | (_Arg3 != NULL) ? _Arg3 : L"NULL", 1275 | (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1276 | 1277 | EventDataDescCreate(&EventData[4], 1278 | (_Arg4 != NULL) ? _Arg4 : L"NULL", 1279 | (_Arg4 != NULL) ? (ULONG)((wcslen(_Arg4) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); 1280 | 1281 | return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zzzzz, EventData); 1282 | } 1283 | #endif 1284 | 1285 | #endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION 1286 | 1287 | #if defined(__cplusplus) 1288 | }; 1289 | #endif 1290 | 1291 | #define MSG_level_Error 0x50000002L 1292 | #define MSG_level_Verbose 0x50000005L 1293 | #define MSG_channel_Application 0x90000001L 1294 | #define MSG_jenkins_event_101_message 0xB0000065L 1295 | #define MSG_jenkins_event_102_message 0xB0000066L 1296 | #define MSG_jenkins_event_119_message 0xB0000067L 1297 | #define MSG_jenkins_event_120_message 0xB0000068L 1298 | #define MSG_jenkins_event_121_message 0xB0000069L 1299 | #define MSG_jenkins_event_122_message 0xB000006AL 1300 | #define MSG_jenkins_event_103_message 0xB000006BL 1301 | #define MSG_jenkins_event_104_message 0xB000006DL 1302 | #define MSG_jenkins_event_105_message 0xB000006FL 1303 | #define MSG_jenkins_event_106_message 0xB0000070L 1304 | #define MSG_jenkins_event_107_message 0xB0000071L 1305 | #define MSG_jenkins_event_110_message 0xB0000073L 1306 | #define MSG_jenkins_event_111_message 0xB0000075L 1307 | #define MSG_jenkins_event_112_message 0xB0000077L 1308 | #define MSG_jenkins_event_113_message 0xB0000079L 1309 | #define MSG_jenkins_event_123_message 0xB000007BL 1310 | #define MSG_jenkins_event_124_message 0xB000007CL 1311 | #define MSG_JyTrace_event_125_message 0xB000007DL 1312 | -------------------------------------------------------------------------------- /libcore/libcameramf.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016 Chew Esmero 3 | * All rights reserved. 4 | */ 5 | 6 | #include "stdafx.h" 7 | #include 8 | #include 9 | #include 10 | #include "..\include\libcamera.h" 11 | #include "..\include\libcore.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "..\include\sdktrace.h" 18 | #include "..\etw\jytrace.h" 19 | 20 | #pragma comment(lib,"WtsApi32.lib") 21 | #pragma comment(lib,"UserEnv.lib") 22 | #pragma comment(lib,"mfplat.lib") 23 | #pragma comment(lib,"mf.lib") 24 | #pragma comment(lib,"mfreadwrite.lib") 25 | #pragma comment(lib,"mfuuid.lib") 26 | #pragma comment(lib,"shlwapi.lib") 27 | 28 | _declspec(dllexport) HRESULT GetDefaultImageStride(IMFMediaType *pType, LONG *plStride) 29 | { 30 | LONG lStride = 0; 31 | 32 | // 33 | // Try to get the default stride from the media type. 34 | // 35 | HRESULT hr = pType->GetUINT32(MF_MT_DEFAULT_STRIDE, (UINT32*)&lStride); 36 | 37 | if (FAILED(hr)) 38 | { 39 | GUID subType = GUID_NULL; 40 | UINT32 width = 0; 41 | UINT32 height = 0; 42 | 43 | // 44 | // Get the subtype and the image size. 45 | // 46 | hr = pType->GetGUID(MF_MT_SUBTYPE, &subType); 47 | if (SUCCEEDED(hr)) hr = MFGetAttributeSize(pType, MF_MT_FRAME_SIZE, &width, &height); 48 | if (SUCCEEDED(hr)) hr = MFGetStrideForBitmapInfoHeader(subType.Data1, width, &lStride); 49 | 50 | // 51 | // Set the attribute for later reference. 52 | // 53 | if (SUCCEEDED(hr)) (void)pType->SetUINT32(MF_MT_DEFAULT_STRIDE, UINT32(lStride)); 54 | } 55 | 56 | if (SUCCEEDED(hr)) *plStride = lStride; 57 | 58 | return hr; 59 | } 60 | 61 | typedef HRESULT(*COPY_TRANSFORM_FN)(BYTE*, LONG, BYTE*, LONG, UINT, UINT); 62 | 63 | struct ChooseDeviceParam { 64 | IMFActivate **ppDevices; // Array of IMFActivate pointers. 65 | UINT32 count; // Number of elements in the array. 66 | UINT32 selection; // Selected device, by array index. 67 | }; 68 | 69 | struct ConversionFunction { 70 | BOOL bSelect; 71 | GUID guidSubType; 72 | LPCWSTR pwszGuidSubType; 73 | COPY_TRANSFORM_FN FnCopyTransform; 74 | }; 75 | 76 | ConversionFunction FormatConversions[] = { 77 | /* Uncompressed RGB formats */ 78 | { FALSE, MFVideoFormat_RGB8, L"MFVideoFormat_RGB8", NULL }, 79 | { FALSE, MFVideoFormat_RGB555, L"MFVideoFormat_RGB555", NULL }, 80 | { FALSE, MFVideoFormat_RGB565, L"MFVideoFormat_RGB565", NULL }, 81 | { FALSE, MFVideoFormat_RGB32, L"MFVideoFormat_RGB32", NULL }, 82 | { FALSE, MFVideoFormat_RGB24, L"MFVideoFormat_RGB24", NULL }, 83 | { FALSE, MFVideoFormat_ARGB32, L"MFVideoFormat_ARGB32", NULL }, 84 | /* YUV Formats: 8-Bit and Palettized */ 85 | { FALSE, MFVideoFormat_AI44, L"MFVideoFormat_AI44", NULL }, 86 | { FALSE, MFVideoFormat_AYUV, L"MFVideoFormat_AYUV", NULL }, 87 | { FALSE, MFVideoFormat_I420, L"MFVideoFormat_I420", NULL }, 88 | { FALSE, MFVideoFormat_IYUV, L"MFVideoFormat_IYUV", NULL }, 89 | { FALSE, MFVideoFormat_NV11, L"MFVideoFormat_NV11", NULL }, 90 | { FALSE, MFVideoFormat_NV12, L"MFVideoFormat_NV12", NULL }, 91 | { FALSE, MFVideoFormat_UYVY, L"MFVideoFormat_UYVY", NULL }, 92 | { FALSE, MFVideoFormat_Y41P, L"MFVideoFormat_Y41P", NULL }, 93 | { FALSE, MFVideoFormat_Y41T, L"MFVideoFormat_Y41T", NULL }, 94 | { FALSE, MFVideoFormat_Y42T, L"MFVideoFormat_Y42T", NULL }, 95 | { FALSE, MFVideoFormat_YUY2, L"MFVideoFormat_YUY2", NULL /*FnCopyYUY2ToRGB32*/ }, 96 | { FALSE, MFVideoFormat_YV12, L"MFVideoFormat_YV12", NULL }, 97 | /* YUV Formats: 10-Bit and 16-Bit */ 98 | { FALSE, MFVideoFormat_P010, L"MFVideoFormat_P010", NULL }, 99 | { FALSE, MFVideoFormat_P016, L"MFVideoFormat_P016", NULL }, 100 | { FALSE, MFVideoFormat_P210, L"MFVideoFormat_P210", NULL }, 101 | { FALSE, MFVideoFormat_P216, L"MFVideoFormat_P216", NULL }, 102 | { FALSE, MFVideoFormat_v210, L"MFVideoFormat_v210", NULL }, 103 | { FALSE, MFVideoFormat_v216, L"MFVideoFormat_v216", NULL }, 104 | { FALSE, MFVideoFormat_v410, L"MFVideoFormat_v410", NULL }, 105 | { FALSE, MFVideoFormat_Y210, L"MFVideoFormat_Y210", NULL }, 106 | { FALSE, MFVideoFormat_Y216, L"MFVideoFormat_Y216", NULL }, 107 | { FALSE, MFVideoFormat_Y410, L"MFVideoFormat_Y410", NULL }, 108 | { FALSE, MFVideoFormat_Y416, L"MFVideoFormat_Y416", NULL }, 109 | /* Encoded Video Types */ 110 | { FALSE, MFVideoFormat_DV25, L"MFVideoFormat_DV25", NULL }, 111 | { FALSE, MFVideoFormat_DV50, L"MFVideoFormat_DV50", NULL }, 112 | { FALSE, MFVideoFormat_DVC, L"MFVideoFormat_DVC", NULL }, 113 | { FALSE, MFVideoFormat_DVH1, L"MFVideoFormat_DVH1", NULL }, 114 | { FALSE, MFVideoFormat_DVHD, L"MFVideoFormat_DVHD", NULL }, 115 | { FALSE, MFVideoFormat_DVSD, L"MFVideoFormat_DVSD", NULL }, 116 | { FALSE, MFVideoFormat_DVSL, L"MFVideoFormat_DVSL", NULL }, 117 | { FALSE, MFVideoFormat_H264, L"MFVideoFormat_H264", NULL }, 118 | { FALSE, MFVideoFormat_M4S2, L"MFVideoFormat_M4S2", NULL }, 119 | { FALSE, MFVideoFormat_MJPG, L"MFVideoFormat_MJPG", NULL }, 120 | { FALSE, MFVideoFormat_MP43, L"MFVideoFormat_MP43", NULL }, 121 | { FALSE, MFVideoFormat_MP4S, L"MFVideoFormat_MP4S", NULL }, 122 | { FALSE, MFVideoFormat_MP4V, L"MFVideoFormat_MP4V", NULL }, 123 | { FALSE, MFVideoFormat_MPEG2, L"MFVideoFormat_MPEG2", NULL }, 124 | { FALSE, MFVideoFormat_MPG1, L"MFVideoFormat_MPG1", NULL }, 125 | { FALSE, MFVideoFormat_MSS1, L"MFVideoFormat_MSS1", NULL }, 126 | { FALSE, MFVideoFormat_MSS2, L"MFVideoFormat_MSS2", NULL }, 127 | { FALSE, MFVideoFormat_WMV1, L"MFVideoFormat_WMV1", NULL }, 128 | { FALSE, MFVideoFormat_WMV2, L"MFVideoFormat_WMV2", NULL }, 129 | { FALSE, MFVideoFormat_WMV3, L"MFVideoFormat_WMV3", NULL }, 130 | { FALSE, MFVideoFormat_WVC1, L"MFVideoFormat_WVC1", NULL }, 131 | }; 132 | 133 | class CMFCameraSource : public IMFSourceReaderCallback { 134 | public: 135 | static HRESULT CreateInstance(LONG lWidth, LONG lHeight, FrameCallback pfnCallback, CMFCameraSource **ppSource) 136 | { 137 | if (ppSource == NULL) return E_POINTER; 138 | 139 | CMFCameraSource *pSource = new (std::nothrow) CMFCameraSource(); 140 | if (pSource == NULL) return E_OUTOFMEMORY; 141 | 142 | HRESULT hr = pSource->Initialize(lWidth, lHeight, pfnCallback); 143 | 144 | if (SUCCEEDED(hr)) 145 | { 146 | *ppSource = pSource; 147 | 148 | // 149 | // Client should Release after using this instance. 150 | // 151 | (*ppSource)->AddRef(); 152 | } 153 | 154 | return hr; 155 | } 156 | 157 | // 158 | // IUnknown methods 159 | // 160 | STDMETHODIMP QueryInterface(REFIID iid, void **ppv) 161 | { 162 | static const QITAB qit[] = 163 | { 164 | QITABENT(CMFCameraSource, IMFSourceReaderCallback), 165 | { 0 }, 166 | }; 167 | 168 | return QISearch(this, qit, iid, ppv); 169 | } 170 | 171 | STDMETHODIMP_(ULONG) AddRef() 172 | { 173 | return InterlockedIncrement(&m_lRefCount); 174 | } 175 | 176 | STDMETHODIMP_(ULONG) Release() 177 | { 178 | ULONG uCount = InterlockedDecrement(&m_lRefCount); 179 | 180 | if (uCount == 0) 181 | { 182 | delete this; 183 | } 184 | 185 | return uCount; 186 | } 187 | 188 | // 189 | // IMFSourceReaderCallback methods 190 | // 191 | STDMETHODIMP OnReadSample(HRESULT hrStatus, DWORD dwStreamIndex, DWORD dwStreamFlags, LONGLONG llTimestamp, IMFSample *pSample) 192 | { 193 | HRESULT hr = hrStatus; 194 | IMFMediaBuffer *pBuffer = NULL; 195 | DWORD dwStream = (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM; 196 | 197 | EnterCriticalSection(&m_csLock); 198 | 199 | if (m_pfnFrameCallback) 200 | { 201 | // 202 | // We just call the provided callback if available. We will continue to request for more frames if callback will 203 | // return S_OK. 204 | // 205 | hr = m_pfnFrameCallback(hrStatus, dwStreamIndex, dwStreamFlags, llTimestamp, pSample); 206 | } 207 | 208 | // 209 | // Request the next frame. If callback function returns != S_OK, then streaming will be stopped. 210 | // 211 | if (SUCCEEDED(hr)) 212 | { 213 | hr = m_pIReader->ReadSample(dwStream, 0, NULL, NULL, NULL, NULL); 214 | 215 | if (FAILED(hr)) 216 | { 217 | EventWriteHresultError(M, FL, FN, L"ReadSample", hr); 218 | } 219 | } 220 | 221 | LeaveCriticalSection(&m_csLock); 222 | 223 | return hr; 224 | } 225 | 226 | STDMETHODIMP OnEvent(DWORD, IMFMediaEvent*) { return S_OK; } 227 | STDMETHODIMP OnFlush(DWORD) { return S_OK; } 228 | 229 | HRESULT SetDevice(IMFActivate *pActivate) 230 | { 231 | if (!m_bInitialized) return E_NOT_VALID_STATE; 232 | 233 | HRESULT hr = S_OK; 234 | IMFMediaSource *pSource = NULL; 235 | IMFAttributes *pAttributes = NULL; 236 | IMFMediaType *pType = NULL; 237 | IMFMediaType *pOutType = NULL; 238 | wchar_t szTrace[MAX_PATH] = { 0 }; 239 | 240 | DWORD dwStream = (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM; 241 | 242 | EnterCriticalSection(&m_csLock); 243 | 244 | do 245 | { 246 | // 247 | // Create the media source for the device... 248 | // 249 | hr = pActivate->ActivateObject(__uuidof(IMFMediaSource), (void**)&pSource); 250 | 251 | if (FAILED(hr)) 252 | { 253 | EventWriteHresultError(M, FL, FN, L"ActivateObject", hr); 254 | break; 255 | } 256 | 257 | // 258 | // Get the symbolic link... 259 | // 260 | hr = pActivate->GetAllocatedString( 261 | MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, 262 | &m_pszSymbolicLink, 263 | &m_uiSymbolicLinkLen); 264 | 265 | if (FAILED(hr)) 266 | { 267 | EventWriteHresultError(M, FL, FN, L"GetAllocatedString", hr); 268 | break; 269 | } 270 | 271 | // 272 | // Create an attribute store to hold initialization settings... 273 | // 274 | hr = MFCreateAttributes(&pAttributes, 2); 275 | 276 | if (FAILED(hr)) 277 | { 278 | EventWriteHresultError(M, FL, FN, L"MFCreateAttributes", hr); 279 | break; 280 | } 281 | 282 | hr = pAttributes->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, TRUE); 283 | 284 | if (FAILED(hr)) 285 | { 286 | EventWriteHresultError(M, FL, FN, L"SetUINT32", hr); 287 | break; 288 | } 289 | 290 | // 291 | // Set the callback pointer to this object... 292 | // 293 | hr = pAttributes->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, this); 294 | 295 | if (FAILED(hr)) 296 | { 297 | EventWriteHresultError(M, FL, FN, L"SetUnknown", hr); 298 | break; 299 | } 300 | 301 | // 302 | // Then create the source reader... 303 | // 304 | hr = MFCreateSourceReaderFromMediaSource(pSource, pAttributes, &m_pIReader); 305 | 306 | if (FAILED(hr)) 307 | { 308 | EventWriteHresultError(M, FL, FN, L"MFCreateSourceReaderFromMediaSource", hr); 309 | break; 310 | } 311 | 312 | // 313 | // Try to find a suitable output type... 314 | // 315 | BOOL bFound = FALSE; 316 | 317 | for (DWORD j = 0;; j++) 318 | { 319 | hr = m_pIReader->GetNativeMediaType(dwStream, j, &pType); 320 | 321 | if (FAILED(hr)) 322 | { 323 | EventWriteHresultError(M, FL, FN, L"GetNativeMediaType", hr); 324 | break; 325 | } 326 | 327 | GUID subType = { 0 }; 328 | hr = pType->GetGUID(MF_MT_SUBTYPE, &subType); 329 | 330 | // 331 | // Check if its in our table of supported types... 332 | // 333 | for (DWORD k = 0; k < ARRAYSIZE(FormatConversions); k++) 334 | { 335 | if (subType == FormatConversions[k].guidSubType) 336 | { 337 | UINT32 uFrNume, uFrDeno; 338 | UINT32 uParNume, uParDeno; 339 | UINT32 uiTempX, uiTempY; 340 | 341 | MFGetAttributeSize(pType, MF_MT_FRAME_SIZE, &uiTempX, &uiTempY); 342 | MFGetAttributeRatio(pType, MF_MT_FRAME_RATE, &uFrNume, &uFrDeno); 343 | MFGetAttributeRatio(pType, MF_MT_PIXEL_ASPECT_RATIO, &uParNume, &uParDeno); 344 | 345 | hr = GetDefaultImageStride(pType, &m_lDefaultStride); 346 | 347 | StringCchPrintf(szTrace, MAX_PATH, L"Native(j,k):(%d,%d) %s, W: %d, H: %d, Stride: %d, F.Rate: " 348 | L"%d:%d, PAR: %d:%d", 349 | j, 350 | k, 351 | FormatConversions[k].pwszGuidSubType, 352 | m_uiWidth, 353 | m_uiHeight, 354 | m_lDefaultStride, 355 | uFrNume, 356 | uFrDeno, 357 | uParNume, 358 | uParDeno); 359 | 360 | EventWriteInfoW(M, FL, FN, szTrace); 361 | 362 | if (FormatConversions[k].guidSubType == MFVideoFormat_YUY2 && 363 | uiTempX == m_uiWidth && uiTempY == m_uiHeight) 364 | { 365 | // __TRACE(pTrace, TL_INFO, KW_INFO, L"Set YUY2 as media subtype format."); 366 | 367 | hr = m_pIReader->SetCurrentMediaType(dwStream, NULL, pType); 368 | 369 | if (FAILED(hr)) 370 | { 371 | EventWriteHresultError(M, FL, FN, L"SetCurrentMediaType", hr); 372 | } 373 | 374 | bFound = TRUE; 375 | break; 376 | } 377 | } 378 | } 379 | 380 | SafeRelease(&pType); 381 | if (bFound) break; 382 | if (hr == MF_E_NO_MORE_TYPES || hr == MF_E_INVALIDSTREAMNUMBER) break; 383 | } 384 | 385 | if (!bFound) 386 | { 387 | // 388 | // Set output media type to RGB32. Whatever native type is supported in our source, source reader will automatically 389 | // insert required decoders/transforms in the pipeline. 390 | // 391 | // __TRACE(pTrace, TL_INFO, KW_INFO, L"Use native as media type format."); 392 | 393 | hr = MFCreateMediaType(&pOutType); 394 | 395 | if (FAILED(hr)) 396 | { 397 | EventWriteHresultError(M, FL, FN, L"MFCreateMediaType", hr); 398 | } 399 | 400 | hr = pOutType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); 401 | 402 | if (FAILED(hr)) 403 | { 404 | EventWriteHresultError(M, FL, FN, L"SetGUID(MF_MT_MAJOR_TYPE...)", hr); 405 | } 406 | 407 | hr = pOutType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32); 408 | 409 | if (FAILED(hr)) 410 | { 411 | EventWriteHresultError(M, FL, FN, L"SetGUID(MF_MT_SUBTYPE...)", hr); 412 | } 413 | 414 | hr = MFSetAttributeSize(pOutType, MF_MT_FRAME_SIZE, m_uiWidth, m_uiHeight); 415 | 416 | if (FAILED(hr)) 417 | { 418 | EventWriteHresultError(M, FL, FN, L"MFSetAttributeSize", hr); 419 | } 420 | 421 | hr = m_pIReader->SetCurrentMediaType(dwStream, NULL, pOutType); 422 | 423 | if (FAILED(hr)) 424 | { 425 | EventWriteHresultError(M, FL, FN, L"SetCurrentMediaType", hr); 426 | } 427 | 428 | SafeRelease(&pOutType); 429 | } 430 | 431 | if (SUCCEEDED(hr)) 432 | { 433 | // 434 | // Ask for the first sample. This call will cause our OnReadSample callback to be called back. Call ReadSample 435 | // again within the callback function to get the next frame and so on. 436 | // 437 | hr = m_pIReader->ReadSample(dwStream, 0, NULL, NULL, NULL, NULL); 438 | 439 | if (FAILED(hr)) 440 | { 441 | EventWriteHresultError(M, FL, FN, L"ReadSample", hr); 442 | } 443 | } 444 | } while (false); 445 | 446 | SafeRelease(&pSource); 447 | SafeRelease(&pAttributes); 448 | SafeRelease(&pType); 449 | SafeRelease(&pOutType); 450 | 451 | LeaveCriticalSection(&m_csLock); 452 | 453 | return hr; 454 | } 455 | 456 | HRESULT CloseDevice() 457 | { 458 | EnterCriticalSection(&m_csLock); 459 | SafeRelease(&m_pIReader); 460 | 461 | CoTaskMemFree(m_pszSymbolicLink); 462 | m_pszSymbolicLink = NULL; 463 | m_uiSymbolicLinkLen = 0; 464 | 465 | LeaveCriticalSection(&m_csLock); 466 | 467 | return S_OK; 468 | } 469 | 470 | HRESULT ResizeVideo(WORD wWidth, WORD wHeight) 471 | { 472 | return E_NOTIMPL; 473 | } 474 | 475 | protected: 476 | CMFCameraSource() 477 | { 478 | InitializeCriticalSection(&m_csLock); 479 | 480 | m_lRefCount = 0; 481 | m_pszSymbolicLink = NULL; 482 | m_uiSymbolicLinkLen = 0; 483 | 484 | m_pIReader = NULL; 485 | 486 | m_uiWidth = m_uiHeight = m_lDefaultStride = 0; 487 | ZeroMemory(&m_mfrAspectRatio, sizeof(MFRatio)); 488 | } 489 | 490 | virtual ~CMFCameraSource() 491 | { 492 | DeleteCriticalSection(&m_csLock); 493 | } 494 | 495 | HRESULT Initialize(LONG lWidth, LONG lHeight, FrameCallback pfnCallback) 496 | { 497 | m_uiWidth = (UINT)lWidth; 498 | m_uiHeight = (UINT)lHeight; 499 | m_pfnFrameCallback = pfnCallback; 500 | m_bInitialized = TRUE; 501 | return S_OK; 502 | } 503 | 504 | protected: 505 | LONG m_lRefCount; 506 | CRITICAL_SECTION m_csLock; 507 | IMFSourceReader *m_pIReader; 508 | wchar_t *m_pszSymbolicLink; 509 | UINT32 m_uiSymbolicLinkLen; 510 | UINT m_uiWidth; 511 | UINT m_uiHeight; 512 | LONG m_lDefaultStride; 513 | MFRatio m_mfrAspectRatio; 514 | FrameCallback m_pfnFrameCallback; 515 | BOOL m_bInitialized; 516 | }; 517 | 518 | class CameraMf : public ICameraMf { 519 | public: 520 | CameraMf() : 521 | m_lRefCount(0), 522 | m_bInitialized(FALSE), 523 | m_pfnFrameCallback(NULL), 524 | m_lWidth(640), 525 | m_lHeight(480), 526 | m_pCamSource(NULL) 527 | {} 528 | 529 | virtual ~CameraMf() 530 | { 531 | if (m_bRendered) StopRenderAsync(); 532 | SafeRelease(&m_pCamSource); 533 | } 534 | 535 | // 536 | // IUnknown methods 537 | // 538 | STDMETHODIMP QueryInterface(REFIID iid, void **ppv) 539 | { 540 | if ((iid == __uuidof(IUnknown)) || (iid == __uuidof(ICameraMf))) 541 | { 542 | *ppv = static_cast(this); 543 | } 544 | else 545 | { 546 | *ppv = NULL; 547 | return E_NOINTERFACE; 548 | } 549 | 550 | AddRef(); 551 | return S_OK; 552 | } 553 | 554 | STDMETHODIMP_(ULONG) AddRef() 555 | { 556 | return InterlockedIncrement(&m_lRefCount); 557 | } 558 | 559 | STDMETHODIMP_(ULONG) Release() 560 | { 561 | ULONG uCount = InterlockedDecrement(&m_lRefCount); 562 | 563 | if (uCount == 0) 564 | { 565 | delete this; 566 | } 567 | 568 | return uCount; 569 | } 570 | 571 | // 572 | // ICameraMf methods. 573 | // 574 | HRESULT Initialize(LONG lWidth, LONG lHeight, FrameCallback pfnFrameCallback) 575 | { 576 | m_lWidth = lWidth; 577 | m_lHeight = lHeight; 578 | m_pfnFrameCallback = pfnFrameCallback; 579 | 580 | HRESULT hr = CMFCameraSource::CreateInstance(m_lWidth, m_lHeight, m_pfnFrameCallback, &m_pCamSource); 581 | 582 | if (SUCCEEDED(hr)) m_bInitialized = TRUE; 583 | 584 | return hr; 585 | } 586 | 587 | // 588 | // Param 'ppFriendlyNames' will be allocated here based on the required size. Caller should call free() on 'ppFriendlyNames' 589 | // after call. If more than one cameras detected, names will be separated by a semicolon (;). 590 | // 591 | HRESULT GetFriendlyNames(wchar_t **ppFriendlyNames, LONG *pcbSize) 592 | { 593 | ChooseDeviceParam param = { 0 }; 594 | IMFAttributes *pAttributes = NULL; 595 | BOOL bReturn = FALSE; 596 | HRESULT hr = E_FAIL; 597 | DWORD dwDevIndex = -1; 598 | wchar_t *pszOldNames = NULL; 599 | wchar_t *pszNames = NULL; 600 | size_t cchTotal = 0; 601 | 602 | do 603 | { 604 | *pcbSize = 0; 605 | 606 | // 607 | // Initialize an attribute store to specify enumeration parameters. 608 | // 609 | hr = MFCreateAttributes(&pAttributes, 1); 610 | 611 | if (FAILED(hr)) 612 | { 613 | EventWriteHresultError(M, FL, FN, L"MFCreateAttributes", hr); 614 | break; 615 | } 616 | 617 | // 618 | // Ask for source type = video capture devices. 619 | // 620 | hr = pAttributes->SetGUID( 621 | MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, 622 | MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID); 623 | 624 | if (FAILED(hr)) 625 | { 626 | EventWriteHresultError(M, FL, FN, L"SetGUID", hr); 627 | break; 628 | } 629 | 630 | // 631 | // Enumerate devices. 632 | // 633 | hr = MFEnumDeviceSources(pAttributes, ¶m.ppDevices, ¶m.count); 634 | 635 | if (FAILED(hr)) 636 | { 637 | EventWriteHresultError(M, FL, FN, L"MFEnumDeviceSources", hr); 638 | break; 639 | } 640 | 641 | if (param.count) 642 | { 643 | BOOL bSuccess = TRUE; 644 | 645 | for (DWORD i = 0; i < param.count; i++) 646 | { 647 | wchar_t *pszFriendlyNameTmp = NULL; 648 | 649 | #pragma warning(suppress: 6387) 650 | hr = param.ppDevices[i]->GetAllocatedString( 651 | MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, 652 | &pszFriendlyNameTmp, 653 | NULL); 654 | 655 | if (FAILED(hr)) 656 | { 657 | EventWriteHresultError(M, FL, FN, L"HrError MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME", hr); 658 | bSuccess = FALSE; 659 | break; 660 | } 661 | 662 | if (pszFriendlyNameTmp) 663 | { 664 | EventWriteWideStrInfo(M, FL, FN, L"FriendlyName", pszFriendlyNameTmp); 665 | 666 | size_t cchLen = 0; 667 | 668 | StringCchLength(pszFriendlyNameTmp, MAX_PATH, &cchLen); 669 | EventWriteNumberInfo(M, FL, FN, L"cchLen", cchLen); 670 | 671 | cchTotal += cchLen + 2; 672 | 673 | pszOldNames = pszNames; 674 | 675 | pszNames = (wchar_t*)realloc(pszNames, cchTotal * sizeof(wchar_t)); 676 | 677 | if (pszNames) 678 | { 679 | if (i == 0) 680 | { 681 | // 682 | // So 'StringCchCat' will work on first concatenate. 683 | // 684 | pszNames[0] = L'\0'; 685 | } 686 | 687 | StringCchCat(pszNames, cchTotal, pszFriendlyNameTmp); 688 | StringCchCat(pszNames, cchTotal, L";"); 689 | } 690 | else 691 | { 692 | EventWriteLastError(M, FL, FN, L"Error realloc", GetLastError()); 693 | free(pszOldNames); 694 | bSuccess = FALSE; 695 | break; 696 | } 697 | 698 | CoTaskMemFree(pszFriendlyNameTmp); 699 | } 700 | } 701 | 702 | if (bSuccess) 703 | { 704 | size_t cchLen = 0, alloc = 0; 705 | 706 | StringCchLength(pszNames, cchTotal, &cchLen); 707 | EventWriteNumberInfo(M, FL, FN, L"cchLen (1st)", cchLen); 708 | 709 | // 710 | // Remove the last semicolon. 711 | // 712 | pszNames[cchLen - 1] = L'\0'; 713 | EventWriteWideStrInfo(M, FL, FN, L"Name list", pszNames); 714 | 715 | StringCchLength(pszNames, cchTotal, &cchLen); 716 | EventWriteNumberInfo(M, FL, FN, L"cchLen (2nd)", cchLen); 717 | 718 | alloc = (cchLen * sizeof(wchar_t)) + sizeof(wchar_t); 719 | 720 | *ppFriendlyNames = (wchar_t*)malloc(alloc); 721 | 722 | if (*ppFriendlyNames) 723 | { 724 | StringCchCopy(*ppFriendlyNames, alloc, pszNames); 725 | *pcbSize = alloc; 726 | } 727 | } 728 | } 729 | } while (false); 730 | 731 | if (pszNames) free(pszNames); 732 | 733 | SafeRelease(&pAttributes); 734 | 735 | for (DWORD i = 0; i < param.count; i++) 736 | { 737 | SafeRelease(¶m.ppDevices[i]); 738 | } 739 | 740 | CoTaskMemFree(param.ppDevices); 741 | 742 | return hr; 743 | } 744 | 745 | HRESULT StartRenderAsync(wchar_t *pszFriendlyName) 746 | { 747 | if (!m_bInitialized) return E_NOT_VALID_STATE; 748 | 749 | ChooseDeviceParam param = { 0 }; 750 | IMFAttributes *pAttributes = NULL; 751 | BOOL bCamPresent = FALSE; 752 | BOOL bReturn = FALSE; 753 | HRESULT hr = S_OK; 754 | DWORD dwDevIndex = -1; 755 | m_bRendered = FALSE; 756 | 757 | do 758 | { 759 | // 760 | // Initialize an attribute store to specify enumeration parameters. 761 | // 762 | hr = MFCreateAttributes(&pAttributes, 1); 763 | 764 | if (FAILED(hr)) 765 | { 766 | EventWriteHresultError(M, FL, FN, L"MFCreateAttributes", hr); 767 | break; 768 | } 769 | 770 | // 771 | // Ask for source type = video capture devices. 772 | // 773 | hr = pAttributes->SetGUID( 774 | MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, 775 | MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID); 776 | 777 | if (FAILED(hr)) 778 | { 779 | EventWriteHresultError(M, FL, FN, L"pAttributes->SetGUID", hr); 780 | break; 781 | } 782 | 783 | // 784 | // Enumerate devices. 785 | // 786 | hr = MFEnumDeviceSources(pAttributes, ¶m.ppDevices, ¶m.count); 787 | 788 | if (FAILED(hr)) 789 | { 790 | EventWriteHresultError(M, FL, FN, L"MFEnumDeviceSources", hr); 791 | break; 792 | } 793 | 794 | if (param.count) 795 | { 796 | for (DWORD i = 0; i < param.count; i++) 797 | { 798 | wchar_t *pszFriendlyNameTmp = NULL; 799 | 800 | #pragma warning(suppress: 6387) 801 | hr = param.ppDevices[i]->GetAllocatedString( 802 | MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, 803 | &pszFriendlyNameTmp, 804 | NULL); 805 | 806 | if (FAILED(hr)) break; 807 | 808 | if (pszFriendlyNameTmp) 809 | { 810 | EventWriteWideStrInfo(M, FL, FN, L"FriendlyName", pszFriendlyNameTmp); 811 | 812 | if ((_wcsicmp(pszFriendlyNameTmp, pszFriendlyName)) == 0) 813 | { 814 | bCamPresent = TRUE; 815 | dwDevIndex = i; 816 | break; 817 | } 818 | 819 | CoTaskMemFree(pszFriendlyNameTmp); 820 | } 821 | } 822 | } 823 | 824 | if (bCamPresent) 825 | { 826 | hr = m_pCamSource->SetDevice(param.ppDevices[dwDevIndex]); 827 | 828 | if (FAILED(hr)) 829 | { 830 | m_bRendered = FALSE; 831 | } 832 | else 833 | { 834 | m_bRendered = TRUE; 835 | bReturn = TRUE; 836 | } 837 | } 838 | else 839 | { 840 | EventWriteErrorW(M, FL, FN, L"Camera not available! Maybe disabled, not installed, or used?"); 841 | } 842 | } while (false); 843 | 844 | SafeRelease(&pAttributes); 845 | 846 | for (DWORD i = 0; i < param.count; i++) 847 | SafeRelease(¶m.ppDevices[i]); 848 | 849 | CoTaskMemFree(param.ppDevices); 850 | 851 | return S_OK; 852 | } 853 | 854 | HRESULT StopRenderAsync() 855 | { 856 | if (!m_bInitialized) return E_NOT_VALID_STATE; 857 | 858 | m_pCamSource->CloseDevice(); 859 | m_bRendered = FALSE; 860 | 861 | return S_OK; 862 | } 863 | 864 | HRESULT IsSystemCamera(wchar_t *pszFriendlyName, PBOOL pbSystemCamera, LONG *pIndex) 865 | { 866 | // 867 | // We just do camera enumeration here so no need for initialization. We just go through the whole process 868 | // or open, read and close. 869 | // 870 | 871 | ChooseDeviceParam param = { 0 }; 872 | IMFAttributes *pAttributes = NULL; 873 | BOOL bCamPresent = FALSE; 874 | BOOL bReturn = FALSE; 875 | HRESULT hr = E_FAIL; 876 | LONG lDevIndex = -1; 877 | 878 | do 879 | { 880 | *pbSystemCamera = FALSE; 881 | 882 | // 883 | // Initialize an attribute store to specify enumeration parameters. 884 | // 885 | hr = MFCreateAttributes(&pAttributes, 1); 886 | 887 | if (FAILED(hr)) 888 | { 889 | EventWriteHresultError(M, FL, FN, L"MFCreateAttributes", hr); 890 | break; 891 | } 892 | 893 | // 894 | // Ask for source type = video capture devices. 895 | // 896 | hr = pAttributes->SetGUID( 897 | MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, 898 | MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID); 899 | 900 | if (FAILED(hr)) 901 | { 902 | EventWriteHresultError(M, FL, FN, L"SetGUID", hr); 903 | break; 904 | } 905 | 906 | // 907 | // Enumerate devices. 908 | // 909 | hr = MFEnumDeviceSources(pAttributes, ¶m.ppDevices, ¶m.count); 910 | 911 | if (FAILED(hr)) 912 | { 913 | EventWriteHresultError(M, FL, FN, L"MFEnumDeviceSources", hr); 914 | break; 915 | } 916 | 917 | if (param.count) 918 | { 919 | for (DWORD i = 0; i < param.count; i++) 920 | { 921 | wchar_t *pszFriendlyNameTmp = NULL; 922 | 923 | #pragma warning(suppress: 6387) 924 | hr = param.ppDevices[i]->GetAllocatedString( 925 | MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, 926 | &pszFriendlyNameTmp, 927 | NULL); 928 | 929 | if (FAILED(hr)) break; 930 | 931 | if (pszFriendlyNameTmp) 932 | { 933 | EventWriteWideStrInfo(M, FL, FN, L"FriendlyName", pszFriendlyNameTmp); 934 | 935 | if ((_wcsicmp(pszFriendlyNameTmp, pszFriendlyName)) == 0) 936 | { 937 | bCamPresent = TRUE; 938 | lDevIndex = i; 939 | *pIndex = i; 940 | 941 | EventWriteNumberInfo(M, FL, FN, L"Found. Index @", lDevIndex); 942 | 943 | break; 944 | } 945 | 946 | CoTaskMemFree(pszFriendlyNameTmp); 947 | } 948 | } 949 | } 950 | 951 | if (bCamPresent) 952 | { 953 | *pbSystemCamera = TRUE; 954 | hr = S_OK; 955 | } 956 | else 957 | { 958 | EventWriteWideStrInfo(M, FL, FN, L"Not available", pszFriendlyName); 959 | } 960 | } while (false); 961 | 962 | SafeRelease(&pAttributes); 963 | 964 | for (DWORD i = 0; i < param.count; i++) 965 | { 966 | SafeRelease(¶m.ppDevices[i]); 967 | } 968 | 969 | CoTaskMemFree(param.ppDevices); 970 | 971 | return hr; 972 | } 973 | 974 | HRESULT MfDumpCameraInfo(wchar_t *pszFriendlyName) 975 | { 976 | HRESULT hr = MFStartup(MF_VERSION); 977 | 978 | if (FAILED(hr)) 979 | { 980 | EventWriteHresultError(M, FL, FN, L"MFStartup", hr); 981 | return hr; 982 | } 983 | 984 | ChooseDeviceParam param = { 0 }; 985 | IMFAttributes *pAttributes = NULL; 986 | BOOL bCamPresent = FALSE; 987 | BOOL bReturn = FALSE; 988 | DWORD dwDevIndex = -1; 989 | wchar_t szTrace[MAX_PATH] = { 0 }; 990 | 991 | do 992 | { 993 | // 994 | // Initialize an attribute store to specify enumeration parameters. 995 | // 996 | hr = MFCreateAttributes(&pAttributes, 1); 997 | 998 | if (FAILED(hr)) 999 | { 1000 | EventWriteHresultError(M, FL, FN, L"MFCreateAttributes", hr); 1001 | break; 1002 | } 1003 | 1004 | // 1005 | // Ask for source type = video capture devices. 1006 | // 1007 | hr = pAttributes->SetGUID( 1008 | MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, 1009 | MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID); 1010 | 1011 | if (FAILED(hr)) 1012 | { 1013 | EventWriteHresultError(M, FL, FN, L"pAttributes->SetGUID", hr); 1014 | break; 1015 | } 1016 | 1017 | // 1018 | // Enumerate devices. 1019 | // 1020 | hr = MFEnumDeviceSources(pAttributes, ¶m.ppDevices, ¶m.count); 1021 | 1022 | if (FAILED(hr)) 1023 | { 1024 | EventWriteHresultError(M, FL, FN, L"MFEnumDeviceSources", hr); 1025 | break; 1026 | } 1027 | 1028 | if (param.count) 1029 | { 1030 | for (DWORD i = 0; i < param.count; i++) 1031 | { 1032 | wchar_t *pszFriendlyName = NULL; 1033 | 1034 | #pragma warning(suppress: 6387) 1035 | hr = param.ppDevices[i]->GetAllocatedString( 1036 | MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, 1037 | &pszFriendlyName, 1038 | NULL); 1039 | 1040 | if (FAILED(hr) || !pszFriendlyName) break; 1041 | 1042 | if ((_wcsicmp(pszFriendlyName, L"Integrated Camera")) == 0) 1043 | { 1044 | bCamPresent = TRUE; 1045 | dwDevIndex = i; 1046 | CoTaskMemFree(pszFriendlyName); 1047 | break; 1048 | } 1049 | 1050 | CoTaskMemFree(pszFriendlyName); 1051 | } 1052 | } 1053 | 1054 | if (bCamPresent) 1055 | { 1056 | // 1057 | // Enumerate supported resolutions 1058 | // 1059 | IMFMediaSource *pSource = NULL; 1060 | IMFAttributes *pAttrib = NULL; 1061 | IMFMediaType *pType = NULL; 1062 | IMFMediaType *pOutType = NULL; 1063 | IMFActivate *pActivate = param.ppDevices[dwDevIndex]; 1064 | IMFSourceReader *pIReader = NULL; 1065 | wchar_t *pszSymbolicLink; 1066 | UINT32 uiSymbolicLinkLen; 1067 | UINT ctr1, ctr2, ctr3; 1068 | 1069 | DWORD dwStream = (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM; 1070 | 1071 | // 1072 | // Create the media source for the device... 1073 | // 1074 | hr = pActivate->ActivateObject(__uuidof(IMFMediaSource), (void**)&pSource); 1075 | 1076 | if (FAILED(hr)) 1077 | { 1078 | EventWriteHresultError(M, FL, FN, L"ActivateObject", hr); 1079 | break; 1080 | } 1081 | 1082 | // 1083 | // Get the symbolic link... 1084 | // 1085 | hr = pActivate->GetAllocatedString( 1086 | MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, 1087 | &pszSymbolicLink, 1088 | &uiSymbolicLinkLen); 1089 | 1090 | if (FAILED(hr)) 1091 | { 1092 | EventWriteHresultError(M, FL, FN, L"GetAllocatedString", hr); 1093 | break; 1094 | } 1095 | 1096 | // 1097 | // Create an attribute store to hold initialization settings... 1098 | // 1099 | hr = MFCreateAttributes(&pAttrib, 2); 1100 | 1101 | if (FAILED(hr)) 1102 | { 1103 | EventWriteHresultError(M, FL, FN, L"MFCreateAttributes", hr); 1104 | break; 1105 | } 1106 | 1107 | hr = pAttrib->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, TRUE); 1108 | 1109 | if (FAILED(hr)) 1110 | { 1111 | EventWriteHresultError(M, FL, FN, L"SetUINT32", hr); 1112 | break; 1113 | } 1114 | 1115 | // 1116 | // Then create the source reader... 1117 | // 1118 | hr = MFCreateSourceReaderFromMediaSource(pSource, pAttrib, &pIReader); 1119 | 1120 | if (FAILED(hr)) 1121 | { 1122 | EventWriteHresultError(M, FL, FN, L"MFCreateSourceReaderFromMediaSource", hr); 1123 | break; 1124 | } 1125 | 1126 | // 1127 | // Try to find a suitable output type... 1128 | // 1129 | BOOL bFound = FALSE; 1130 | 1131 | for (ctr1 = 0;; ctr1++) 1132 | { 1133 | hr = pIReader->GetNativeMediaType(dwStream, ctr1, &pType); 1134 | 1135 | if (FAILED(hr)) 1136 | { 1137 | EventWriteHresultError(M, FL, FN, L"GetNativeMediaType", hr); 1138 | break; 1139 | } 1140 | 1141 | GUID subType = { 0 }; 1142 | hr = pType->GetGUID(MF_MT_SUBTYPE, &subType); 1143 | 1144 | // 1145 | // Check if its in our table of supported types... 1146 | // 1147 | for (DWORD k = 0; k < ARRAYSIZE(FormatConversions); k++) 1148 | { 1149 | if (subType == FormatConversions[k].guidSubType) 1150 | { 1151 | UINT32 uFrNume, uFrDeno; 1152 | UINT32 uParNume, uParDeno; 1153 | UINT uiWidth, uiHeight; 1154 | LONG lDefaultStride; 1155 | 1156 | MFGetAttributeSize(pType, MF_MT_FRAME_SIZE, &uiWidth, &uiHeight); 1157 | MFGetAttributeRatio(pType, MF_MT_FRAME_RATE, &uFrNume, &uFrDeno); 1158 | MFGetAttributeRatio(pType, MF_MT_PIXEL_ASPECT_RATIO, &uParNume, &uParDeno); 1159 | hr = GetDefaultImageStride(pType, &lDefaultStride); 1160 | 1161 | StringCchPrintf( 1162 | szTrace, 1163 | MAX_PATH, 1164 | L"%s, W: %d, H: %d, Stride: %d, F.Rate: " 1165 | L"%d:%d, PAR: %d:%d", 1166 | FormatConversions[k].pwszGuidSubType, 1167 | uiWidth, 1168 | uiHeight, 1169 | lDefaultStride, 1170 | uFrNume, 1171 | uFrDeno, 1172 | uParNume, 1173 | uParDeno); 1174 | 1175 | EventWriteInfoW(M, FL, FN, szTrace); 1176 | } 1177 | } 1178 | 1179 | SafeRelease(&pType); 1180 | 1181 | if (hr == MF_E_NO_MORE_TYPES || hr == MF_E_INVALIDSTREAMNUMBER) break; 1182 | } 1183 | 1184 | if (hr == MF_E_NO_MORE_TYPES) hr = S_OK; 1185 | 1186 | SafeRelease(&pActivate); 1187 | SafeRelease(&pIReader); 1188 | 1189 | CoTaskMemFree(pszSymbolicLink); 1190 | 1191 | if (pSource) pSource->Shutdown(); 1192 | SafeRelease(&pSource); 1193 | 1194 | SafeRelease(&pAttributes); 1195 | SafeRelease(&pType); 1196 | SafeRelease(&pOutType); 1197 | } 1198 | } while (false); 1199 | 1200 | SafeRelease(&pAttributes); 1201 | 1202 | for (DWORD i = 0; i < param.count; i++) 1203 | { 1204 | SafeRelease(¶m.ppDevices[i]); 1205 | } 1206 | 1207 | CoTaskMemFree(param.ppDevices); 1208 | 1209 | hr = MFShutdown(); 1210 | 1211 | if (FAILED(hr)) 1212 | { 1213 | EventWriteHresultError(M, FL, FN, L"MFShutdown", hr); 1214 | } 1215 | 1216 | return hr; 1217 | } 1218 | 1219 | // 1220 | // Param 'ppInfo' will be allocated here based on the required size. Caller should call free() on 'ppInfo' 1221 | // after call when '*pCount' > 0. 'pCount' will contain the number of MFMEDIA_INFO's allocated. 1222 | // 1223 | HRESULT MfGetMediaInfo(wchar_t *pszFriendlyName, MFMEDIA_INFO **ppInfo, LONG *pCount) 1224 | { 1225 | HRESULT hr = MFStartup(MF_VERSION); 1226 | 1227 | if (FAILED(hr)) 1228 | { 1229 | EventWriteHresultError(M, FL, FN, L"MFStartup", hr); 1230 | return hr; 1231 | } 1232 | 1233 | ChooseDeviceParam param = { 0 }; 1234 | IMFAttributes *pAttributes = NULL; 1235 | BOOL bCamPresent = FALSE; 1236 | BOOL bReturn = FALSE; 1237 | DWORD dwDevIndex = -1; 1238 | wchar_t szTrace[MAX_PATH] = { 0 }; 1239 | vector infolist; 1240 | 1241 | do 1242 | { 1243 | *pCount = 0; 1244 | 1245 | // 1246 | // Initialize an attribute store to specify enumeration parameters. 1247 | // 1248 | hr = MFCreateAttributes(&pAttributes, 1); 1249 | 1250 | if (FAILED(hr)) 1251 | { 1252 | EventWriteHresultError(M, FL, FN, L"MFCreateAttributes", hr); 1253 | break; 1254 | } 1255 | 1256 | // 1257 | // Ask for source type = video capture devices. 1258 | // 1259 | hr = pAttributes->SetGUID( 1260 | MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, 1261 | MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID); 1262 | 1263 | if (FAILED(hr)) 1264 | { 1265 | EventWriteHresultError(M, FL, FN, L"pAttributes->SetGUID", hr); 1266 | break; 1267 | } 1268 | 1269 | // 1270 | // Enumerate devices. 1271 | // 1272 | hr = MFEnumDeviceSources(pAttributes, ¶m.ppDevices, ¶m.count); 1273 | 1274 | if (FAILED(hr)) 1275 | { 1276 | EventWriteHresultError(M, FL, FN, L"MFEnumDeviceSources", hr); 1277 | break; 1278 | } 1279 | 1280 | if (param.count) 1281 | { 1282 | for (DWORD i = 0; i < param.count; i++) 1283 | { 1284 | wchar_t *pszName = NULL; 1285 | 1286 | #pragma warning(suppress: 6387) 1287 | hr = param.ppDevices[i]->GetAllocatedString( 1288 | MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, 1289 | &pszName, 1290 | NULL); 1291 | 1292 | if (FAILED(hr) || !pszName) break; 1293 | 1294 | if ((_wcsicmp(pszName, pszFriendlyName)) == 0) 1295 | { 1296 | CoTaskMemFree(pszName); 1297 | bCamPresent = TRUE; 1298 | dwDevIndex = i; 1299 | break; 1300 | } 1301 | 1302 | CoTaskMemFree(pszName); 1303 | } 1304 | } 1305 | 1306 | if (bCamPresent) 1307 | { 1308 | // 1309 | // Enumerate supported resolutions 1310 | // 1311 | IMFMediaSource *pSource = NULL; 1312 | IMFAttributes *pAttrib = NULL; 1313 | IMFMediaType *pType = NULL; 1314 | IMFMediaType *pOutType = NULL; 1315 | IMFActivate *pActivate = param.ppDevices[dwDevIndex]; 1316 | IMFSourceReader *pIReader = NULL; 1317 | wchar_t *pszSymbolicLink; 1318 | UINT32 uiSymbolicLinkLen; 1319 | // UINT ctr1; 1320 | 1321 | DWORD dwStream = (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM; 1322 | 1323 | // 1324 | // Create the media source for the device... 1325 | // 1326 | hr = pActivate->ActivateObject(__uuidof(IMFMediaSource), (void**)&pSource); 1327 | 1328 | if (FAILED(hr)) 1329 | { 1330 | EventWriteHresultError(M, FL, FN, L"ActivateObject", hr); 1331 | break; 1332 | } 1333 | 1334 | // 1335 | // Get the symbolic link... 1336 | // 1337 | hr = pActivate->GetAllocatedString( 1338 | MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, 1339 | &pszSymbolicLink, 1340 | &uiSymbolicLinkLen); 1341 | 1342 | if (FAILED(hr)) 1343 | { 1344 | EventWriteHresultError(M, FL, FN, L"GetAllocatedString", hr); 1345 | break; 1346 | } 1347 | 1348 | // 1349 | // Create an attribute store to hold initialization settings... 1350 | // 1351 | hr = MFCreateAttributes(&pAttrib, 2); 1352 | 1353 | if (FAILED(hr)) 1354 | { 1355 | EventWriteHresultError(M, FL, FN, L"MFCreateAttributes", hr); 1356 | break; 1357 | } 1358 | 1359 | hr = pAttrib->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, TRUE); 1360 | 1361 | if (FAILED(hr)) 1362 | { 1363 | EventWriteHresultError(M, FL, FN, L"SetUINT32", hr); 1364 | break; 1365 | } 1366 | 1367 | // 1368 | // Then create the source reader... 1369 | // 1370 | hr = MFCreateSourceReaderFromMediaSource(pSource, pAttrib, &pIReader); 1371 | 1372 | if (FAILED(hr)) 1373 | { 1374 | EventWriteHresultError(M, FL, FN, L"MFCreateSourceReaderFromMediaSource", hr); 1375 | break; 1376 | } 1377 | 1378 | // 1379 | // Try to find a suitable output type... 1380 | // 1381 | BOOL bFound = FALSE; 1382 | 1383 | for (UINT ctr1 = 0;; ctr1++) 1384 | { 1385 | hr = pIReader->GetNativeMediaType(dwStream, ctr1, &pType); 1386 | 1387 | if (FAILED(hr)) 1388 | { 1389 | EventWriteHresultError(M, FL, FN, L"GetNativeMediaType", hr); 1390 | break; 1391 | } 1392 | 1393 | GUID subType = { 0 }; 1394 | 1395 | hr = pType->GetGUID(MF_MT_SUBTYPE, &subType); 1396 | 1397 | // 1398 | // Check if its in our table of supported types... 1399 | // 1400 | for (DWORD k = 0; k < ARRAYSIZE(FormatConversions); k++) 1401 | { 1402 | if (subType == FormatConversions[k].guidSubType) 1403 | { 1404 | UINT32 uFrNume, uFrDeno; 1405 | UINT32 uParNume, uParDeno; 1406 | UINT uiWidth, uiHeight; 1407 | LONG lDefaultStride; 1408 | 1409 | MFGetAttributeSize(pType, MF_MT_FRAME_SIZE, &uiWidth, &uiHeight); 1410 | MFGetAttributeRatio(pType, MF_MT_FRAME_RATE, &uFrNume, &uFrDeno); 1411 | MFGetAttributeRatio(pType, MF_MT_PIXEL_ASPECT_RATIO, &uParNume, &uParDeno); 1412 | hr = GetDefaultImageStride(pType, &lDefaultStride); 1413 | 1414 | MFMEDIA_INFO mi; 1415 | 1416 | StringCchPrintf(mi.szSubtype, MAX_PATH, L"%s", FormatConversions[k].pwszGuidSubType); 1417 | mi.lIndex = ctr1; 1418 | mi.subTypeGuid = subType; 1419 | mi.lResolutionX = uiWidth; 1420 | mi.lResolutionY = uiHeight; 1421 | mi.lFrameRateNumerator = uFrNume; 1422 | mi.lFrameRateDenominator = uFrDeno; 1423 | mi.lPxAspectRatioNumerator = uParNume; 1424 | mi.lPxAspectRatioDenominator = uParDeno; 1425 | mi.lStride = lDefaultStride; 1426 | 1427 | infolist.push_back(mi); 1428 | 1429 | StringCchPrintf( 1430 | szTrace, 1431 | MAX_PATH, 1432 | L"%s, W: %d, H: %d, Stride: %d, F.Rate: " 1433 | L"%d:%d, PAR: %d:%d", 1434 | FormatConversions[k].pwszGuidSubType, 1435 | uiWidth, 1436 | uiHeight, 1437 | lDefaultStride, 1438 | uFrNume, 1439 | uFrDeno, 1440 | uParNume, 1441 | uParDeno); 1442 | 1443 | EventWriteInfoW(M, FL, FN, szTrace); 1444 | } 1445 | } 1446 | 1447 | SafeRelease(&pType); 1448 | 1449 | if (hr == MF_E_NO_MORE_TYPES || hr == MF_E_INVALIDSTREAMNUMBER) break; 1450 | } 1451 | 1452 | if (hr == MF_E_NO_MORE_TYPES) hr = S_OK; 1453 | 1454 | if (infolist.size() > 0) 1455 | { 1456 | *ppInfo = (MFMEDIA_INFO*)malloc(infolist.size() * sizeof(MFMEDIA_INFO)); 1457 | 1458 | if (*ppInfo) 1459 | { 1460 | *pCount = infolist.size(); 1461 | 1462 | MFMEDIA_INFO *pInfoTmp = *ppInfo; 1463 | 1464 | for (int i = 0; i < infolist.size(); i++) 1465 | { 1466 | MFMEDIA_INFO infoItem = infolist.at(i); 1467 | CopyMemory(pInfoTmp, &infoItem, sizeof(MFMEDIA_INFO)); 1468 | pInfoTmp++; 1469 | } 1470 | } 1471 | } 1472 | 1473 | SafeRelease(&pActivate); 1474 | SafeRelease(&pIReader); 1475 | 1476 | CoTaskMemFree(pszSymbolicLink); 1477 | 1478 | if (pSource) 1479 | { 1480 | pSource->Shutdown(); 1481 | } 1482 | 1483 | SafeRelease(&pSource); 1484 | SafeRelease(&pAttributes); 1485 | SafeRelease(&pType); 1486 | SafeRelease(&pOutType); 1487 | } 1488 | } while (false); 1489 | 1490 | SafeRelease(&pAttributes); 1491 | 1492 | for (DWORD i = 0; i < param.count; i++) 1493 | { 1494 | SafeRelease(¶m.ppDevices[i]); 1495 | } 1496 | 1497 | CoTaskMemFree(param.ppDevices); 1498 | 1499 | hr = MFShutdown(); 1500 | 1501 | if (FAILED(hr)) 1502 | { 1503 | EventWriteHresultError(M, FL, FN, L"MFShutdown", hr); 1504 | } 1505 | 1506 | return hr; 1507 | } 1508 | 1509 | private: 1510 | BOOL m_bRendered; 1511 | BOOL m_bInitialized; 1512 | LONG m_lRefCount; 1513 | FrameCallback m_pfnFrameCallback; 1514 | LONG m_lWidth; 1515 | LONG m_lHeight; 1516 | CMFCameraSource *m_pCamSource; 1517 | }; 1518 | 1519 | // 1520 | // Our exported CameraMf factory function. 1521 | // 1522 | _declspec(dllexport) HRESULT CreateCameraMfInstance(ICameraMf **ppObj) 1523 | { 1524 | if (ppObj == NULL) return E_POINTER; 1525 | 1526 | ICameraMf *pObj = new (std::nothrow) CameraMf(); 1527 | if (pObj == NULL) return E_OUTOFMEMORY; 1528 | 1529 | *ppObj = pObj; 1530 | 1531 | (*ppObj)->AddRef(); 1532 | 1533 | return S_OK; 1534 | } --------------------------------------------------------------------------------