FltGetStreamHandleContext And FltSetStreamHandleContext Function - api

Is the structure of the third parameter of FltGetStreamHandleContext a user-defined structure? And before you get the Context via FltGetStreamHandleContext, do you have to predefine the Context through the FltSetStreamHandleContext function? Sorry for the inconvenience of using the translator.

yes, to what is point PFLT_CONTEXT is user-defined structure - so you yourself design it content. you need allocate it by call FltAllocateContext. really this function allocate more then ContextSize parameter for hold reference count on allocated context (initially it equal 1) and FSRTL_PER_STREAM_CONTEXT because FltSetStream[Handle]Context shell over FsRtlInsertPerStreamContext or FsRtlInsertPerFileObjectContext (read more Tracking Per-Stream Context in a Legacy File System Filter Driver)
if you not call FltSetStream[Handle]Context before FltGetStream[Handle]Context - you got NULL_CONTEXT (or simply 0) (more exactly FltGetStream[Handle]Context return error STATUS_NOT_FOUND)
so again context is your defined structure in mini-filter drivers (in legacy you need inherit context from FSRTL_PER_STREAM_CONTEXT but minifiletrs encapsulate this)
usually we use next code;
MY_STREAM_CONTEXT* Ctx;// your custom data
if (0 <= FltGetStreamHandleContext(FltObjects->Instance, FltObjects->FileObject, (PFLT_CONTEXT*)&Ctx))
{
//.. use Ctx
FltReleaseContext(Ctx);
}

Related

Modify Scilab/Xcos Block in Scilab 6 Gateway Function

I would like to modify an Xcos block from within a gateway function using the new (non-legacy) Scilab API, for example, replace the block's model property by a new model structure. In other words, do the same as the Scilab command(s):
m = scicos_model()
block.model = m
However, I did not manage to achieve this behavior with the functions from Scilab 6 API: a block created by standard_define() is correctly passed to my gateway function, where this argument is available as scilabVar of type 128. On the other hand, the Scilab help claims that a block is a "scilab tlist of type "Block" with fields : graphics, model, gui and doc".
Attempts
Assume scilabVar block taken from gateway function argument, string constants of type wchar_t[], scilabVar model holding the result of scicos_model():
Application of function scilab_setTListField (env, block, "model", model) returns error status (as its equivalents for MList and List do)
Knowing that property .model is at index 3, a setfield (3, model, block) called through scilab_call ("setfield", ...) also fails.
This is not surprising: when called directly from the Scilab command line, it ends up with
setfield: Wrong type for input argument #3: List expected. .
However, a getfield (3, block) works, so that at least read access to the block's data fields is possible.
An external helper function
function block = blockSetModel (block, model)
block.model = model
endfunction
also called through scilab_call("blockSetModel", ...) actually returns a block with changed model,
but the original block passed to this function remains unchanged.
Although ugly, this gives at least a way to construct an individual block structure
which needs to be returned as a copy.
Summary
So, is there simply a function missing in the API, which returns the TList (or whatever) behind a type 128 pointer variable?
Or is there any other approach to this problem I was unable to discover?
Background
The goal behind is to move the block definition task from the usual interfacing "gui" function (e.g. a Scilab script MyBlock.sci) into own C code. For this purpose, the interfacing function is reduced to a wrapper around a C gateway, which, for example, usesscilab_call ("standard_define",...) to create a new block when being called with parameter job=="define".
Modification of the contained model and graphics objects through the Scilab API works fine since these are standard list types. However, getting or setting these objects as attributes .model and .graphics of the
original block fails as described above.
Starting from Scilab/Xcos 6.0.0, the data-structure behind a block is no more an MList (or TList) so you cannot upgrade the model to your own MList. All the data behind are stored using a classical MVC within a C++ coded Block.hxx.
On each try you made, a serialization/deserialization happens to reconstruct the block model field as a Scilab value.
Could you describe what kind of field you want to append/edit regarding the block structure ? Some of the predefined fields might be enough to pass extra information.

Will code written in this style be optimized out by RVO in C++11?

I grew up in the days when passing around structures was bad mojo because they are often large, so pointers were always the way to go. Now that C++11 has quite good RVO (right value optimization), I'm wondering if code like the following will be efficient.
As you can see, my class has a bunch of vector structures (not pointers to them). The constructor accepts value structures and stores them away.
My -hope- is that the compiler will use move semantics so that there really is no copying of data going on; the constructor will (when possible) just assume ownership of the values passed in.
Does anyone know if this is true, and happens automagically, or do I need a move constructor with the && syntax and so on?
// ParticleVertex
//
// Class that represents the particle vertices
class ParticleVertex : public Vertex
{
public:
D3DXVECTOR4 _vertexPosition;
D3DXVECTOR2 _vertexTextureCoordinate;
D3DXVECTOR3 _vertexDirection;
D3DXVECTOR3 _vertexColorMultipler;
ParticleVertex(D3DXVECTOR4 vertexPosition,
D3DXVECTOR2 vertexTextureCoordinate,
D3DXVECTOR3 vertexDirection,
D3DXVECTOR3 vertexColorMultipler)
{
_vertexPosition = vertexPosition;
_vertexTextureCoordinate = vertexTextureCoordinate;
_vertexDirection = vertexDirection;
_vertexColorMultipler = vertexColorMultipler;
}
virtual const D3DVERTEXELEMENT9 * GetVertexDeclaration() const
{
return particleVertexDeclarations;
}
};
Yes, indeed you should trust the compiler to optimally "move" the structures:
Want Speed? Pass By Value
Guideline: Don’t copy your function arguments. Instead, pass them by value and let the compiler do the copying
In this case, you'd move the arguments into the constructor call:
ParticleVertex myPV(std::move(pos),
std::move(textureCoordinate),
std::move(direction),
std::move(colorMultipler));
In many contexts, the std::move will be implicit, e.g.
D3DXVECTOR4 getFooPosition() {
D3DXVECTOR4 result;
// bla
return result; // NRVO, std::move only required with MSVC
}
ParticleVertex myPV(getFooPosition(), // implicit rvalue-reference moved
RVO means Return Value Optimization not Right value optimization.
RVO is a optimization performed by the compiler when the return of a function is by value, and its clear that the code returns a temporary object created in the body, so the copy can be avoided. The function returns the created object directly.
What C++11 introduces is Move Semantics. Move semantics allows us to "move" the resource from a certain temporary to a target object.
But, move implies that the object wich the resource comes from, is in a unusable state after the move. This is not the case (I think) you want in your class, because the vertex data is used by the class, even if the user calls to this function or not.
So, use the common return by const reference to avoid copies.
On the other hand,, DirectX provides handles to the resources (Pointers), not the real resource. Pointers are basic types,its copying is cheap, so don't worry about performance. In your case, you are using 2d/3d vectors. Its copying is cheap too.
Personally, I think that returning a pointer to an internal resource is a very bad idea, always. I think that in this case the best aproach is to return by const reference.

MATLAB and the use of global variables?

I am writing a tool for dicom images and spectroscopy and there is a lot of shared data I want to use between the functions I am making. I have GUI that I made and the different sliders and buttons use a lot of this shared data from the dicom files.
I have been using global variables to store information that all of these functions share. I have a lot of globals currently. I have been taught to avoid global variables if possible because of increasing coupling. Would it be better to read in the data from the dicom file in each function? This seems redundant. Would using MATLAB as object-oriented help?
I would recommend using application data structures.
Application data is essential data stored as a structure that is defined by your application and is typically attached to a GUI application or figure window.
To use application data (appdata) use the setappdata and getappdata functions. For example, assuming that you have a handle to your GUI stored as hGUI, the following adds a random matrix to your application data and then retrieves it later (lifted from MATLAB documentation)
% Save matrix for later
matrix = randn(35);
setappdata(hGUI, 'mydata', matrix);
% Do some stuff...
% Retrieve my matrix, this could be in a different file to `setappdata`
myMatrix = getappdata(hGUI, 'mydata');
You can store essentially arbitrary data in your application data, and you can store it and get it from any of your source files, as long as hGUI refers to your GUI application.
Since you mention you are working with a GUI and wanting to share data between the control callbacks, I would suggest designing your code using nested functions. The overall code would look something like this:
function dicomGUI
%# Initialize your GUI here, linking the control callbacks to the
%# nested functions below:
hLoad = uicontrol('Style', 'push', 'String', 'Load file', ...
'Callback', #load_file);
...
%# Initialize the data variables for the DICOM files here:
data = []; %# Shared among nested functions
...
%# Below are all the nested functions your controls will use:
function load_file(hSource, event)
data = ...; %# Load the data here
end
...
end
Not only does this let you put all your GUI code in one m-file, but it simplifies the control callbacks and makes it easy for them to share variables in the workspace of the parent function dicomGUI. An example of this approach, along with other suggestions for sharing data between GUI controls, can be found on this documentation page: Share Data Among a GUI's Callbacks.
As Chris mentions, this could become a very large m-file for a large and intricate GUI. To keep the file size down in such a case I would suggest making the body of each callback simply a call to a function in a separate file which accepts the shared data variables, performs whatever work is necessary, then returns the modified data to the same shared variables. For example:
function transform_callback(hSource, event)
%# Apply some transform to the data:
data = transform_data(data);
%# If the above changes the GUI (disabling controls, changing a
%# display, etc.), then those changes should be made here.
end
Globals as a rule are a bad thing. There are a couple of better ways typically, which include:
Reading in the data initially, and passing it to each function which needs it.
Reading it the data, and each function which needs it calls a function which returns it.
You might need to update the data package upon return somehow as well, depending on if you only use the data or if you change the data as well as using it.
Either one of these ideas should help your process. It makes your code much more readable, and less likely to make some kind of a mistake.
There is another possibility due to the object-oriented nature of MATLAB. You can define your own handle class and pass it in the initialization phase to each callback as an additional argument:
classdef Data<handle
properties (Access=public)
Val;
end
end
function SimpleGui
data = Data();
hLoad = uicontrol('Style', 'push', 'String', 'Push me', ...
'Callback', {#callback data});
data.Val = 5;
end
function callback(hSource, event, data)
data.Val = data.Val+1;
disp(data.Val);
end
Yet another option:
Also, regarding the guidata/appdata (as described by #Chris), it can be improved in the following way:
Create an encapsulating callback that always gets and sets guidata:
function CallbackWrapper(hObj,evt,func)
data = guidata(hObj);
data = func(hObj,evt,data);
guidata(hObj,data);
end
Now your callbacks should be defined in the following way (note the different signature):
function SimpleGui
hSave = uicontrol('Style', 'push', 'String', 'Push me', ...
'Callback', {#CallbackWrapper #myCallBack});
data.x = 1;
guidata(hSave,data);
end
function data = myCallBack(hObj,evt,data)
data.x = data.x + 1;
disp(data.x);
end
If you are using one of the later releases of MATLAB, you should take advantage of the OOPS (object oriented programming system).
You should adhere to software design principles and start by architecting a sound software design. You should do this before writing any code. I recommend using UML for software modeling.

std::unique_ptr and pointer-to-pointer

I've been using std::unique_ptr to store some COM resources, and provided a custom deleter function. However, many of the COM functions want pointer-to-pointer. Right now, I'm using the implementation detail of _Myptr, in my compiler. Is it going to break unique_ptr to be accessing this data member directly, or should I store a gajillion temporary pointers to construct unique_ptr rvalues from?
COM objects are reference-countable by their nature, so you shouldn't use anything except reference-counting smart pointers like ATL::CComPtr or _com_ptr_t even if it seems inappropriate for your usecase (I fully understand your concerns, I just think you assign too much weight to them). Both classes are designed to be used in all valid scenarios that arise when COM objects are used, including obtaining the pointer-to-pointer. Yes, that's a bit too much functionality, but if you don't expect any specific negative consequences you can't tolerate you should just use those classes - they are designed exactly for this purpose.
I've had to tackle the same problem not too long ago, and I came up with two different solutions:
The first was a simple wrapper that encapsulated a 'writeable' pointer and could be std::moved into my smart pointer. This is just a little more convenient that using the temp pointers you are mentioning, since you cannot define the type directly at the call-site.
Therefore, I didn't stick with that. So what I did was a Retrieve helper-function that would get the COM function and return my smart-pointer (and do all the temporary pointer stuff internally). Now this trivially works with free-functions that only have a single T** parameter. If you want to use this on something more complex, you can just pass in the call via std::bind and only leave the pointer-to-be-returned free.
I know that this is not directly what you're asking, but I think it's a neat solution to the problem you're having.
As a side note, I'd prefer boost's intrusive_ptr instead of std::unique_ptr, but that's a matter of taste, as always.
Edit: Here's some sample code that's transferred from my version using boost::intrusive_ptr (so it might not work out-of-the box with unique_ptr)
template <class T, class PtrType, class PtrDel>
HRESULT retrieve(T func, std::unique_ptr<PtrType, PtrDel>& ptr)
{
ElementType* raw_ptr=nullptr;
HRESULT result = func(&raw_ptr);
ptr.reset(raw_ptr);
return result;
}
For example, it can be used like this:
std::unique_ptr<IFileDialog, ComDeleter> FileDialog;
/*...*/
using std::bind;
using namespace std::placeholders;
std::unique_ptr<IShellItem, ComDeleter> ShellItem;
HRESULT status = retrieve(bind(&IFileDialog::GetResult, FileDialog, _1), ShellItem);
For bonus points, you can even let retrieve return the unique_ptr instead of taking it by reference. The functor that bind generates should have signature typedefs to derive the pointer type. You can then throw an exception if you get a bad HRESULT.
C++0x smart pointers have a portable way to get at the raw pointer container .get() or release it entirely with .release(). You could also always use &(*ptr) but that is less idiomatic.
If you want to use smart pointers to manage the lifetime of an object, but still need raw pointers to use a library which doesn't support smart pointers (including standard c library) you can use those functions to most conveniently get at the raw pointers.
Remember, you still need to keep the smart pointer around for the duration you want the object to live (so be aware of its lifetime).
Something like:
call_com_function( &my_uniq_ptr.get() ); // will work fine
return &my_localscope_uniq_ptr.get(); // will not
return &my_member_uniq_ptr.get(); // might, if *this will be around for the duration, etc..
Note: this is just a general answer to your question. How to best use COM is a separate issue and sharptooth may very well be correct.
Use a helper function like this.
template< class T >
T*& getPointerRef ( std::unique_ptr<T> & ptr )
{
struct Twin : public std::unique_ptr<T>::_Mybase {};
Twin * twin = (Twin*)( &ptr );
return twin->_Myptr;
}
check the implementation
int wmain ( int argc, wchar_t argv[] )
{
std::unique_ptr<char> charPtr ( new char[25] );
delete getPointerRef(charPtr);
getPointerRef(charPtr) = 0;
return charPtr.get() != 0;
}

Lambdas with captured variables

Consider the following line of code:
private void DoThis() {
int i = 5;
var repo = new ReportsRepository<RptCriteriaHint>();
// This does NOT work
var query1 = repo.Find(x => x.CriteriaTypeID == i).ToList<RptCriteriaHint>();
// This DOES work
var query1 = repo.Find(x => x.CriteriaTypeID == 5).ToList<RptCriteriaHint>();
}
So when I hardwire an actual number into the lambda function, it works fine. When I use a captured variable into the expression it comes back with the following error:
No mapping exists from object type
ReportBuilder.Reporter+<>c__DisplayClass0
to a known managed provider native
type.
Why? How can I fix it?
Technically, the correct way to fix this is for the framework that is accepting the expression tree from your lambda to evaluate the i reference; in other words, it's a LINQ framework limitation for some specific framework. What it is currently trying to do is interpret the i as a member access on some type known to it (the provider) from the database. Because of the way lambda variable capture works, the i local variable is actually a field on a hidden class, the one with the funny name, that the provider doesn't recognize.
So, it's a framework problem.
If you really must get by, you could construct the expression manually, like this:
ParameterExpression x = Expression.Parameter(typeof(RptCriteriaHint), "x");
var query = repo.Find(
Expression.Lambda<Func<RptCriteriaHint,bool>>(
Expression.Equal(
Expression.MakeMemberAccess(
x,
typeof(RptCriteriaHint).GetProperty("CriteriaTypeID")),
Expression.Constant(i)),
x)).ToList();
... but that's just masochism.
Your comment on this entry prompts me to explain further.
Lambdas are convertible into one of two types: a delegate with the correct signature, or an Expression<TDelegate> of the correct signature. LINQ to external databases (as opposed to any kind of in-memory query) works using the second kind of conversion.
The compiler converts lambda expressions into expression trees, roughly speaking, by:
The syntax tree is parsed by the compiler - this happens for all code.
The syntax tree is rewritten after taking into account variable capture. Capturing variables is just like in a normal delegate or lambda - so display classes get created, and captured locals get moved into them (this is the same behaviour as variable capture in C# 2.0 anonymous delegates).
The new syntax tree is converted into a series of calls to the Expression class so that, at runtime, an object tree is created that faithfully represents the parsed text.
LINQ to external data sources is supposed to take this expression tree and interpret it for its semantic content, and interpret symbolic expressions inside the tree as either referring to things specific to its context (e.g. columns in the DB), or immediate values to convert. Usually, System.Reflection is used to look for framework-specific attributes to guide this conversion.
However, it looks like SubSonic is not properly treating symbolic references that it cannot find domain-specific correspondences for; rather than evaluating the symbolic references, it's just punting. Thus, it's a SubSonic problem.