When an application puts data on the clipboard in a private format (CF_PRIVATEFIRST to CF_PRIVATELAST) then it has to free it in response to WM_DESTROYCLIPBOARD, because for these formats the system won't do it automatically.
It ought logically to be true that a private format used by one application won't be seen by any other application (even if they use the same format code in the private range).
a) How does the system enforce this? Does it use the clipboard owner (window handle)?
b) Do private format items automatically get removed from the clipboard when the owner window is closed? (Using a clipboard viewer it seems that they do not.) So what happens when window handles are reused?
In addition to freeing the memory in response to WM_DESTROYCLIPBOARD, do you also need to free it when the application exits? (I know that the clipboard uses global memory so that the data can be accessed from any process, so I'm guessing it isn't automatically freed when the process that created it exits.)
Ideally, you would remove just the private formats and leave any standard formats in place when the application exits, but I can't find an API call to remove just one format from the clipboard. Is there a simple way to do this other than emptying the clipboard and then explicitly writing back to it the non-private formats?
I've searched the MSDN documentation and Google and can't find answers to these questions, so can anyone here help?
(I know about registered clipboard formats. I'm not asking about those.)
Non-authoritative answer, but it may guide your testing to determine the truth:
I think contrary to the documentation for SetClipboardData when using a private format the ownership of the memory of the passed handle is not given to the system. Thus any other program trying to read the clipboard would be getting the handle for data it couldn't read. Test: can your clipboard viewer actually retrieve the private data, or just the handles?
I believe the memory that you are supposed to free is your own application memory that you referenced when you called SetClipboardData. So you don't need to free the memory on application exit as it should be freed with the rest of your memory.
The private formats would point to data that no longer existed, similar to delayed rendering data that was not rendered when the WM_RENDERALLFORMATS message was received.
Related
Is it valid to change the contents of lpstrFile on CDN_FILEOK via Hook on GetOpenFileName()/GetSaveFileName()?
The reason is that I may need to append additional information to the file name for GetSaveFileName(). The user could enter a generic name like "my file" and the program handles adding information user wouldn't know to add (already part of filter). Then it would check for overwrite and put up a question if okay to overwrite. If not, I can just use the custom data field, but I couldn't find any reference if it's allowed to change the contents of lpstrFile
TIA!!
Depends on your definition of valid. The designers of this API did not intend for you to do this but if it works, it works™. These dialogs will probably not change their internal design ever again since Microsoft have a fair amount of application compatibility to worry about in this area and these dialogs were replaced by the COM based API in Vista+.
My recommendation would be to store the address of your buffer in lCustData as well before calling the Open/Save function and only modify that buffer. The dialog could in theory use its own buffer in some places and there might not be space for you to write anything in those and there is no way to figure out their size.
In practice, there seems to be no problem to play with the buffer behind Windows' back. In the past I have even replaced the actual buffer address with a new bigger memory block when implementing support for multi-file-select.
In a Mac OS X app (Cocoa), I'm copying some images from my app to others using a NSDraggingSession. The NSDraggingItem makes use of an object that implements the protocol NSPasteboardItemDataProvider, to provide the data when the user drops it.
As I'm dealing with images, the types involved are: NSPasteboardTypePNG, kPasteboardTypeFileURLPromise, kUTTypeFileURL, com.adobe.photoshop-image and public.svg-image. These images are in a remote location, so before I can provide them to the pasteboard, I have to download them from the Internet.
I implement the method - pasteboard(pasteboard:item:provideDataForType:) doing something like this:
If the type requested is kPasteboardTypeFileURLPromise, I get the paste location and build and set in the pasteboard the URL string with the location where the file is supposed to be written in the future.
If the type requested is kUTTypeFileURL, I download the file, specify a temporal location and write the downloaded file to that location. Then, I set in the pasteboard the URL string of the location.
If the type requested is one of the others, I download the file and set the plain NSData in the pasteboard.
All these operations are performed on the main thread, producing some lags that I want to get rid of.
I've tried to perform these operations on a background thread, and come back to the main thread to set the final data in the pasteboard, but this doesn't work because the method finishes before.
Does anyone know a way to achieve it?
Promises of pasteboard types are usually meant to be an alternative format of data that you already have, where you want to avoid the expense in time and memory of converting before it's necessary. I don't think it's really appropriate to use it to defer downloading any of the data, at all. For one thing, the download could fail when it's ultimately requested. For another, it could take an arbitrarily long time, as you're struggling with now.
So, I think you should download the data in advance. Either keep it in memory or save it to a temporary file. Use promised types, if appropriate, to deliver it in different forms, but have it on hand in advance.
When I copy data in my win32 program to the clipbord, should i free the memory i copied to clipboard, after I paste it elsewhere? or the system is responsible for this.
There are two ways of putting data on the clipboard.
Method 1: Put the data onto the clipboard directly, by calling SetClipboardData and passing a non-NULL value as the second parameter. In that case, the system will take responsibility for the data, and you should not free it yourself.
Method 2: Put a placeholder onto the clipboard, by calling SetClipboardData and passing NULL as the second parameter. In that case, the application is responsible for the data until the point it calls SetClibpoardData with a non-NULL second parameter, at which point responsibility transfers to the operating system.
It's not clear from your question which method you are using.
Read the documentation:
If SetClipboardData succeeds, the system owns the object identified by the hMem parameter. The application may not write to or free the data once ownership has been transferred to the system
Keeping track of the clipboard data so you can remove it from the clipboard when closing your app is completely optional. Once the data is on the clipboard, the system owns it and it is separate from your app, so you can choose to leave it on the clipboard so it remains available for continued usage after your app is closed. Unless you are using delayed rendering, that ism in which case it does make sense to remove it from the clipboard when closing your app, since your app will not be running anymore to render the data when requested by other apps.
Your application is responsible for handling data on the clipboard, if it put it there. This is why a lot of applications, like Microsoft Office, ask you if you want to keep a large amount of data on the clipboard or not, when you exit the application.
I would strongly advise user-interaction however, since you do not know if the user needs the data on the clipboard somewhere else later.
It is generally done by the system however, some responsible applications also take care of asking the user to free up the clipboard before leaving.
e.g. MSWord will ask the user to keep the data in memory or not before it quits.
For general purpose, you can leave it to system.
Remember here that user might want to keep it in Clipboard (Even after closing application) so you should not mangle with it and remove it from memory.
As the title says, I want to associate a random bit of data (ULONG) with a running process on the local machine. I want that data persisted with the process it's associated with, not the process thats reading & writing the data. Is this possible in Win32?
Yes but it can be tricky. You can't access an arbitrary memory address of another process and you can't count on shared memory because you want to do it with an arbitrary process.
The tricky way
What you can do is to create a window (with a special and known name) inside the process you want to decorate. See the end of the post for an alternative solution without windows.
First of all you have to get a handle to the process with OpenProcess.
Allocate memory with VirtualAllocEx in the other process to hold a short method that will create a (hidden) window with a special known name.
Copy that function from your own code with WriteProcessMemory.
Execute it with CreateRemoteThread.
Now you need a way to identify and read back this memory from another process other than the one that created that. For this you simply can find the window with that known name and you have your holder for a small chunk of data.
Please note that this technique may be used to inject code in another process so some Antivirus may warn about it.
Final notes
If Address Space Randomization is disabled you may not need to inject code in the process memory, you can call CreateRemoteThread with the address of a Windows kernel function with the same parameters (for example LoadLibrary). You can't do this with native applications (not linked to kernel32.dll).
You can't inject into system processes unless you have debug privileges for your process (with AdjustTokenPrivileges).
As alternative to the fake window you may create a suspended thread with a local variable, a TLS or stack entry used as data chunk. To find this thread you have to give it a name using, for example, this (but it's seldom applicable).
The naive way
A poor man solution (but probably much more easy to implement and somehow even more robust) can be to use ADS to hide a small data file for each process you want to monitor (of course an ADS associated with its image then it's not applicable for services and rundll'ed processes unless you make it much more complicated).
Iterate all processes and for each one create an ADS with a known name (and the process ID).
Inside it you have to store the system startup time and all the data you need.
To read back that informations:
Iterate all processes and check for that ADS, read it and compare the system startup time (if they mismatch then it means you found a widow ADS and it should be deleted.
Of course you have to take care of these widows so periodically you may need to check for them. Of course you can avoid this storing ALL these small chunk of data into a well-known location, your "reader" may check them all each time, deleting files no longer associated to a running process.
If you try to close a Microsoft Office application when you've got a ton of its stuff on the clipboard (e.g. a whole word doc), it prompts you to ask if you would like to access that data after the application is closed.
In this day and age, does it really matter if I have say 10MB of stuff on the clipboard?
As I write my image processing app, should I follow the same rule as Office, or just forget about it and leave the data there?
Personally, I favor just forgetting about it and leaving it there. I've always found the MS Word approach more annoying than useful.
The reason word is asking about this is that it uses Delayed Rendering for the clipboard. This allows word to only create the formats that are requested upon a paste operation. However, any formats on the clipboard that were created with delayed rendering will disappear if the program exits without rendering them. In the case of excel, rendering thousands of empty cells in RTF would take megabytes of space, even though the actual data is tiny. Thus it asks whether you want the data rendered to the clipboard or if you're fine with losing it.
For your own application, the question then becomes: should I use delayed rendering? The answer depends on how long it take you to render in the various formats you'd like to support. If you're only supporting one format that renders quickly, odds are there's not going to be an advantage to delayed rendering.
If you're storing things on the clipboard without the user requesting it then you might just annoy a few people :)
Otherwise, yeah, just leave the data there.
How To Erase Windows Clipboard Data and Why.
any one who has access to the computer can easily see the clipboard information.
I'd guess, malware today would also be snooping there.
this question might be more suitable on superuser.