mini filter driver | passing information from pre-operation to post-operation - filter-driver

I'm tracking changed made to file and would like to "remember" and pass some information from the pre-operation callback to the post-operation callback.
What is the best way to do it?
[Edit: The driver should only support Windows 10 everything else is a bonus]

You can simply use the PVOID *CompletionContext in PreOperation to store a pointer to the data you want to pass to the PostOperation.
In the PostOperation just use CompletionContext as it will be the data you pointed it to in the PreOperation.
For example:
PreOp:
MyPreOpData = ExAllocatePoolWithTag(DATA_SIZE);
FltGetFileNameInformation(&NameInfo);
MyPreData->NameInfo = NameInfo;
MyPreData->OtherData = MyDrvGetOtherData(Params);
*CompletionContext = MyPreData;
PostOp:
if (CompletionContext != NULL)
{
PMY_DATA MyPreData = (PMY_DATA)CompletionContext;
// now continue using the data queried in the PreOp
...
// when done free it
ExFreePoolWithTag(MyPreData);
}
See here for more details.
Good luck,
Gabriel

Related

What is a correct way to obtain FOnlineSubsystemSteam instance in c++ code

I'm trying to get steam app id and steam user id in my Unreal Engine 4 project in the following way:
if (SteamAPI_Init())
{
IOnlineSubsystem* ossBase = IOnlineSubsystem::Get();
FOnlineSubsystemSteam* oss = Cast<FOnlineSubsystemSteam*>(ossBase);
if (!oss) {
printText(TEXT("Steam Subsystem is down!"), FColor::Red.WithAlpha(255));
return;
}
auto SteamID = FString(std::to_string(SteamUser()->GetSteamID().ConvertToUint64()).c_str());
auto AppID = FString(std::to_string(oss->GetSteamAppId()).c_str());
But it is not possible to convert IOnlineSubsystem to FOnlineSubsystemSteam. So what is a correct way to obtain the instance of FOnlineSubsystemSteam?
The solution is to use static_cast:
FOnlineSubsystemSteam* oss = static_cast<FOnlineSubsystemSteam*>(ossBase);
This one works. It seems obvious to use UE4 Cast, but in this case it does not work.

ag-Grid set filter and sort model without triggering event

I am updating sort & filter models via api:
this.gridApi.setFilterModel(filterModels);
this.gridApi.setSortModel(sortModels);
The problem with this is I have a server request bound to the change even of both sort & filter so when user changes then the data is updated. This means when I change model on code like restoring a state or resetting the filters it causes multiple requests.
Is there a way to update the filter/sort model without triggering the event?
I see there is a ColumnEventType parameter but couldn't see how it works. Can I specify some variable that I can look for inside my event handlers to get them to ignore calls that are not generated from user?
I am trying to manage URL state so when url query params change my code sets the models in the grids but this ends up causing the page to reload multiple times because the onFilter and onSort events get called when the model is set and there is no way I can conceive to prevent this.
At the time, you are going to have to manage this yourself, ie, just before you call the setModel, somehow flag this in a shared part of your app (maybe a global variable)
Then when you react to these events, check the estate of this, to guess where it came from.
Note that at the moment, we have added source to the column events, but they are not yet for the model events, we are planning to add them though, but we have no ETA
Hope this helps
I had to solve similar issue. I found solution which working for my kind of situation. Maybe this help someone.
for (let j = 0; j < orders.length; j++) {
const sortModelEntry = orders[j];
if (typeof sortModelEntry.property === 'string') {
const column: Column = this.gridColumnApi.getColumn(sortModelEntry.property);
if (column && ! column.getColDef().suppressSorting) {
column.setSort(sortModelEntry.direction.toLowerCase());
column.setSortedAt(j);
}
}
this.gridApi.refreshHeader();
Where orders is array of key-value object where key is name of column and value is sorting directive (asc/desc).
Set filter without refresh was complicated
for (let j = 0; j < filters.length; j++) {
const filterModelEntry = filters[j];
if (typeof filterModelEntry.property === 'string') {
const column: Column = this.gridColumnApi.getColumn(filterModelEntry.property);
if (column && ! column.getColDef().suppressFilter) {
const filter: any = this.gridApi.getFilterApi(filterModelEntry.property);
filter['filter'] = filterModelEntry.command;
filter['defaultFilter'] = filterModelEntry.command;
filter['eTypeSelector'].value = filterModelEntry.command;
filter['filterValue'] = filterModelEntry.value;
filter['filterText'] = filterModelEntry.value;
filter['eFilterTextField'].value = filterModelEntry.value;
column.setFilterActive(true);
}
}
}
Attributes in filter:
property - name of column
command - filter action (contains, equals, ...)
value - value used in filter
For anyone else looking for a solution to this issue in Nov 2020, tapping into onFilterModified() might help. This gets called before onFilterChanged() so setting a value here (eg. hasUserManuallyChangedTheFilters = false, etc.) and checking the same in the filter changed event is a possible workaround. Although, I haven't found anything similar for onSortChanged() event, one that gets called before the sorting is applied to the grid.
I am not sure any clean way to achieve this but I noticed that FilterChangedEvent has "afterFloatingFilter = false" only if filterModel was updated from ui.
my workaround is as below
onFilterChanged = event:FilterChangedEvent) => {
if(event.afterFloatingFilter === undefined) return;
console.log("SaveFilterModel")
}

How to get the current tool SitePage and/or its Properties?

With the ToolManager I can get the the current placement, the context and of course, the Site through the SiteService. But I want to get the current SitePage properties the user is currently accessing.
This doubt can be extended to the current Tool properties with a
little more emphasis considering that once I have the Tool I could not
find any methods covering the its properties.
I could get the tool properties and I'm using it (it is by instance) through Properties got with sitepage.getTool(TOOLID).getConfig(). To save a property, I'm using the ToolConfiguration approach and saving the data after editing with the ToolConfiguration.save() method. Is it the correct approach?
You can do this by getting the current tool session and then working your way backward from that. Here is a method that should do it.
public SitePage findCurrentPage() {
SitePage sp = null;
ToolSession ts = SessionManager.getCurrentToolSession();
if (ts != null) {
ToolConfiguration tool = SiteService.findTool(ts.getPlacementId());
if (tool != null) {
String sitePageId = tool.getPageId();
sp = s.getPage(sitePageId);
}
}
return sp;
}
Alternatively, you could use the current tool to work your way to it but I think this method is harder.
String toolId = toolManager.getCurrentTool().getId();
String context = toolManager.getCurrentPlacement().getContext();
Site s = siteService.getSite( context );
ToolConfiguration tc = s.getTool(toolId);
String sitePageId = tc.getPageId();
SitePage sp = s.getPage(sitePageId);
NOTE: I have not tested this code to make sure it works.

CQ Workflow- Comment not transferring between participant with a process step in between

When there is a process step between two participant steps, the comments is not passing between participants. My Workflow is like this-
ParticipantA ---> Process step X (ecma script) ----> Process step Y (ecma script) -----> ParticipantB
When I add some comment at ParticipantA step it does not carry forward to ParticipantB. Seems OOB functionality has limitations on this.
As a workaround, I am trying to get it at "Process step X" and passing on to Process step Y. I am able to get it but not able to set it for next step.
Below is my code-
log.info("Noop process called for: " + workItem.getWorkflowData().getPayload());
var comment = workItem.getMetaDataMap().get("comment");
log.info("Comment in approval process-----------" + comment);
var workflowData = workItem.getWorkflowData();
if (workflowData.getPayloadType() == "JCR_PATH") {
log.info("setting comment in meta data----------------");
workflowData.getMetaDataMap().put("comment", comment);
}
Can you help on how to set comment for next step?
Thanks in advance.
Regards,
Vivek
You would need to actually store your comment within a workflow Metadata Map. This
should help.
Once you have successfully stored your comment, you can access it later.
Hope this helps
I guess it is a session change within the workflow. The WorkflowData instance will be newly set. You can easily check it in the debugger of your ide. You have to iterate over the HistoryItems as illustrated here:
final List<HistoryItem> history = workflowSession.getHistory(workItem.getWorkflow());
final List<String> comments = new ArrayList<>();
if (history.size() > 0) {
HistoryItem current = history.get(history.size() - 1);
do {
comments.add(current.getComment());
current = current.getPreviousHistoryItem();
} while (current != null);
}
Comments are empty strings, if not set - if i'm not mistaken.

NodeJS: What is the proper way to handling TCP socket streams ? Which delimiter should I use?

From what I understood here, "V8 has a generational garbage collector. Moves objects aound randomly. Node can’t get a pointer to raw string data to write to socket." so I shouldn't store data that comes from a TCP stream in a string, specially if that string becomes bigger than Math.pow(2,16) bytes. (hope I'm right till now..)
What is then the best way to handle all the data that's comming from a TCP socket ? So far I've been trying to use _:_:_ as a delimiter because I think it's somehow unique and won't mess around other things.
A sample of the data that would come would be something_:_:_maybe a large text_:_:_ maybe tons of lines_:_:_more and more data
This is what I tried to do:
net = require('net');
var server = net.createServer(function (socket) {
socket.on('connect',function() {
console.log('someone connected');
buf = new Buffer(Math.pow(2,16)); //new buffer with size 2^16
socket.on('data',function(data) {
if (data.toString().search('_:_:_') === -1) { // If there's no separator in the data that just arrived...
buf.write(data.toString()); // ... write it on the buffer. it's part of another message that will come.
} else { // if there is a separator in the data that arrived
parts = data.toString().split('_:_:_'); // the first part is the end of a previous message, the last part is the start of a message to be completed in the future. Parts between separators are independent messages
if (parts.length == 2) {
msg = buf.toString('utf-8',0,4) + parts[0];
console.log('MSG: '+ msg);
buf = (new Buffer(Math.pow(2,16))).write(parts[1]);
} else {
msg = buf.toString() + parts[0];
for (var i = 1; i <= parts.length -1; i++) {
if (i !== parts.length-1) {
msg = parts[i];
console.log('MSG: '+msg);
} else {
buf.write(parts[i]);
}
}
}
}
});
});
});
server.listen(9999);
Whenever I try to console.log('MSG' + msg), it will print out the whole buffer, so it's useless to see if something worked.
How can I handle this data the proper way ? Would the lazy module work, even if this data is not line oriented ? Is there some other module to handle streams that are not line oriented ?
It has indeed been said that there's extra work going on because Node has to take that buffer and then push it into v8/cast it to a string. However, doing a toString() on the buffer isn't any better. There's no good solution to this right now, as far as I know, especially if your end goal is to get a string and fool around with it. Its one of the things Ryan mentioned # nodeconf as an area where work needs to be done.
As for delimiter, you can choose whatever you want. A lot of binary protocols choose to include a fixed header, such that you can put things in a normal structure, which a lot of times includes a length. In this way, you slice apart a known header and get information about the rest of the data without having to iterate over the entire buffer. With a scheme like that, one can use a tool like:
node-buffer - https://github.com/substack/node-binary
node-ctype - https://github.com/rmustacc/node-ctype
As an aside, buffers can be accessed via array syntax, and they can also be sliced apart with .slice().
Lastly, check here: https://github.com/joyent/node/wiki/modules -- find a module that parses a simple tcp protocol and seems to do it well, and read some code.
You should use the new stream2 api. http://nodejs.org/api/stream.html
Here are some very useful examples: https://github.com/substack/stream-handbook
https://github.com/lvgithub/stick