I'm very new to win32/DirectX but I'm managing fine with it. I have a really quick question that I don't really understand and it'd be great if someone could clear it up for me. So all the event handlers are calling functions so the DirectX code can can execute stuff when they get executed (like OnMouseDown, OnMouseMove etc).
An example of what I mean is:
case WM_RBUTTONDOWN:
OnMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
return 0;
case WM_RBUTTONUP:
OnMouseUp(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
return 0;
So I wanted to do stuff in my DX game when the mouse wheel is scrolled. I searched all over the app for every instance of these functions and copied them to create my own called "OnMouseWheel", but whenever I call this function I get the following error:
Unhandled exception at 0x534D5821 in Init Direct3D.exe: 0xC0000005: Access violation executing location 0x534D5821.
Whereas if I replace it with one of the other OnMouse functions it works fine, why is this and what do I have to do to fix it?
Right now I have something like this (i've also added my function to the win32 app header and the directX app file):
case WM_MOUSEWHEEL:
OnMouseWheel(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
return 0;
Also I realize that the parameters I've added are probaly not needed for the wheel, I was just copying the other ones, but even if I have a empty function I get the same error.
Header definition:
virtual void OnMouseDown(WPARAM btnState, int x, int y){ }
virtual void OnMouseUp(WPARAM btnState, int x, int y) { }
virtual void OnMouseMove(WPARAM btnState, int x, int y){ }
virtual void OnMouseWheel(WPARAM btnState, int x, int y){ }
virtual void KeyInputTest(){}
Related
If I create a File handle using CreateFile for a path like "\\?\NUL" or "\\?\pipe\", the handle is mapped to a File object that's opened for the "\Device\Null" or "\Device\NamedPipe" kernel Device object. Since the GetFinalPathNameByHandle function supports the VOLUME_NAME_NT property, which already returns strings like "\Device\HarddiskVolume1\", I thought I would be able to obtain a similar path for a device handle. However, the call always fails, either with ERROR_INVALID_FUNCTION, or ERROR_INVALID_PARAMETER, depending on the access flags the file was opened with.
In fact, almost any call to similar functions fails -- like GetFileInformationByHandle, GetFileInformationByHandleEx, and even calls to NT functions like NtQueryInformationFile -- returning STATUS_INVALID_PARAMETER. The only functions that don't fail are GetFileType (able to identify a pipe), GetVolumeInformationByHandle (able to identify the driver), and NtQueryInformationFile with FileModeInformation.
All these functions work when used on any standard file, but they are not supported for device file handles. How can I obtain path information from a device handle? Are there some Nt or Io functions that would work? Is there some other way to identify a device if the only thing I have is the handle?
As RbMm and eryksun have pointed out, the driver which implements the object must be able to handle IRP_MJ_QUERY_INFORMATION, but if it doesn't, the name of the object can be obtained via NtQueryObject, passing ObjectNameInformation (1) to it, which will obtain the OBJECT_NAME_INFORMATION structure with the object name.
Since I intended to call it with C#, here is the P/Invoke code for it:
static class Ntdll
{
[DllImport("ntdll.dll")]
static extern int NtQueryObject(
IntPtr Handle, int ObjectInformationClass,
IntPtr ObjectInformation, int ObjectInformationLength,
out int ReturnLength
);
public static int NtQueryObject(IntPtr Handle, int ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength)
{
int length;
int status = NtQueryObject(Handle, ObjectInformationClass, ObjectInformation, ObjectInformationLength, out length);
if(status != 0) throw new Win32Exception(RtlNtStatusToDosError(status));
return length;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct OBJECT_NAME_INFORMATION
{
public ushort Length;
public ushort MaximumLength;
public string Buffer;
}
[DebuggerStepThrough]
public static void NtQueryObject(IntPtr Handle, out OBJECT_NAME_INFORMATION ObjectNameInformation)
{
IntPtr buffer = Marshal.AllocHGlobal(1024);
try{
Ntdll.NtQueryObject(Handle, 1, buffer, 1024);
ObjectNameInformation = Marshal.PtrToStructure<Ntdll.OBJECT_NAME_INFORMATION>(buffer);
}finally{
Marshal.FreeHGlobal(buffer);
}
}
}
The path can be then constructed by prepending "\\?\GlobalRoot" to the Buffer member.
I'm implementing flow control in a custom protocol in the linux kernel. When I receive an ACK, I want to remove the acked packets from the write queue. Here's some code
for(i = (ack->sequence - qp->first_unack); i>0&&sk->sk_write_queue.qlen>0; i++){
skb_del = skb_dequeue(&sk->sk_write_queue);
qp->first_unack++;
kfree_skb(skb_del);
}
I get a kernel freeze from this code. Everything works well however, when I comment out the kfree(skb_del). Any ideas why is this happening? How else can I free up the memory?
As the skbs are queued to the socket you can use already provided socket APIs;
sk_eat_skb(struct sock *sk, struct sk_buff *skb, bool copied_early) // copied_ealy = 0
For more details you can track tcp_recvmsg, there properly you will get the impementation flow
Moreove why you are using custom APIS from the queuing/dequeuing loop on your own. Just go through the include/net/sock.h I hope you will get necessary details
This is probably because of double freeing skb_del.
Theoretically, before calling kfree_skb(skb_del) you can check the value of skb_del->users by doing refcount_read(&skb_del->users), and if skb_del->users is 0, then it means that skb_del has already been freed.
In practice, the kfree_skb() function doesn't set skb_del->users to 0 when skb_del is finally released (due to some optimization considerations), so after skb_del will be release it would stay 1, and you won't be able to know if skb_del has been released or not.
If you are still curious if this is a double-free issue and you are fine with making some changes in the skbuff infrastructure (just for this investigation) then we need to modify some skbuff functions.
WARNING: It's very easy to cause the kernel to crash when playing with this function, so be careful. But these modification works (in this way I've found a double-free of skb). Keep in mind that this is a suggestion only for investigating the double-free issue, and I've no idea if these modifications will effect your system in the long-run.
We'll modify the following functions (based on kernel v5.9.1):
skb_unref() // from include/linux/skbuff.h
__kfree_skb() // from net/core/skbuff.c
kfree_skb() // from net/core/skbuff.c
consume_skb() // from net/core/skbuff.c
Original skb_unref()
static inline bool skb_unref(struct sk_buff *skb)
{
if (unlikely(!skb))
return false;
if (likely(refcount_read(&skb->users) == 1))
smp_rmb();
else if (likely(!refcount_dec_and_test(&skb->users)))
return false;
return true;
}
Modified skb_unref()
static inline bool skb_unref(struct sk_buff *skb)
{
if (unlikely(!skb))
return false;
if (likely(refcount_read(&skb->users) == 1)) {
smp_rmb();
refcount_set(&skb->users, 0);
} else if (likely(!refcount_dec_and_test(&skb->users))) {
return false;
}
return true;
}
Original __kfree_skb()
void __kfree_skb(struct sk_buff *skb)
{
skb_release_all(skb);
kfree_skbmem(skb);
}
Modified __kfree_skb()
void __kfree_skb(struct sk_buff *skb)
{
if (!skb_unref(skb))
return;
skb_release_all(skb);
kfree_skbmem(skb);
}
Original kfree_skb()
void kfree_skb(struct sk_buff *skb)
{
if (!skb_unref(skb))
return;
trace_kfree_skb(skb, __builtin_return_address(0));
__kfree_skb(skb);
}
Modified kfree_skb()
void kfree_skb(struct sk_buff *skb)
{
//if (!skb_unref(skb))
// return;
trace_kfree_skb(skb, __builtin_return_address(0));
__kfree_skb(skb);
}
Original consume_skb()
void consume_skb(struct sk_buff *skb)
{
if (!skb_unref(skb))
return;
trace_consume_skb(skb);
__kfree_skb(skb);
}
Modified consume_skb()
void consume_skb(struct sk_buff *skb)
{
//if (!skb_unref(skb))
// return;
trace_consume_skb(skb);
__kfree_skb(skb);
}
Good luck in the investigation.
May god will be with you.
In my program, I have a bunch of objects of a custom class Position. The declaration of Position is as follows:
class Position {
public:
Position(int x, int y);
~Position();
Actor *getActor() { return actor.get(); };
void setActor(Actor *actor) { actor = std::move(actor); };
Actor *clearActor() { return actor.release(); };
int getX() { return x; };
int getY() { return y; };
private:
int x, y;
std::unique_ptr<Actor> actor;
};
I also have a class called Actor. Not every Position will have an Actor, and so the majority of the time the unique_ptr "actor" of a Position object should be empty (I'm using unique_ptrs to automatically clean up any Actor associated with a Position at runtime).
The Position constructor is as follows:
Position::Position(int x, int y)
{
this->x = x;
this->y = y;
actor.reset(nullptr);
}
However, I know that this isn't correctly setting the stored pointer to nullptr because when I try calling actor.get() inside Position::getActor(), I get an error as follows:
First-chance exception at 0x01096486 in ____.exe: 0xC0000005: Access violation reading location 0x00000008.
Is there a way to initialize a member unique_ptr to nullptr? I know I could get around this by adding a variable to the Actor class that defines whether or not the Actor is active, setting the unique_ptr to a new inactive Actor, and ignoring all inactive Actors, but I'd rather avoid this if possible.
Thanks!
Edit: I've added the code where I call getActor:
bool Grid::addActor(Actor *actor, int x, int y)
{
Position *destination = at(x, y);
if (!destination->getActor()) {
destination->setActor(actor);
actor->setPosition(x, y);
actor->setGrid(this);
return true;
}
else {
inactive_actors.emplace_back(actor);
return false;
}
}
Your error is here:
void setActor(Actor *actor) { actor = std::move(actor); };
You're assigning the result of std::move to the parameter actor. You probably meant to reset the member variable actor with the parameter actor:
void setActor(Actor *actor) { this->actor.reset(actor); };
As a side note, you can simply change your constructor to this:
Position::Position(int x, int y)
: x(x), y(y)
{
}
This will initialize the members x and y with the arguments, and default-initialize std::unique_ptr<Actor> actor to null.
You don't need to initialize the std::unique pointer to null. Just leave it as its default empty value in the constructor and only ever reset it to point to a non-null pointer.
I am writing a small GUI application using Haskell's gtk2hs library and am currently working with the multiline text boxes within it. I have a function which I want to run when the user makes changes to the text within the text box, but don't want them to have to click a button to activate it.
Furthermore, because it is a rather intrusive and processing intensive function (It draws graphics, loads files etc.), I would like it to fire not whenever a user makes any change (which could probably be done with the bufferChanged signal in text buffer I'm guessing?) but when they stop for a few seconds in between changes.
Basically I am wondering if there is something in gtk which is analogous to the way range widgets can have their update policy set to continuous or delayed, but for text boxes
I don't know anything of the Haskell bindings but in plain C it is quite easy to implement by leveraging a timeout GSource.
#include <gtk/gtk.h>
static guint source_id = 0;
static gboolean do_stuff(gpointer user_data)
{
g_print("doing stuff...\n");
return FALSE;
}
static void postpone(void)
{
if (source_id > 0)
g_source_remove(source_id);
source_id = g_timeout_add(1000, do_stuff, NULL);
}
int main(int argc, char **argv)
{
GtkWidget *window, *text_view;
GtkTextBuffer *text_buffer;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
text_view = gtk_text_view_new();
gtk_container_add(GTK_CONTAINER(window), text_view);
text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
g_signal_connect(text_buffer, "changed", G_CALLBACK(postpone), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
The issue of quitting the TextView before the timeout has elapsed is still open though.
I wrote a simple code to capture the netdevice notifications and simply print their value out to the messages log file ... here's the code :
#include <linux/notifier.h>
#include <asm/kdebug.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
int my_dev_event_handler (struct notifier_block *self,unsigned long val, void *data)
{
printk (KERN_INFO "my_dev_event: Val=%ld, Interface=%s\n", val,((struct net_device *) data)->name);
return 0;
}
static struct notifier_block my_dev_notifier = {
.notifier_call = my_dev_event_handler,
};
static int __init
my_init (void)
{
printk(KERN_ALERT "***Module Loaded***\n");
register_netdevice_notifier (&my_dev_notifier);
return 0;
}
static void __exit my_end(void)
{
printk(KERN_ALERT "***Module Unloaded***\n");
}
module_init(my_init);
module_exit(my_end);
this code compiles and runs correctly, it prints out the "my_dev_event:..." line every time a device goes up/off ... but sometimes (not always) the entire system freezes when a device goes up\down ... now I have two questions here:
1- why is the system freezing? anything wrong with this code?
2- if there's a better way to notify my kernel module when a device goes connected/disconnected ...
The only problem I see is that my_end doesn't unregister the notifier.
This can cause crashes or freezes after you've unloaded your module. This is because a pointer to your code remains in Linux data structures, but your code is no longer there.
Regarding an alternative way - I think you're using the correct way to get these notifications.