I'm writing a thumbnail handler for a custom file type. When I register it, it returns with a success message. The "thumbnail" is shown as completely blank, but it does not say "no thumbnail available". The problem is, the actual thumbnail handler never gets called. I know this, because I put a series of statements in my handler under handler::initialize, handler::queryinterface and handler::getthumbnail. I have gone through most of this documentation., but all I can find is that I need to use initialize and getthumbnail. Here is my code:
Header:
#pragma once
#include <windows.h>
#include <thumbcache.h> // For IThumbnailProvider
#include <wincodec.h> // Windows Imaging Codecs
#include <fstream>
#include <iostream>
#pragma comment(lib, "windowscodecs.lib")
class ThumbnailProvider :
public IInitializeWithStream,
public IThumbnailProvider
{
public:
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void **ppv);
IFACEMETHODIMP_(ULONG) AddRef();
IFACEMETHODIMP_(ULONG) Release();
// IInitializeWithStream
IFACEMETHODIMP Initialize(IStream *pStream, DWORD grfMode);
// IThumbnailProvider
IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha);
ThumbnailProvider();
protected:
~ ThumbnailProvider();
private:
// Reference count of component.
long m_cRef;
// Provided during initialization.
IStream *m_pStream;
std::ofstream output;
void stripImageFrom (IStream *stream, HBITMAP *phbmp);
};
Body:
#include " ThumbnailProvider.h"
#include <Shlwapi.h>
#include <Wincrypt.h> // For CryptStringToBinary.
#include <msxml6.h>
#include <atlimage.h>
#include <fstream>
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "Crypt32.lib")
#pragma comment(lib, "msxml6.lib")
extern HINSTANCE g_hInst;
extern long g_cDllRef;
ThumbnailProvider:: ThumbnailProvider() : m_cRef(1), m_pStream(NULL)
{
std::ofstream st;
st.open("C:\\Users\\labs\\Desktop\\Output\\out.txt", std::ios_base::app);
st << "Made provider";
st.close();
InterlockedIncrement(&g_cDllRef);
}
ThumbnailProvider::~ ThumbnailProvider()
{
InterlockedDecrement(&g_cDllRef);
}
#pragma region IUnknown
// Query to the interface the component supported.
IFACEMETHODIMP ThumbnailProvider::QueryInterface(REFIID riid, void **ppv)
{
std::ofstream st;
st.open("C:\\Users\\labs\\Desktop\\Output\\out.txt", std::ios_base::app);
st << "Querying interface";
st.close();
static const QITAB qit[] =
{
QITABENT( ThumbnailProvider, IThumbnailProvider),
QITABENT( ThumbnailProvider, IInitializeWithStream),
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
// Increase the reference count for an interface on an object.
IFACEMETHODIMP_(ULONG) ThumbnailProvider::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
// Decrease the reference count for an interface on an object.
IFACEMETHODIMP_(ULONG) ThumbnailProvider::Release()
{
ULONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
{
delete this;
}
return cRef;
}
#pragma endregion
#pragma region IInitializeWithStream
// Initializes the thumbnail handler with a stream.
IFACEMETHODIMP ThumbnailProvider::Initialize(IStream *pStream, DWORD grfMode)
{
std::ofstream st;
st.open("C:\\Users\\labs\\Desktop\\Output\\out.txt", std::ios_base::app);
st << "Got to initialization";
st.close();
// A handler instance should be initialized only once in its lifetime.
HRESULT hr = HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED);
if (m_pStream == NULL)
{
// Take a reference to the stream if it has not been initialized yet.
hr = pStream->QueryInterface(&m_pStream);
}
return hr;
}
#pragma endregion
#pragma region IThumbnailProvider
// Gets a thumbnail image and alpha type. The GetThumbnail is called with the
// largest desired size of the image, in pixels. Although the parameter is
// called cx, this is used as the maximum size of both the x and y dimensions.
// If the retrieved thumbnail is not square, then the longer axis is limited
// by cx and the aspect ratio of the original image respected. On exit,
// GetThumbnail provides a handle to the retrieved image. It also provides a
// value that indicates the color at of the image and whether it has
// valid alpha in ation.
IFACEMETHODIMP ThumbnailProvider::GetThumbnail(UINT cx, HBITMAP *phbmp,
WTS_ALPHATYPE *pdwAlpha) {
std::ofstream st;
st.open("C:\\Users\\labs\\Desktop\\Output\\out.txt", std::ios_base::app);
st << "Getting thumbnail";
st.close();
ThumbnailProvider::stripImageFrom (m_pStream, phbmp);
cx = 1024 * 1024;
*pdwAlpha = WTSAT_UNKNOWN;
return S_OK;
}
#pragma endregion
#pragma region Helper Functions
// The PNG signature is 137 80 78 71 13 10 26 10. This does not make sense to do backward. I will do it forward.
void ThumbnailProvider::stripImageFrom (IStream *stream, HBITMAP *phbmp) {
unsigned long numBytes = 0;
unsigned long *numBytesPtr = &numBytes;
char *chptr = nullptr;
byte vals[8] = { 0 };
STATSTG *stat = nullptr;
DWORD temp = NULL;
stream->Stat(stat, temp);
unsigned long long length = stat->cbSize.QuadPart;
unsigned long long i;
for (i = 0; i<length; i++) {
stream->Read(chptr, 1, numBytesPtr);
if (*chptr == 137) {
vals[0] = 1;
}
else if (*chptr == 80 && vals[0]) {
vals[1] = 1;
}
else if (*chptr == 78 && vals[1]) {
vals[2] = 1;
}
else if (*chptr == 71 && vals[2]) {
vals[3] = 1;
}
else if (*chptr == 13 && vals[3]) {
vals[4] = 1;
}
else if (*chptr == 10 && vals[4] && !vals[5]) {
vals[5] = 1;
}
else if (*chptr == 26 && vals[5]) {
vals[6] = 1;
}
else if (*chptr == 10 && vals[6]) {
vals[7] = 1;
i -= 7;
break;
}
else {
memset(vals, 0, 8 * sizeof(vals[0]));
}
}
if (vals[7]) {
IStream *imgstream = nullptr;
stream->Read(imgstream, length-i, numBytesPtr);
CImage *img = nullptr;
img->Load(imgstream);
*phbmp = *img;
}
}
#pragma endregion
Everything else is just edited from one of Microsoft's examples, so I am pretty sure that is ok. The example is here.
If you're having this problem, make sure you're building for the right architecture. That solved it for me.
Related
I am attempting to write some code that connects the Windows::Graphics::Capture API to IMFSinkWriter in order to capture the desktop to an MP4 file. I find that the IMFSinkWriter WriteSample function always returns 0x80070057 and I'm trying to understand why. I suspect there is a somewhat obvious mistake as I am not extremely familiar with COM, WinRT, DirectX, etc. Any ideas?
#include <iostream>
#include <Windows.h>
// XXX workaround bug in platform headers where this has a circular declaration
#include "winrt/base.h"
namespace winrt::impl
{
template <typename Async>
auto wait_for(Async const& async, Windows::Foundation::TimeSpan const& timeout);
}
// XXX
#include <dxgi.h>
#include <inspectable.h>
#include <dxgi1_2.h>
#include <d3d11.h>
#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
#include <codecapi.h>
#include <strmif.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.System.h>
#include <winrt/Windows.Graphics.Capture.h>
#include <windows.graphics.capture.interop.h>
#include <windows.graphics.directx.direct3d11.interop.h>
#pragma comment(lib, "Mfuuid.lib")
#pragma comment(lib, "Mfplat.lib")
#pragma comment(lib, "mfreadwrite.lib")
#pragma comment(lib, "Mf.lib")
winrt::com_ptr<IMFSinkWriter> sinkWriter;
std::chrono::steady_clock::time_point firstFrameTime;
std::chrono::steady_clock::time_point lastFrameTime;
bool recordedFirstFrame = false;
void OnFrameArrived(winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool const& sender, winrt::Windows::Foundation::IInspectable const &) {
winrt::Windows::Graphics::Capture::Direct3D11CaptureFrame frame = sender.TryGetNextFrame();
std::chrono::steady_clock::time_point frameTime = std::chrono::steady_clock::now();
LONGLONG duration = 0;
LONGLONG frametime100ns;
if (!recordedFirstFrame) {
recordedFirstFrame = true;
firstFrameTime = frameTime;
frametime100ns = 0;
}
else {
frametime100ns = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - firstFrameTime).count() / 100;
duration = std::chrono::duration_cast<std::chrono::milliseconds>(frameTime - lastFrameTime).count();
}
auto surface = frame.Surface();
auto access = surface.as<Windows::Graphics::DirectX::Direct3D11::IDirect3DDxgiInterfaceAccess>();
winrt::com_ptr<ID3D11Texture2D> texture;
winrt::check_hresult(access->GetInterface(winrt::guid_of<ID3D11Texture2D>(), texture.put_void()));
IMFMediaBuffer* buffer;
MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), texture.get(), 0, FALSE, &buffer);
IMFSample *sample;
winrt::check_hresult(MFCreateSample(&sample));
HRESULT hr = sample->AddBuffer(buffer);
printf("add buffer! %x\n", hr);
hr = sample->SetSampleTime(frametime100ns);
printf("set sample time (%lld) %d\n", frametime100ns, hr);
hr = sample->SetSampleDuration(duration);
printf("set sample duration (%lld) %d\n", duration, hr);
hr = sinkWriter->WriteSample(0 /* video stream index */, sample);
printf("wrote sample %x\n", hr);
lastFrameTime = frameTime;
}
int main()
{
winrt::init_apartment(winrt::apartment_type::multi_threaded);
winrt::check_hresult(MFStartup(MF_VERSION, MFSTARTUP_NOSOCKET));
// get a list of monitor handles
std::vector<HMONITOR> monitors;
EnumDisplayMonitors(
nullptr, nullptr,
[](HMONITOR hmon, HDC, LPRECT, LPARAM lparam) {
auto& monitors = *reinterpret_cast<std::vector<HMONITOR>*>(lparam);
monitors.push_back(hmon);
return TRUE;
},
reinterpret_cast<LPARAM>(&monitors)
);
//get GraphicsCaptureItem for first monitor
auto interop_factory = winrt::get_activation_factory<winrt::Windows::Graphics::Capture::GraphicsCaptureItem, IGraphicsCaptureItemInterop>();
winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = { nullptr };
winrt::check_hresult(
interop_factory->CreateForMonitor(
monitors[0],
winrt::guid_of<ABI::Windows::Graphics::Capture::IGraphicsCaptureItem>(),
winrt::put_abi(item)
)
);
// Create Direct 3D Device
winrt::com_ptr<ID3D11Device> d3dDevice;
winrt::check_hresult(D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
nullptr, 0, D3D11_SDK_VERSION, d3dDevice.put(), nullptr, nullptr));
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice device;
const auto dxgiDevice = d3dDevice.as<IDXGIDevice>();
{
winrt::com_ptr<::IInspectable> inspectable;
winrt::check_hresult(CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.get(), inspectable.put()));
device = inspectable.as<winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice>();
}
auto idxgiDevice2 = dxgiDevice.as<IDXGIDevice2>();
winrt::com_ptr<IDXGIAdapter> adapter;
winrt::check_hresult(idxgiDevice2->GetParent(winrt::guid_of<IDXGIAdapter>(), adapter.put_void()));
winrt::com_ptr<IDXGIFactory2> factory;
winrt::check_hresult(adapter->GetParent(winrt::guid_of<IDXGIFactory2>(), factory.put_void()));
ID3D11DeviceContext* d3dContext = nullptr;
d3dDevice->GetImmediateContext(&d3dContext);
// setup swap chain
DXGI_SWAP_CHAIN_DESC1 desc = {};
desc.Width = static_cast<uint32_t>(item.Size().Width);
desc.Height = static_cast<uint32_t>(item.Size().Height);
desc.Format = static_cast<DXGI_FORMAT>(winrt::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16B16A16Float);
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.BufferCount = 2;
desc.Scaling = DXGI_SCALING_STRETCH;
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
desc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
winrt::com_ptr<IDXGISwapChain1> swapchain;
winrt::check_hresult(factory->CreateSwapChainForComposition(d3dDevice.get(), &desc, nullptr, swapchain.put()));
auto framepool = winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool::CreateFreeThreaded(device, winrt::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16B16A16Float, 2, item.Size());
auto session = framepool.CreateCaptureSession(item);
framepool.FrameArrived(OnFrameArrived);
//Setup MF output stream
winrt::com_ptr<IMFDXGIDeviceManager> devManager;
UINT resetToken;
winrt::check_hresult(MFCreateDXGIDeviceManager(&resetToken, devManager.put()));
winrt::check_hresult(devManager->ResetDevice(d3dDevice.get(), resetToken));
winrt::com_ptr<IMFByteStream> outputStream;
winrt::check_hresult(MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, L"C:\\test.mp4", outputStream.put()));
//configure MF output media type
winrt::com_ptr<IMFMediaType> videoMediaType;
//winrt::com_ptr<IMFMediaType> audioMediaType;
//for video
winrt::check_hresult(MFCreateMediaType(videoMediaType.put()));
winrt::check_hresult(videoMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
winrt::check_hresult(videoMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264));
winrt::check_hresult(videoMediaType->SetUINT32(MF_MT_AVG_BITRATE, 2000000));
winrt::check_hresult(videoMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
winrt::check_hresult(videoMediaType->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_Main));
winrt::check_hresult(videoMediaType->SetUINT32(MF_MT_YUV_MATRIX, MFVideoTransferMatrix_BT601));
winrt::check_hresult(MFSetAttributeSize(videoMediaType.get(), MF_MT_FRAME_SIZE, item.Size().Width, item.Size().Height));
winrt::check_hresult(MFSetAttributeRatio(videoMediaType.get(), MF_MT_FRAME_RATE, 30, 1));
winrt::check_hresult(MFSetAttributeRatio(videoMediaType.get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1));
//Creates a streaming writer
winrt::com_ptr<IMFMediaSink> mp4StreamSink;
winrt::check_hresult(MFCreateMPEG4MediaSink(outputStream.get(), videoMediaType.get(), NULL, mp4StreamSink.put()));
//setup MF Input stream
winrt::com_ptr<IMFMediaType> inputVideoMediaType;
HRESULT hr = S_OK;
GUID majortype = { 0 };
MFRatio par = { 0 };
hr = videoMediaType->GetMajorType(&majortype);
if (majortype != MFMediaType_Video)
{
throw new winrt::hresult_invalid_argument();
}
// Create a new media type and copy over all of the items.
// This ensures that extended color information is retained.
winrt::check_hresult(MFCreateMediaType(inputVideoMediaType.put()));
winrt::check_hresult(videoMediaType->CopyAllItems(inputVideoMediaType.get()));
// Set the subtype.
winrt::check_hresult(inputVideoMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_ARGB32));
// Uncompressed means all samples are independent.
winrt::check_hresult(inputVideoMediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE));
// Fix up PAR if not set on the original type.
hr = MFGetAttributeRatio(
inputVideoMediaType.get(),
MF_MT_PIXEL_ASPECT_RATIO,
(UINT32*)&par.Numerator,
(UINT32*)&par.Denominator
);
// Default to square pixels.
if (FAILED(hr))
{
winrt::check_hresult(MFSetAttributeRatio(
inputVideoMediaType.get(),
MF_MT_PIXEL_ASPECT_RATIO,
1, 1
));
}
winrt::check_hresult(MFSetAttributeSize(inputVideoMediaType.get(), MF_MT_FRAME_SIZE, item.Size().Width, item.Size().Height));
inputVideoMediaType->SetUINT32(MF_MT_VIDEO_ROTATION, MFVideoRotationFormat_0); //XXX where do we get the rotation from?
winrt::com_ptr<IMFAttributes> attributes;
winrt::check_hresult(MFCreateAttributes(attributes.put(), 6));
winrt::check_hresult(attributes->SetGUID(MF_TRANSCODE_CONTAINERTYPE, MFTranscodeContainerType_MPEG4));
winrt::check_hresult(attributes->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 1));
winrt::check_hresult(attributes->SetUINT32(MF_MPEG4SINK_MOOV_BEFORE_MDAT, 1));
winrt::check_hresult(attributes->SetUINT32(MF_LOW_LATENCY, FALSE)); ///XXX should we?
winrt::check_hresult(attributes->SetUINT32(MF_SINK_WRITER_DISABLE_THROTTLING, FALSE)); //XX shuold we?
// Add device manager to attributes. This enables hardware encoding.
winrt::check_hresult(attributes->SetUnknown(MF_SINK_WRITER_D3D_MANAGER, devManager.get()));
//winrt::com_ptr<IMFSinkWriter> sinkWriter;
winrt::check_hresult(MFCreateSinkWriterFromMediaSink(mp4StreamSink.get(), attributes.get(), sinkWriter.put()));
sinkWriter->SetInputMediaType(0, inputVideoMediaType.get(), nullptr);
winrt::com_ptr<ICodecAPI> encoder;
sinkWriter->GetServiceForStream(0 /* video stream index */, GUID_NULL, IID_PPV_ARGS(encoder.put()));
VARIANT var;
VariantInit(&var);
var.vt = VT_UI4;
var.ulVal = eAVEncCommonRateControlMode_Quality;
winrt::check_hresult(encoder->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var));
var.ulVal = 70;
winrt::check_hresult(encoder->SetValue(&CODECAPI_AVEncCommonQuality, &var));
winrt::check_hresult(sinkWriter->BeginWriting());
session.StartCapture();
std::cout << "Hello World!\n";
Sleep(1000);
session.Close();
sinkWriter->Flush(0);
sinkWriter->Finalize();
}
I was able to track down the problem. The above code had two issues:
Need to call SetCurrentLength() on the IMFMediaBuffer object. It seems silly since the way to get the length is to get the IMF2DBuffer interface from the IMFMediaBuffer object and call GetContiguousLength(), but it works.
Taking the texture straight from the OnFrameArrived() callback and passing it into the IMF sink is also wrong. This will exhaust the framepool (which is declared as having 2 frames) and hang the encoder. One possible solution is to copy the data out into a new texture before passing it to the encoder.
In my project,
I implement a new class called myApp which inherits from ApplicationBase and UdpSocket classes. When I build my project I get no error, but when I debug C/C++ application with the IDE, it displays the first error in errors section. And the command line display the second error when I run make :
Code of myApp.ned, myApp.h and myApp.cc in what follows :
I did include inet library in project references, and I tried the solution posted in The following NED types could not be fully resolved, due to a missing base type or interface.
import inet.applications.contract.IApp;
simple myApp like IApp
{
parameters:
int localPort = default(-1); // local UDP port number (-1: use ephemeral port)
int destPort; // remote UDP port number
string packetName = default("myApp");
string interfaceTableModule; // The path to the InterfaceTable module
double helloInterval #unit(s) = default(5s); // how often hello messages should be sent out
volatile double sendInterval #unit(s); // should usually be a random value, e.g. exponential(1)
double startTime #unit(s) = default(this.sendInterval); // application start time (start of the first packet)
double stopTime #unit(s) = default(-1s); // time of finishing sending, -1s means forever
double maxVariance = default(1); // This is the maximum of a random value to determine when the first hello message will be sent out
volatile double broadcastDelay #unit(s) = default(uniform(0s,0.01s));
int timeToLive = default(-1); // if not -1, set the TTL (IPv4) or Hop Limit (IPv6) field of sent packets to this value
bool dontFragment = default(false); // if true, asks IP to not fragment the message during routing
int typeOfService = default(-1); // if not -1, set the ToS (IPv4) or Traffic Class (IPv6) field of sent packets to this value
string multicastInterface = default(""); // if not empty, set the multicast output interface option on the socket (interface name expected)
bool receiveBroadcast = default(false); // if true, makes the socket receive broadcast packets
bool joinLocalMulticastGroups = default(false); // if true, makes the socket receive packets from all multicast groups set on local interfaces
#class(myApp);
gates:
input socketIn #labels(UdpControlInfo/up);
output socketOut #labels(UdpControlInfo/down);
}
#ifndef MYAPP_H_
#define MYAPP_H_
#include "inet/common/INETDefs.h"
#include "inet/applications/base/ApplicationBase.h"
#include "inet/transportlayer/contract/udp/UdpSocket.h"
#include "inet/transportlayer/contract/udp/UdpControlInfo_m.h"
#include "inet/common/ModuleAccess.h"
#include "inet/common/TimeTag_m.h"
#include "inet/common/packet/Packet.h"
#include "inet/common/lifecycle/ModuleOperations.h"
#include "inet/common/IProtocolRegistrationListener.h"
#include "inet/common/ProtocolTag_m.h"
#include "inet/linklayer/common/InterfaceTag_m.h"
#include "inet/networklayer/contract/IInterfaceTable.h"
#include "inet/networklayer/contract/ipv4/Ipv4Address.h"
#include "inet/networklayer/ipv4/IIpv4RoutingTable.h"
#include "inet/networklayer/ipv4/Ipv4Header_m.h"
#include "inet/networklayer/ipv4/Ipv4InterfaceData.h"
#include "inet/networklayer/common/FragmentationTag_m.h"
#include "inet/networklayer/common/L3AddressResolver.h"
#include "HelloMsg_m.h"
#include "XedMsg_m.h"
#include <omnetpp.h>
#include <vector>
#include <random>
#include <algorithm>
using namespace omnetpp;
using namespace inet;
using namespace std;
class myApp : public ApplicationBase, public UdpSocket::ICallback
{
protected:
//enum SelfMsgKinds { START = 1, SEND, STOP };
int localPort = -1, destPort = -1;
bool dontFragment = false;
const char *packetName = nullptr;
simtime_t startTime;
simtime_t stopTime;
// state
UdpSocket socket;
cMessage *selfMsg = nullptr;
cModule *host = nullptr;
cMessage *event = nullptr;
cPar *broadcastDelay = nullptr;
unsigned int sequencenumber = 0;
simtime_t helloInterval;
IInterfaceTable *ift = nullptr;
InterfaceEntry *interface80211ptr = nullptr;
int interfaceId = -1;
list<L3Address> neighbors;
Ipv4Address source;
/********** XED **********/
class XED
{
public:
L3Address originatorAddr, destinationAddr;
unsigned int random;
XED(const L3Address& originatorAddr, const L3Address& destinationAddr, unsigned int random)
: originatorAddr(originatorAddr), destinationAddr(destinationAddr), random(random) {};
bool operator==(const XED& other) const
{
return this->originatorAddr == other.originatorAddr && this->destinationAddr == other.destinationAddr
&& this->random == other.random;
}
};
list<XED> lr,ls;
/********** MTLSD **********/
class MTLSD
{
public:
L3Address originatorAddr, destinationAddr;
char *position;
simtime_t time;
MTLSD(const L3Address& originatorAddr, const L3Address& destinationAddr, char *position, simtime_t time)
: originatorAddr(originatorAddr), destinationAddr(destinationAddr), position(position), time(time) {};
bool operator==(const MTLSD& other) const
{
return this->originatorAddr == other.originatorAddr && this->destinationAddr == other.destinationAddr
&& this->position == other.position && this->time == time;
}
};
protected:
virtual int numInitStages() const override { return NUM_INIT_STAGES; }
virtual void initialize(int stage) override;
virtual void handleMessageWhenUp(cMessage *msg) override;
void handleSelfMessage(cMessage *msg);
/*virtual void processStart();
virtual void processSend();
virtual void processStop();*/
// lifecycle
virtual void handleStartOperation(LifecycleOperation *operation) override { start(); }
virtual void handleStopOperation(LifecycleOperation *operation) override { stop(); }
virtual void handleCrashOperation(LifecycleOperation *operation) override { stop(); }
void start();
void stop();
virtual void socketDataArrived(UdpSocket *socket, Packet *packet) override;
virtual void socketErrorArrived(UdpSocket *socket, Indication *indication) override;
virtual void socketClosed(UdpSocket *socket) override;
//virtual void generateMTLSDPacket();
//virtual Packet *generateXEDPacket();
virtual double generateRandom();
public:
myApp() {}
~myApp();
};
#endif /* MYAPP_H_ */
#include "myApp.h"
#include "inet/applications/base/ApplicationPacket_m.h"
#include "inet/applications/udpapp/UdpBasicApp.h"
#include "inet/common/TagBase_m.h"
#include "inet/networklayer/common/L3AddressTag_m.h"
#include <iterator>
using namespace std;
Define_Module(myApp);
myApp::~myApp()
{
EV << "App destructor" << endl;
cancelAndDelete(selfMsg);
}
void myApp::initialize(int stage)
{
ApplicationBase::initialize(stage);
if (stage == INITSTAGE_LOCAL)
{
sequencenumber = 0;
ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
event = new cMessage("event");
broadcastDelay = &par("broadcastDelay");
helloInterval = par("helloInterval");
localPort = par("localPort");
destPort = par("destPort");
packetName = par("packetName");
startTime = par("startTime");
stopTime = par("stopTime");
}
else if (stage == INITSTAGE_ROUTING_PROTOCOLS)
{
registerService(Protocol::manet, nullptr, gate("socketIn"));
registerProtocol(Protocol::manet, gate("socketOut"), nullptr);
}
}
void myApp::handleSelfMessage(cMessage *msg)
{
if (msg == event)
{
auto hello = makeShared<HelloMsg>();
Ipv4Address source = (interface80211ptr->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
hello->setChunkLength(b(128));
hello->setSrcAddress(source);
sequencenumber += 2;
hello->setSequencenumber(sequencenumber);
hello->setNextAddress(source);
hello->setHopdistance(1);
auto packet = new Packet("Hello", hello);
packet->addTagIfAbsent<L3AddressReq>()->setDestAddress(Ipv4Address(255, 255, 255, 255));
packet->addTagIfAbsent<L3AddressReq>()->setSrcAddress(source);
packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(interface80211ptr->getInterfaceId());
packet->addTagIfAbsent<PacketProtocolTag>()->setProtocol(&Protocol::manet);
packet->addTagIfAbsent<DispatchProtocolReq>()->setProtocol(&Protocol::ipv4);
send(packet, "socketOut");
packet = nullptr;
hello = nullptr;
scheduleAt(simTime()+helloInterval+broadcastDelay->doubleValue(), event);
}
}
void myApp::handleMessageWhenUp(cMessage *msg)
{
if (msg->isSelfMessage())
{
handleSelfMessage(msg);
}
else if (check_and_cast<Packet *>(msg)->getTag<PacketProtocolTag>()->getProtocol() == &Protocol::manet)
{
auto recHello = staticPtrCast<HelloMsg>(check_and_cast<Packet *>(msg)->peekData<HelloMsg>()->dupShared());
if (msg->arrivedOn("socketIn"))
{
bubble("Received hello message");
Ipv4Address source = interface80211ptr->getProtocolData<Ipv4InterfaceData>()->getIPAddress();
Ipv4Address src;
unsigned int msgsequencenumber;
int numHops;
Ipv4Address next;
src = recHello->getSrcAddress();
msgsequencenumber = recHello->getSequencenumber();
next = recHello->getNextAddress();
numHops = recHello->getHopdistance();
if (src == source)
{
EV_INFO << "Hello msg dropped. This message returned to the original creator.\n";
delete msg;
return;
}
else
{
neighbors.push_back(src);
/*list<XED>::iterator findIter = find(ls.begin()->destinationAddr, ls.end()->destinationAddr, src);
if (findIter != ls.end()->destinationAddr)
{
}*/
source = (interface80211ptr->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
//socket.bind(source, localPort);
auto xed = makeShared<XedMsg>();
xed->setChunkLength(b(128)); ///size of XED message in bits
xed->setSrcAddress(source);
xed->setDstAddress(src);
double random = generateRandom();
xed->setRandom(random);
//XED item = XED(source, src, random);
//ls.push_back(item);
auto packet = new Packet("XED", xed);
packet->addTagIfAbsent<L3AddressReq>()->setDestAddress(src);
packet->addTagIfAbsent<L3AddressReq>()->setSrcAddress(source);
packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(interfaceId);
packet->addTagIfAbsent<PacketProtocolTag>()->setProtocol(&Protocol::ipv4);
packet->addTagIfAbsent<DispatchProtocolReq>()->setProtocol(&Protocol::ipv4);
socket.setOutputGate(gate("socketOut"));
socket.setCallback(this);
socket.bind(source, localPort);
//emit(packetSentSignal, packet);
socket.sendTo(packet, src, destPort);
//send(packet, "socketOut");
packet = nullptr;
xed = nullptr;
/*Ipv4Address source = (interface80211ptr->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
EV << "I am node " << source << ", my neighbors are : " << endl;
list<L3Address>::iterator it;
for (it = neighbors.begin(); it != neighbors.end(); ++it)
{
EV << it. << endl;
}
for (auto const& i : neighbors)
{
EV << i.str() << endl;
}*/
EV << "I am your neighbor " << src.str();
}
delete msg;
}
else if (check_and_cast<Packet *>(msg)->getTag<PacketProtocolTag>()->getProtocol() == &Protocol::ipv4)
{
EV << "Xed message received" << endl;
//auto recXed = staticPtrCast<XedMsg>(check_and_cast<Packet *>(msg)->peekData<XedMsg>()->dupShared());
}
else
throw cRuntimeError("Message arrived on unknown gate %s", msg->getArrivalGate()->getName());
}
}
void myApp::start()
{
/*socket.setOutputGate(gate("socketOut"));
socket.setCallback(this);*/
int num_80211 = 0;
InterfaceEntry *ie;
InterfaceEntry *i_face;
const char *name;
for (int i = 0; i < ift->getNumInterfaces(); i++)
{
ie = ift->getInterface(i);
name = ie->getInterfaceName();
if (strstr(name, "wlan") != nullptr)
{
i_face = ie;
num_80211++;
interfaceId = i;
}
}
if (num_80211 == 1)
{
interface80211ptr = i_face;
interfaceId = interface80211ptr->getInterfaceId();
}
else
throw cRuntimeError("Node has found %i 80211 interfaces", num_80211);
scheduleAt(simTime() + uniform(0.0, par("maxVariance").doubleValue()), event);
}
double myApp::generateRandom()
{
double lower_bound = 10000;
double upper_bound = 100000;
uniform_real_distribution<double> unif(lower_bound,upper_bound);
default_random_engine re;
double a_random_double = unif(re);
return a_random_double;
}
void myApp::stop()
{
cancelEvent(event);
socket.close();
delayActiveOperationFinish(par("stopOperationTimeout"));
}
void myApp::socketDataArrived(UdpSocket *socket, Packet *packet)
{
emit(packetReceivedSignal, packet);
EV_INFO << "Received packet: " << UdpSocket::getReceivedPacketInfo(packet) << endl;
}
void myApp::socketErrorArrived(UdpSocket *socket, Indication *indication)
{
EV_WARN << "Ignoring UDP error report " << indication->getName() << endl;
delete indication;
}
void myApp::socketClosed(UdpSocket *socket)
{
if (operationalState == State::STOPPING_OPERATION)
startActiveOperationExtraTimeOrFinish(par("stopOperationExtraTime"));
}
Error: NED type 'myApp' could not be fully resolved due to a missing base type or interface, at /home/bocuhra/Downloads/omnetpp-5.4.1/samples/SaaS/myApp.ned:18
myApp.cc
HelloMsg_m.cc
XedMsg_m.cc
Creating executable: out/gcc-release//SaaS
/usr/bin/ld: cannot find -lINET
collect2: error: ld returned 1 exit status
Makefile:104: recipe for target 'out/gcc-release//SaaS' failed
make: *** [out/gcc-release//SaaS] Error 1
I did solve the problem by adding all ned files in my .ini file.
ned-path = .;../inet/src/inet
I'm trying make simple code call an enclave field and just add 1.
I'm reference this site : https://software.intel.com/en-us/articles/getting-started-with-sgx-sdk-f...
After it finishes, there is no error, but the enclave code is not working.
Here is my project.zip code with Visual Studio 2017 https://drive.google.com/open?id=13trTAamhNWaz2Q2BRDtUFP5qCX8Syyuc
app.cpp
#include <stdio.h>
#include <Windows.h>
#include <tchar.h>
#include "sgx_urts.h"
#include "Enclave1_u.h"
#define ENCLAVE_FILE _T("Enclave1.signed.dll")
int main() {
int a = 1;
int i = 0;
sgx_enclave_id_t eid;
sgx_status_t ret = SGX_SUCCESS;
sgx_launch_token_t token = { 0 };
int updated = 0;
ret = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated, &eid, NULL);
if (ret != SGX_SUCCESS)
{
printf("APP error%#x, failed to create enclave. \n", ret);
return -1;
}
int *ptr = &a;
printf("%d\n",*ptr);
while (i<5) {
foo(eid, ptr);
printf("%d\n", *ptr);
Sleep(1000);
i++;
}
if (SGX_SUCCESS != sgx_destroy_enclave(eid))
return -1;
}
Enclave1.edl
enclave {
from "sgx_tstdc.edl" import *;
trusted {
/* define ECALLs here. */
public void foo([in, size = 4]int *ptr);
};
untrusted {
/* define OCALLs here. */
};
};
Enclave1.cpp
#include "Enclave1_t.h"
#include "sgx_trts.h"
#include <string.h>
void foo(int *ptr)
{
if (*ptr == 1) *ptr == 43971;
*ptr += 1;
}
I expected it to print:
43971, 43972, 43973, 43974 .....
But the result is:
1, 1, 1, .........
What did I miss?
i solved this problem.
foo needs [out] instad of [in] so Enclave1.edl should
enclave { from "sgx_tstdc.edl" import *;
trusted {
/* define ECALLs here. */
public void foo([out, size = 4]int *ptr);
};
untrusted {
/* define OCALLs here. */
};
};
project1.signed.dll file is not updated on debug folder. so i try rebuild project and it updated. I'm realized this file is enclave field itself
IF state grammar is wrong. it should be if (*ptr == 1) *ptr = 43971;
I am using the GLFW and only want to open a empty windows.
I downloaded the GLFW for Windows 32.
Created an empty console project and wrote this code:
#include "main.h"
#pragma comment (lib, "glfw3dll")
#pragma comment (lib, "OpenGL32")
#define GLFW_DLL
#include <glfw3.h>
#include <chrono>
#include <iostream>
using namespace std::chrono;
GLFWwindow* window;
bool running = true;
bool initialise(){
return true;
}
void update(double deltaTime){
}
void render(){
}
int main(int argc, char **argv) {
if (!glfwInit)
return -1;
window = (glfwCreateWindow(800, 600, "Hello World", nullptr, nullptr));
if (window == nullptr){
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!initialise()){
glfwTerminate();
return -1;
}
auto currentTimeStamp = system_clock::now();
auto prevTimeStamp = system_clock::now();
while (running)
{
currentTimeStamp = system_clock::now();
auto elapsed = duration_cast<milliseconds>(currentTimeStamp - prevTimeStamp);
auto seconds = double(elapsed.count()) / 1000.0;
update(seconds);
render();
glfwPollEvents();
prevTimeStamp = currentTimeStamp;
}
glfwTerminate();
return -1;
}
And I think I added the library and the header correctly.
But everytime the programm exits with -1 after the glfwCreateWindow(..) function, because this functions return null.
Can somebody help me?
if (!glfwInit)
return -1;
I'm not sure why glfwInit would be NULL unless something truly terrible happened during DLL load.
Try calling glfwInit() instead:
if( !glfwInit() )
return -1;
After performing the command "insmod demo_device" the modules listed in /proc/modules
**demo_device 2528 0 - Live 0xe02da000**
fp_indicators 5072 1 - Live 0xe02d2000 (P)
screader 22672 1 - Live 0xe02c5000 (P)
icamdescrambler 12912 0 - Live 0xe02b2000 (P)
icamemmfilter 16208 0 - Live 0xe02a4000 (P)
icamecmfilter 14992 0 - Live 0xe0294000 (P)
but "(P)" is not avail after that.
After firing the command cat /proc/devices the device "demo_device" is not listed there.
So my question is that: what (P) stands in (cat /proc/modules) and what could be the reason that the device is not listed in (cat /proc/devices).
Thanks in Advance !!
The source code is as:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include "query_ioctl.h"
#define FIRST_MINOR 0
#define MINOR_CNT 1
static dev_t dev;
static struct cdev c_dev;
static struct class *cl;
static int status = 1, dignity = 3, ego = 5;
static int my_open(struct inode *i, struct file *f)
{
return 0;
}
static int my_close(struct inode *i, struct file *f)
{
return 0;
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
static int my_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
#else
static long my_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
#endif
{
query_arg_t q;
switch (cmd)
{
case QUERY_GET_VARIABLES:
q.status = status;
q.dignity = dignity;
q.ego = ego;
if (copy_to_user((query_arg_t *)arg, &q, sizeof(query_arg_t)))
{
return -EACCES;
}
break;
case QUERY_CLR_VARIABLES:
status = 0;
dignity = 0;
ego = 0;
break;
case QUERY_SET_VARIABLES:
if (copy_from_user(&q, (query_arg_t *)arg, sizeof(query_arg_t)))
{
return -EACCES;
}
status = q.status;
dignity = q.dignity;
ego = q.ego;
break;
default:
return -EINVAL;
}
return 0;
}
static struct file_operations query_fops =
{
.owner = THIS_MODULE,
.open = my_open,
.release = my_close,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
.ioctl = my_ioctl
#else
.unlocked_ioctl = my_ioctl
#endif
};
static int __init query_ioctl_init(void)
{
int ret;
struct device *dev_ret;
printk("Before calling alloc\n");
dev=150;
if ((ret = register_chrdev_region(dev, MINOR_CNT, "demo_device")))
{
return ret;
}
else if((ret = alloc_chrdev_region(&dev,0,MINOR_CNT,"demo_device")))
{
return ret;
}
printk("After alloc %d %d\n",ret,dev);
cdev_init(&c_dev, &query_fops);
if ((ret = cdev_add(&c_dev, dev, MINOR_CNT)) < 0)
{
return ret;
}
printk("After cdev_add\n");
if (IS_ERR(cl = class_create(THIS_MODULE, "char")))
{
cdev_del(&c_dev);
unregister_chrdev_region(dev, MINOR_CNT);
return PTR_ERR(cl);
}
printk("After class_create\n");
if (IS_ERR(dev_ret = device_create(cl, NULL, dev, NULL, "demo")))
{
class_destroy(cl);
cdev_del(&c_dev);
unregister_chrdev_region(dev, MINOR_CNT);
return PTR_ERR(dev_ret);
}
printk("After device_create\n");
return 0;
}
static void __exit query_ioctl_exit(void)
{
device_destroy(cl, dev);
class_destroy(cl);
cdev_del(&c_dev);
unregister_chrdev_region(dev, MINOR_CNT);
}
module_init(query_ioctl_init);
module_exit(query_ioctl_exit);
MODULE_LICENSE("GPL");
And after inserting the module I am able to see these messages:
$insmod demo_device.ko
Before calling alloc
After alloc 0 217055232
After cdev_add
After class_create
After device_create
$
Make sure that Major Number of the device is not preoccupied by some other device file. use the following command to check the occupied Major Numbers
cat /proc/devices
Use the following code to capture initialization error in init function
int t=register_chrdev(majorNumber,"mydev",&fops);
if(t<0)
printk(KERN_ALERT "device registration failed.");
Use dmesg to look into kernel logs
Look at module_flags_taint() in kernel/module.c.
The 'P' flag merely indicated the other modules are proprietary. The reason your device doesn't show up in /proc/devices is probably because something is wrong with the initialisation, but we can't help you with that unless you show us code.
After perfroming make clean to the linux/application source code and rebuilding it again...make it works. Now after inserting the module the corresponding entry is visibe in the /proc/devcies file :)