Media Foundation using C instead of C++ - c

I am learning to use the Media Foundation API from sample code shown in Microsoft website using C instead of C++. The sample code is shown below.
HRESULT CreateVideoCaptureDevice(IMFMediaSource **ppSource)
{
*ppSource = NULL;
UINT32 count = 0;
IMFAttributes *pConfig = NULL;
IMFActivate **ppDevices = NULL;
// Create an attribute store to hold the search criteria.
HRESULT hr = MFCreateAttributes(&pConfig, 1);
// Request video capture devices.
if (SUCCEEDED(hr))
{
hr = pConfig->SetGUID(
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
);
}
// Enumerate the devices,
if (SUCCEEDED(hr))
{
hr = MFEnumDeviceSources(pConfig, &ppDevices, &count);
}
// Create a media source for the first device in the list.
if (SUCCEEDED(hr))
{
if (count > 0)
{
hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(ppSource));
}
else
{
hr = MF_E_NOT_FOUND;
}
}
for (DWORD i = 0; i < count; i++)
{
ppDevices[i]->Release();
}
CoTaskMemFree(ppDevices);
return hr;
}
When I tried to build the sample code, I always get the following error:
error C2039: 'ActivateObject': is not a member of 'IMFActivate'
error C2039: 'Release': is not a member of 'IMFActivate'
error C2039: 'SetGUID': is not a member of 'IMFAttributes'
I explored the definition of IMFActivate and IMFAttributes (in mfidl.h) and I notice it have a C style interface.
May I know if anyone can show an example of how to use the interface ?

You should be using COM interfaces defined "C style", using virtual method table pointer:
IMFActivate* pMfActivate = ...
IMFMediaSource* pMfMediaSource;
pMfActivate->lpVtbl->ActivateObject(
pMfActivate, &IID_IMFMediaSource, (IUnknown**) &pMfMediaSource);
where C++ style is
IMFActivate* pMfActivate = ...
IMFMediaSource* pMfMediaSource;
pMfActivate->ActivateObject(
__uuidof(IMFMediaSource), (IUnknown**) &pMfMediaSource);

Related

Problem with windows api called ObRegisterCallbacks

I tried to debug my driver,but the debuged computer always stop at here.enter image description here
And after continue,debuged computer throw a blue screen directly with the error which says SYSTEM THREAD EXCEPTION NOT HANDLED.
I have searched to check the usage of this function,but all of them let the ObjectType equal PsProcessType directly with no error when running.Here is my code:
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
POB_CALLBACK_REGISTRATION callBackRegistration = { 0 };
POB_OPERATION_REGISTRATION operationRegistration = { 0 };
UNICODE_STRING altitude;
RtlInitUnicodeString(&altitude, L"60000");
operationRegistration->ObjectType = PsProcessType;//<-- Here is place where I get confused
operationRegistration->Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
operationRegistration->PreOperation = (POB_PRE_OPERATION_CALLBACK) & PobPreOperationCallback;
callBackRegistration->Version = OB_FLT_REGISTRATION_VERSION;
callBackRegistration->OperationRegistrationCount = 1;
callBackRegistration->Altitude = altitude;
callBackRegistration->RegistrationContext = NULL;
callBackRegistration->OperationRegistration = operationRegistration;
KdBreakPoint();
BypassSignCheck(DriverObject);
ObRegisterCallbacks(callBackRegistration,&hRegistration);
DriverObject->DriverUnload = UnloadDriver;
return STATUS_SUCCESS;
}
Change:
POB_CALLBACK_REGISTRATION callBackRegistration = { 0 };
POB_OPERATION_REGISTRATION operationRegistration = {
0 };
to
OB_CALLBACK_REGISTRATION callBackRegistration { };
OB_OPERATION_REGISTRATION operationRegistration { };
and then every time you have a '->' with one of these objects change it to a '.', and tka ethe address using '&' when calling functions.
Right now you have pointers but you never point them at valid objects, but since the rgistration is only needed locally there is no reason to not use stack-based objects.

Windows API authenticode get root certificate

I want to walk the certificate chain of a authenticode signed PE binary using the Windows API.
To get the certificate store I followed the example from Microsoft:
https://support.microsoft.com/en-us/help/323809/how-to-get-information-from-authenticode-signed-executables
With that I get the leaf certificate and the intermediate certificate, but not the root certificate. Tested with different Windows binaries (eg. explorer.exe)
I tried the following loops to walk the store:
while (pCertContext = CertFindCertificateInStore(hStore, ENCODING, 0, CERT_FIND_ANY, NULL, pCertContext));
while (pCertContext = CertEnumCertificatesInStore(hStore, pCertContext));
Is the root certificate not included in the authenticode signature?
Do I miss some option?
Thanks #RbMm for your suggestion with CertGetCertificateChain, that does solve my question.
To get the whole chain, you need to start at the leaf certificate (store seams to start top-down).
Adapted from https://learn.microsoft.com/de-de/windows/desktop/SecCrypto/example-c-program-creating-a-certificate-chain:
CERT_INFO CertInfo;
CertInfo.Issuer = pSignerInfo->Issuer;
CertInfo.SerialNumber = pSignerInfo->SerialNumber;
pCertContext = CertFindCertificateInStore(hStore, ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&CertInfo, NULL);
if (!pCertContext) {
_tprintf(_T("CertFindCertificateInStore failed with %x\n"), GetLastError());
__leave;
}
CERT_ENHKEY_USAGE EnhkeyUsage;
CERT_USAGE_MATCH CertUsage;
CERT_CHAIN_PARA ChainPara;
EnhkeyUsage.cUsageIdentifier = 0;
EnhkeyUsage.rgpszUsageIdentifier = NULL;
CertUsage.dwType = USAGE_MATCH_TYPE_AND;
CertUsage.Usage = EnhkeyUsage;
ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
ChainPara.RequestedUsage = CertUsage;
if (!CertGetCertificateChain(
NULL, // use the default chain engine
pCertContext, // pointer to the end certificate
NULL, // use the default time
NULL, // search no additional stores
&ChainPara, // use AND logic and enhanced key usage
// as indicated in the ChainPara
// data structure
dwFlags,
NULL, // currently reserved
&pChainContext)) {
cerr << "Error on CertGetCertificateChain" << endl;
__leave;
}
PCERT_SIMPLE_CHAIN rgpChain = NULL;
PCERT_CHAIN_ELEMENT rgpElement = NULL;
rgpChain = pChainContext->rgpChain[0];
for (int j = 0; j < rgpChain->cElement; j++) {
rgpElement = rgpChain->rgpElement[j];
PrintCertificateInfo(rgpElement->pCertContext);
cout << endl;
}

FFMPEG library add padding the plane/frame processed

I am trying to create a filter to be a part of FFMPEG. In the process of creating it I need to create a padding around the frame so the image does not resample, just has the needed width and height. I know this is possible with libswscale/swscale.h, but I have no been able to find any example as to how to do the padding for the plane that is being processed. Example code below:
if (av_frame_is_writable(in)) {
out = in;
} else {
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
av_frame_free(&in);
return AVERROR(ENOMEM);
}
av_frame_copy_props(out, in);
}
for (p = 0; p < filter->nb_planes; p++) {
// did not find any documentation as to
//how set those attributes to add padding to the plane
filter->sws_ctx = sws_getContext(src_w, src_h, src_pix_fmt,
dst_w, dst_h, dst_pix_fmt,
SWS_BILINEAR, NULL, NULL, NULL);
}
There is no other way as to do it inside the filter. The funcionality has to be implemented from vf_pad filter.
Credit: #durandal_1707 from from #ffmpeg IRC

How can I get screenshot from all displays with X11?

I was working on writing a screenshot thing, and found this excellent topic for Mac: How can I get screenshot from all displays on MAC?
I was wondering if anyone has the equivalent for x11 library? To get all the monitors and then screenshot them all?
I had found this topic: https://stackoverflow.com/a/5293559/1828637
But the code linked from there is not as easy to follow for a novice like me.
Will RootWindow(3) get the area of all the monitors combined? Then I can go through and get the monitors dimensions then XGetImage those sections on the return of RootWindow?
I had come across this topic: How do take a screenshot correctly with xlib? But I'm not sure if it has multi-monitor support. I do this in ctypes so I cant test that code easily without going through the grueling task of writing it first. So I was wondering if this is correct or how would I modify it to handle multi mon please?
Edit
The poster there shared his code, it is seen here: https://github.com/Lalaland/ScreenCap/blob/master/src/screenCapturerImpl.cpp#L96 but it's complicated and I don't understand it. It uses functions like XFixesGetCursorImage which I can't find in the documentation, and I don't see how the multi monitors work there. Author of that topic warned he doesn't remember the code and it may not work with modern Linux.
This is not a perfect answer to the question, but the following code could be modified to get a very fast version of your desired end result:
https://github.com/Clodo76/vr-desktop-mirror/blob/master/DesktopCapture/main.cpp
The DesktopCapturePlugin_Initialize method converts all the displays into objects:
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API DesktopCapturePlugin_Initialize()
{
DesksClean();
g_needReinit = 0;
IDXGIFactory1* factory;
CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&factory));
IDXGIAdapter1* adapter;
for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
{
IDXGIOutput* output;
for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); j++)
{
DXGI_OUTPUT_DESC outputDesc;
output->GetDesc(&outputDesc);
MONITORINFOEX monitorInfo;
monitorInfo.cbSize = sizeof(MONITORINFOEX);
GetMonitorInfo(outputDesc.Monitor, &monitorInfo);
// Maybe in future add a function to identify the primary monitor.
//if (monitorInfo.dwFlags == MONITORINFOF_PRIMARY)
{
int iDesk = DeskAdd();
g_desks[iDesk].g_width = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left;
g_desks[iDesk].g_height = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top;
auto device = g_unity->Get<IUnityGraphicsD3D11>()->GetDevice();
IDXGIOutput1* output1;
output1 = reinterpret_cast<IDXGIOutput1*>(output);
output1->DuplicateOutput(device, &g_desks[iDesk].g_deskDupl);
}
output->Release();
}
adapter->Release();
}
factory->Release();
}
Then the OnRenderEvent method copies a frame from the display into a texture (provided by unity in this case):
void UNITY_INTERFACE_API OnRenderEvent(int eventId)
{
for (int iDesk = 0; iDesk < g_nDesks; iDesk++)
{
if (g_desks[iDesk].g_deskDupl == nullptr || g_desks[iDesk].g_texture == nullptr)
{
g_needReinit++;
return;
}
IDXGIResource* resource = nullptr;
const UINT timeout = 0; // ms
HRESULT resultAcquire = g_desks[iDesk].g_deskDupl->AcquireNextFrame(timeout, &g_desks[iDesk].g_frameInfo, &resource);
if (resultAcquire != S_OK)
{
g_needReinit++;
return;
}
g_desks[iDesk].g_isPointerVisible = (g_desks[iDesk].g_frameInfo.PointerPosition.Visible == TRUE);
g_desks[iDesk].g_pointerX = g_desks[iDesk].g_frameInfo.PointerPosition.Position.x;
g_desks[iDesk].g_pointerY = g_desks[iDesk].g_frameInfo.PointerPosition.Position.y;
ID3D11Texture2D* texture;
HRESULT resultQuery = resource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&texture));
resource->Release();
if (resultQuery != S_OK)
{
g_needReinit++;
return;
}
ID3D11DeviceContext* context;
auto device = g_unity->Get<IUnityGraphicsD3D11>()->GetDevice();
device->GetImmediateContext(&context);
context->CopyResource(g_desks[iDesk].g_texture, texture);
g_desks[iDesk].g_deskDupl->ReleaseFrame();
}
g_needReinit = 0;
}

Scanning for BLE Devices from C/C++

from the "Bluetooth Device Access Guide", I've read that the Bluetooth API should be accessable from C or from C++. I've found some C-headers (IOBluetoothUserLib.h, Bluetooth.h) in the IOBluetooth framework that are related to Bluetooth and contain enumerations and data structured to define search creteria but I fail to find any function that takes such enumeration or data structure as parameter. According to the documentation I would have to create a CBCentralManager but I fail to find a way to do so from C or C++.
Background: We use OS/X as a developing plattform for devlopment of BLE enabled microcontrollers. To update firmware on this microcontrollers I want to write a BLE bootloader and I want to have a commandline client to update the firmware. All of the code is written in C++ and I wouldn't like to learn objectiv-C for this small task.
Any pointers, documentation, examples?
thank you
Torsten
According to the documentation I would have to create a CBCentralManager but I fail to find a way to do so from C or C++.
The documentation you refer to is for classic Bluetooth, for which the IOBluetooth framework has some functionality. CBCentralManager is the manager from CoreBluetooth, which is for Bluetooth LE only.
For classic Bluetooth, the manager you want is the HID Manager from the IOKit framework, documentation for which can be found here. If you search around, you'll find lots of examples of C++ usage of IOKit and IOHIDManager (1, 2).
IOKit may in fact give you all the functionality you need, but IOBluetooth supplies some Bluetooth specific features. From Developing Bluetooth Applications:
Although you don’t need to use the Bluetooth API to access a HID-class device, you may choose to use functions or methods from the Bluetooth framework to enhance the user’s experience. For example, your application can provide Bluetooth-specific information that lets the user know if a device doesn’t support a particular service.
I agreed with Henrik you'll need some glue. Look at RedBearLab guys work and precise to class.
ofxBLE. h/mm
// C++ interface //
// (Obj-C may be a superset of C, but this just makes interopability
// easier with oF)
class ofxBLE {
protected:
ofxBLEDelegate *btDelegate;
public:
ofxBLE();
~ofxBLE();
void scanPeripherals();
void sendPosition(uint8_t x, uint8_t y);
bool isConnected();
};
...
- (void)bleDidDisconnect {
NSLog(#"->Disconnected");
}
- (void)bleDidReceiveData:(unsigned char *)data length:(int)length {
}
#end
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
//= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// C++ class implementation
ofxBLE::ofxBLE() {
btDelegate = [[ofxBLEDelegate alloc] init];
}
ofxBLE::~ofxBLE() {
}
void ofxBLE::scanPeripherals(){
[btDelegate scanForPeripherals];
}
void ofxBLE::sendPosition(uint8_t x, uint8_t y) {
// position should be NORMALIZED to between 0 and 255 BEFORE
// passing into this method!
[btDelegate sendPositionX:x withY:y];
}

Resources