What is the use of passing additional data in CreateWindowEx - windows

In Windows API docs, it mentions that you can pass additional data like State Information to CreateWindowEx() function as its last parameter which can be accessed during WM_CREATE/WM_NCCREATE events. Then, you can store the state info inside the window itself using SetWindowLongPtr() function.
But what would be the point of doing this if we can directly set data using SetWindowLongPtr() immediately after Window initialization (inside wWinmain())?

Passing user data through the lpParam parameter of CreateWindow/Ex() allows that data to be accessible to your window procedure while CreateWindow/Ex() is still running. There are several messages sent to the window by CreateWindow/Ex() itself, including WM_(NC)CREATE. When WM_(NC)CREATE is received, your data is accessible via the CREATESTRUCT pointed at by the lParam, and so you can then assign that data to the window via SetWindowLongPtr() (or SetProp()) for subsequent messages to access via GetWindowLongPtr() (or GetProp()).
If you wait until after CreateWindow/Ex() has exited before you then call SetWindowLongPtr(), those initial messages won't have a chance to access your data, unless you store it in a global or thread-local variable that the window procedure can access.
Whether or not that is acceptable to you depends on your particular situation.

Related

Is it safe to use a process handle which belongs to a terminated process

I am developing a Windows console application in C++. I need my program to do some operations on another process which I don't have any control over.
But, I have some doubts about a case where the target process might get terminated for some reason (by Task Manager, etc). Is it safe to use a handle to a process which is already terminated?
Note : I stop my operations if one of the functions fails.
HANDLE hProcess = OpenProcess(pid);
if( hProcess != NULL )
{
// Lets suppose process is terminated here
/* Some operations on process using returned handle*/
}
Kernel objects in Windows are reference-counted, with references being represented as handles to objects. Client code can create kernel objects and receive an initial reference (e.g. CreateProcess), increment the reference count on an existing object (e.g. OpenProcess, or DuplicateHandle), and decrement the reference count (CloseHandle). As long as you hold on to a HANDLE, the object referenced by that HANDLE is kept alive.
In case of a process object, that object is valid at least as long as you hold a reference (HANDLE) to it. The fact that a process has been terminated is observable, but doesn't otherwise invalidate or destroy the process object if there are any outstanding references to it.
Specifically this means that you can perform any operations you'd do with a "live" process (one for which the OS is still scheduling threads to execute), such as WaitForSingleObject. In addition you can call GetExitCodeProcess and that call won't return STILL_ACTIVE.
Barring a call to CloseHandle, you are now a stakeholder that has a say in the demise of the process object. It won't go away unless you sign it off. A corollary of this is that you now also control the validity of the PID. It's tied to the process' lifetime, and as long as you hold a reference to it by way of a HANDLE, that PID won't get reused for another process.
In summary, as long as you hold on to a (process) HANDLE you can do whatever.

How DriverKit driver notify application?

I know how to send data to DriverKit and get back some values, that is application calling IOConnectCallStructMethod() and driver fill the OSData in structureOutput from application.
In my Application it is using IOConnectCallAsyncScalarMethod() and the kext using sendAsyncResult64() to let the app know events coming in. However the method sendAsyncResult64() is not available in DriverKit.
I saw AsyncCompletion looks like solution but no idea to implement it. Anyone know how to do?
Appreciate if any suggestion!
IOUserClient::AsyncCompletion is indeed the replacement for sendAsyncResult64().
To call it successfully, you need to retain the OSAction object supplied in the completion field of the IOUserClientMethodArguments supplied in your ExternalMethod dispatch function. Then, when you are ready to send an asynchronous result, call
userclient->AsyncCompletion(saved_osaction, result, async_arguments, num_async_arguments);
Don't forget to release the OSAction object once you no longer need it. The array of async arguments will be passed to the handler function in the user space application, same as with a kext calling sendAsyncResult64().
Note that you can't asynchronously fill "small" structureOutput fields (4096 bytes or less) as these must be returned in the ExternalMethod handler. Only if the buffer is large enough to be passed via structureOutputDescriptor can you retain that descriptor and fill it with data after the initial ExternalMethod returns. This is no different than for kexts, however.

How to obtain data directly from PFFile without warning

I am using PFFile to store images. If the image is already downloaded, I want to access it directly. If not, I want to use the background methods. However, if I use getData, I get the following warning:
Warning: A long-running operation is being executed on the main thread.
Break on warnBlockingOperationOnMainThread() to debug.
Since I know that the data is available, this warning is unnecessary and clutters my log. Is there any way to access PFFile's data without triggering a warning?
You are getting the warning because the data is not available locally and getData is a synchronous call to fetch the data from the server. When getData is called, it blocks the main thread - the UI - and stops all app interaction until the data downloads, which is why you are getting the error. Generally, blocking the UI to do a background operation, such as downloading, is very much frowned upon.
I would use the isDataAvailable property of PFFile to check if the data is available locally. If it isn't, use getDataInBackgroundWithBlock: to fetch the data in the background. You can use the completion method supplied by that call to update your imageView.
UPDATE - You can also wrap the getData call in a dispatch_async block, which will move the operation to another thread, therefore removing it from the main thread and getting rid of the warning.

Sending and receiving Windows messages

Windows messages seems a good way to notify an application on Windows OSes. It actually works well, but few question comes up to my mind:
How to specify structured data to the lparam of the SendMessage routines (like many message codes does)? I mean... of course the parameter is a pointer, but how the process access to it? Maybe is it allocated by a DLL loaded by the processes sending/receiving the message?
Is it possible to share message structured parameters (between sender and receiver)? They are marshalled between the send operation and the peeking operation? If this is the case, it is possible to return data from the caller by modifying the structured parameter? This could be usefull with SendMessage, since it is executed synchronously, instead the PostMessage routine.
Other doubts...
What the differences from PostMessage and SendNotifyMessage?
Is it possible to cause a deadlock in the case an application calls SendMessage to itself while processing the message pump?
If the message is one of the standard window's messages - usually with a message id between 0 and WM_USER, then the systems window message dispatching logic contains code to marshal the struct to the any processes the message is dispatched to.
Messages above WM_USER get no such treatment - and this includes all the common control messages introduced with Windows 95 - you cannot end any of the LVM_* (list view messages) or other new control messages to a control in a different process and get a result back.
WM_COPYDATA was specifically introduced as a general purpose mechanism for user code to marshal arbitrary data between processes - outside of WM_COPYDATA (or reusing other windows standard messages) there is no way to get windows to automatically marshal structured data using the message queue mechanism into another process.
If it is your own code doing the sending AND receiving of messages, you could use a dll to define a shared memory section, instead of sending pointers (the dll might be based differently in each process) sends offsets to the shared memory block.
If you want to exchange structured data with external applications that do not marshal their data (for example to extract data from a list or tree view) then you need to perform dll injection so you can send and process the message from "in-process".
SendNofityMessage is different to PostMessage because PostMessage always puts the message in the message queue, whereas SendNotifyMessage acts like SendMessage for windows in the same process. Then, even if the target window is in another process, the message is dispatched DIRECTLY to the window proc not placed in the posted message queue for retreivel via GetMessage or PeekMessage.
Lastly it is possible to cause a deadlock - however while in a "blocking" sendmessage waiting for another thread to reply, SendMessage will dispatch messages sent (not posted) from other threads - to prevent deadlocks. This mitigates most potential deadlocks, but its still possible to create deadlocks by calling other blocking apis, or going into modal message processing loops.
Your concerns apply primarily in the case of messages sent between processes -- within a process, you can just send a pointer, and the sender just has to ensure the data remains valid until the receiver is finished using it.
Some interprocess messages require you to work with an HGLOBAL (e.g., the clipboard messages). Others require an explicit block size (e.g., with WM_COPYDATA). Still others send data in a pre-specified structure (e.g., a zero-terminated string) to support marshalling.
Generally speaking you can't return a value by modifying the block you received. To return a value, you need to (for example) send a reply message.
SendMessage has some (fairly complex) logic to prevent deadlocks, but you still need to be careful.

How can I handle window messages from a separate thread?

I wish to launch a separate thread for handling window messages (via a blocking GetMessage loop), but still create the windows in the initial thread, afterward.
Within the separate thread, as soon as it launches, I am calling PeekMessage with PM_NOREMOVE to ensure a message queue exists (is this necessary?), followed by..
AttachThreadInput(initial thread id,GetCurrentThreadId(),true)
..before finally entering the message loop
I am not yet using a mutex or cs to ensure this is happening in time, but am merely using a Sleep statement in my initial thread for the sake of simplicity.
Regardless, window messages do not appear to be intercepted by the separate thread.
I am a little unsure as to whether I am doing this correctly, and would appreciate any possible guidance. Both threads are in the same process
Thank you all
That's not what AttachThreadInput does. Even after you attach your input queue to another thread, Windows still have thread affinity. Messages in the queue for a given window can only be removed from the queue by that window's thread.
What AttachTheadInput does is to make two threads share an input queue. This allows them to query information about the input state and know that the other thread will get the same answer for the same query. For instance, one thread could call GetAsyncKeyState and know that the answer reflected the key state for the other thread.
It allows two or more threads to have the same relationship to the input queue and each other as processes had in Windows 3x. This is the reason that this API exists; so that complex multiprocess applications could be ported from Win 3x to Win95/WinNT.
It seems the best way to instigate window creation from the main thread, while having messages for them handled in a separate, looping thread is to use a custom message, that can be sent to the separate thread - Thus allowing it to create the window, but still allowing that action to be invoked from the initial thread:
1) Allocate a custom message, and create a structure to hold the window initialisation parameters:
message_create_window = WM_USER + 0;
class Message_create_window{
Message_create_window(...);
};
2) Instead of calling CreateWindow(Ex), use something similiar to the following, passing in the relavant window creation parameters:
PostThreadMessage(
thread.id,
message_create_window,
new Message_create_window(...),
0
);
3) Handle the custom message in the message pump of your ui handling thread, extract the creation parameters, & free afterwards:
MSG msg;
GetMessage(&msg,0,0,0);
...
switch(msg->message){
...
case message_create_window:{
Message_create_window *data=msg->wParam;
CreateWindowEx(data->...);
delete data;
}break;
...
This does, however, have the following side-effects:
The window will be created asynchronously. If it is required that the initial thread block until the window is created (or, indeed, that the window's existence can ever be asserted) then a thread synchronisation tool must be used (such as an event)
Care should be taken when interacting with the window (it is a multithreaded application, after all)
If there are any major holes in this answer, or this seems like a terrible approach, please correct me.
(This is still my question, & I am trying to find the best way to accomplish this)

Resources