6
6
#ifdef MF_WPP
7
7
#include " AvsCameraDMFT.tmh" // --REF_ANALYZER_DONT_REMOVE--
8
8
#endif
9
+
10
+ // TODO: required to avoid bug OS bug 36971659 in extended property handling that introduces a 16 bytes cookie
11
+ typedef struct
12
+ {
13
+ // byte cookieBuffer[16];
14
+ KSCAMERA_EXTENDEDPROP_HEADER header;
15
+ } KSCAMERA_EXTENDEDPROP_HEADER_BUFFERED, * PKSCAMERA_EXTENDEDPROP_HEADER_BUFFERED;
16
+
9
17
//
10
18
// This DeviceMFT is a stripped down implementation of the device MFT Sample present in the sample Repo
11
19
// The original DMFT is present at https://github.com/microsoft/Windows-driver-samples/tree/main/avstream/sampledevicemft
@@ -29,6 +37,7 @@ CMultipinMft::CMultipinMft()
29
37
DMFTCHECKHR_GOTO (pAttributes->SetUINT32 ( MF_SA_D3D_AWARE, TRUE ), done);
30
38
DMFTCHECKHR_GOTO (pAttributes->SetString ( MFT_ENUM_HARDWARE_URL_Attribute, L" SampleMultiPinMft" ),done);
31
39
m_spAttributes = pAttributes;
40
+ m_selectedProfileId = { KSCAMERAPROFILE_Legacy, 0 , 0 };
32
41
done:
33
42
DMFTRACE (DMFT_GENERAL, TRACE_LEVEL_INFORMATION, " %!FUNC! exiting %x = %!HRESULT!" , hr, hr);
34
43
}
@@ -638,6 +647,10 @@ IFACEMETHODIMP CMultipinMft::ProcessInput(
638
647
goto done;
639
648
}
640
649
650
+ if (m_selectedProfileId.Type == KSCAMERAPROFILE_FaceAuth_Mode)
651
+ {
652
+ // DMFT might switch to different behavior when profile, KSCAMERAPROFILE_FaceAuth_Mode is selected.
653
+ }
641
654
DMFTCHECKHR_GOTO (spInPin->SendSample ( pSample ), done );
642
655
done:
643
656
DMFTRACE ( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, " %!FUNC! exiting %x = %!HRESULT!" , hr, hr );
@@ -990,13 +1003,23 @@ IFACEMETHODIMP CMultipinMft::KsProperty(
990
1003
--*/
991
1004
{
992
1005
HRESULT hr = S_OK;
1006
+
1007
+ // / PDMFT only cares about ExtendedCameraControls, all others
1008
+ // / are just blindly forwarded to the upstream DMFTs.
1009
+ if (!IsEqualCLSID (pProperty->Set , KSPROPERTYSETID_ExtendedCameraControl))
1010
+ {
1011
+ DMFTCHECKHR_GOTO (m_spIkscontrol->KsProperty (pProperty, ulPropertyLength, pvPropertyData,
1012
+ ulDataLength, pulBytesReturned), done);
1013
+ goto done;
1014
+ }
993
1015
994
- DMFTCHECKHR_GOTO (m_spIkscontrol-> KsProperty (pProperty,
995
- ulPropertyLength,
996
- pvPropertyData,
997
- ulDataLength,
998
- pulBytesReturned),done);
1016
+ if (pProperty-> Id == KSPROPERTY_CAMERACONTROL_EXTENDED_PROFILE)
1017
+ {
1018
+ DMFTCHECKHR_GOTO ( ProfilePropertyHandler (pProperty, ulPropertyLength, pvPropertyData, ulDataLength, pulBytesReturned), done);
1019
+ goto done;
1020
+ }
999
1021
done:
1022
+ DMFTRACE (DMFT_GENERAL, TRACE_LEVEL_INFORMATION, " %!FUNC! exiting %x = %!HRESULT!" , hr, hr);
1000
1023
return hr;
1001
1024
}
1002
1025
@@ -1040,15 +1063,53 @@ IFACEMETHODIMP CMultipinMft::KsEvent(
1040
1063
--*/
1041
1064
{
1042
1065
1043
- HRESULT hr = S_OK;
1044
- // Handle the events here if you want, This sample passes the events to the driver
1045
- DMFTCHECKHR_GOTO (m_spIkscontrol->KsEvent (pEvent,
1046
- ulEventLength,
1047
- pEventData,
1048
- ulDataLength,
1049
- pBytesReturned), done);
1050
- done:
1051
- return hr;
1066
+ // HRESULT hr = S_OK;
1067
+ // handle the event if it is to set profile
1068
+ if (pEvent != nullptr
1069
+ && ulEventLength >= sizeof (KSEVENT)
1070
+ && pEvent->Set == KSEVENTSETID_ExtendedCameraControl
1071
+ && pEventData != nullptr
1072
+ && ulDataLength >= sizeof (KSEVENTDATA)
1073
+ && (pEvent->Id == KSPROPERTY_CAMERACONTROL_EXTENDED_PROFILE))
1074
+ {
1075
+
1076
+ m_hSelectedProfileKSEvent.reset ();
1077
+ RETURN_IF_WIN32_BOOL_FALSE (DuplicateHandle (
1078
+ GetCurrentProcess (),
1079
+ ((KSEVENTDATA*)(pEventData))->EventHandle .Event ,
1080
+ GetCurrentProcess (),
1081
+ &m_hSelectedProfileKSEvent,
1082
+ 0 ,
1083
+ FALSE ,
1084
+ DUPLICATE_SAME_ACCESS));
1085
+
1086
+ if (m_isProfileDDISupportedInBaseDriver.value_or (true ))
1087
+ {
1088
+ RETURN_IF_FAILED (m_hSelectedProfileKSEventSentToDriver.create ());
1089
+ KSEVENTDATA driverEventData = {};
1090
+ driverEventData.NotificationType = KSEVENTF_EVENT_HANDLE;
1091
+ driverEventData.EventHandle .Event = m_hSelectedProfileKSEventSentToDriver.get ();
1092
+ DMFTRACE (DMFT_GENERAL, TRACE_LEVEL_INFORMATION, " Handling profile set KsEvent, created profile KsEvent handle for driver: %p" , m_hSelectedProfileKSEventSentToDriver.get ());
1093
+
1094
+ // defer to source device
1095
+ auto hr = m_spIkscontrol->KsEvent (pEvent, ulEventLength, (void *)(&driverEventData), ulDataLength, pBytesReturned);
1096
+ if (FAILED (hr))
1097
+ {
1098
+ DMFTRACE (DMFT_GENERAL, TRACE_LEVEL_INFORMATION, " Failed to send profile KsEvent handle to driver: %p | hr=0x%08x" , m_hSelectedProfileKSEventSentToDriver.get (), hr);
1099
+ m_hSelectedProfileKSEventSentToDriver.reset ();
1100
+ m_isProfileDDISupportedInBaseDriver = false ;
1101
+ }
1102
+ }
1103
+ }
1104
+ else {
1105
+ // Pass the events to the driver
1106
+ RETURN_IF_FAILED (m_spIkscontrol->KsEvent (pEvent,
1107
+ ulEventLength,
1108
+ pEventData,
1109
+ ulDataLength,
1110
+ pBytesReturned));
1111
+ }
1112
+ return S_OK;
1052
1113
}
1053
1114
1054
1115
//
@@ -1293,6 +1354,102 @@ IFACEMETHODIMP CMultipinMft::Shutdown(
1293
1354
return ShutdownEventGenerator ();
1294
1355
}
1295
1356
1357
+ /* ++
1358
+ Description:
1359
+ Implements the KsProperty KSPROPERTY_CAMERACONTROL_EXTENDED_PROFILE handler.
1360
+ --*/
1361
+
1362
+ HRESULT CMultipinMft::ProfilePropertyHandler (
1363
+ _In_reads_bytes_ (ulPropertyLength) PKSPROPERTY pProperty,
1364
+ _In_ ULONG ulPropertyLength,
1365
+ _In_ LPVOID pPropertyData,
1366
+ _In_ ULONG ulDataLength,
1367
+ _Inout_ PULONG pulBytesReturned) try
1368
+ {
1369
+
1370
+ UNREFERENCED_PARAMETER (ulPropertyLength);
1371
+ HRESULT hr = S_OK;
1372
+
1373
+ if (pProperty->Flags & KSPROPERTY_TYPE_SET)
1374
+ {
1375
+ DMFTCHECKNULL_GOTO (pulBytesReturned, done, E_POINTER);
1376
+ *pulBytesReturned = sizeof (KSCAMERA_EXTENDEDPROP_HEADER_BUFFERED) + sizeof (KSCAMERA_EXTENDEDPROP_PROFILE);
1377
+ if (ulDataLength < *pulBytesReturned)
1378
+ {
1379
+ return HRESULT_FROM_WIN32 (ERROR_MORE_DATA);
1380
+ }
1381
+ if (pPropertyData)
1382
+ {
1383
+
1384
+ PBYTE pPayload = (PBYTE)pPropertyData;
1385
+ PKSCAMERA_EXTENDEDPROP_HEADER pExtendedHeader = &((PKSCAMERA_EXTENDEDPROP_HEADER_BUFFERED)pPayload)->header ;
1386
+ KSCAMERA_EXTENDEDPROP_PROFILE* pProfile = (PKSCAMERA_EXTENDEDPROP_PROFILE)(pExtendedHeader + 1 );
1387
+
1388
+ m_selectedProfileId.Type = pProfile->ProfileId ;
1389
+ m_selectedProfileId.Index = pProfile->Index ;
1390
+ m_selectedProfileId.Unused = pProfile->Reserved ;
1391
+
1392
+ if (m_selectedProfileId.Type == GUID_NULL)
1393
+ {
1394
+ DMFTRACE (DMFT_GENERAL, TRACE_LEVEL_WARNING, " The caller incorrectly sets GUID_NULL, default back to legacy." );
1395
+ m_selectedProfileId = { KSCAMERAPROFILE_Legacy, 0 , 0 };
1396
+ }
1397
+
1398
+ // signal we are done
1399
+ if (m_hSelectedProfileKSEvent.get () != nullptr )
1400
+ {
1401
+ if (m_hSelectedProfileKSEventSentToDriver != nullptr )
1402
+ {
1403
+ DMFTRACE (DMFT_GENERAL, TRACE_LEVEL_INFORMATION, " Waiting for driver profile KsEvent handle: %p" , m_hSelectedProfileKSEventSentToDriver.get ());
1404
+ if (!m_hSelectedProfileKSEventSentToDriver.wait (kMAX_WAIT_TIME_DRIVER_PROFILE_KSEVENT ))
1405
+ {
1406
+
1407
+ DMFTRACE (DMFT_GENERAL, TRACE_LEVEL_ERROR,
1408
+ " Waiting for driver profile KsEvent handle: %p timed out after %i ms, failing" ,
1409
+ m_hSelectedProfileKSEventSentToDriver.get (),
1410
+ kMAX_WAIT_TIME_DRIVER_PROFILE_KSEVENT );
1411
+ m_hSelectedProfileKSEvent.SetEvent ();
1412
+ RETURN_IF_FAILED (HRESULT_FROM_WIN32 (ERROR_TIMEOUT));
1413
+ }
1414
+ m_hSelectedProfileKSEventSentToDriver.reset ();
1415
+ }
1416
+ m_hSelectedProfileKSEvent.SetEvent ();
1417
+ m_hSelectedProfileKSEvent.reset ();
1418
+ }
1419
+ }
1420
+ }
1421
+ else if (pProperty->Flags & KSPROPERTY_TYPE_GET)
1422
+ {
1423
+ DMFTCHECKNULL_GOTO (pulBytesReturned, done, E_POINTER);
1424
+ *pulBytesReturned = sizeof (KSCAMERA_EXTENDEDPROP_HEADER_BUFFERED) + sizeof (KSCAMERA_EXTENDEDPROP_PROFILE);
1425
+ if (ulDataLength < *pulBytesReturned)
1426
+ {
1427
+ return HRESULT_FROM_WIN32 (ERROR_MORE_DATA);
1428
+ }
1429
+ if (pPropertyData)
1430
+ {
1431
+ if (!m_isProfileDDISupportedInBaseDriver.has_value ())
1432
+ {
1433
+ hr = m_spIkscontrol->KsProperty (pProperty, ulPropertyLength, pPropertyData, ulDataLength, pulBytesReturned);
1434
+ m_isProfileDDISupportedInBaseDriver = SUCCEEDED (hr);
1435
+ DMFTRACE (DMFT_GENERAL, TRACE_LEVEL_INFORMATION, " Profile DDI GET support on base driver: %d, hr=0x%08x" , m_isProfileDDISupportedInBaseDriver.value (), hr);
1436
+ *pulBytesReturned = sizeof (KSCAMERA_EXTENDEDPROP_HEADER_BUFFERED) + sizeof (KSCAMERA_EXTENDEDPROP_PROFILE);
1437
+ }
1438
+ }
1439
+ }
1440
+ // --GETPAYLOAD--
1441
+ else if (pProperty->Flags & KSPROPERTY_TYPE_GETPAYLOADSIZE)
1442
+ {
1443
+ RETURN_HR_IF_NULL (E_POINTER, pulBytesReturned);
1444
+ *pulBytesReturned = sizeof (KSCAMERA_EXTENDEDPROP_HEADER_BUFFERED) + sizeof (PKSCAMERA_EXTENDEDPROP_PROFILE);
1445
+ }
1446
+
1447
+ done:
1448
+ DMFTRACE (DMFT_GENERAL, TRACE_LEVEL_INFORMATION, " %!FUNC! exiting %x = %!HRESULT!" , hr, hr);
1449
+ return hr;
1450
+ } CATCH_RETURN()
1451
+
1452
+
1296
1453
//
1297
1454
// Static method to create an instance of the MFT.
1298
1455
//
0 commit comments