Jump to content
pcoder

globalSize()

Recommended Posts

Has anyone seen the case of globalSize() returning more than the requested size?
It would be much more useful to get the requested size (<= allocated size) to determine the clipboard data size,
but unfortunately I've found contradicting statements about globalSize().

 

Pro allocated size:
learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalsize
stackoverflow.com/questions/22075754/how-do-i-determine-clipboard-data-size

 

Pro requested size:
devblogs.microsoft.com/oldnewthing/20120316-00/?p=8083
www.labri.fr/perso/betrema/winnt/heapmm.html
www.joelonsoftware.com/2001/11/20/a-hard-drill-makes-an-easy-battle/

Share this post


Link to post
6 hours ago, pcoder said:

Has anyone seen the case of globalSize() returning more than the requested size?
It would be much more useful to get the requested size (<= allocated size) to determine the clipboard data size,
but unfortunately I've found contradicting statements about globalSize().

 

Pro allocated size:
learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalsize
stackoverflow.com/questions/22075754/how-do-i-determine-clipboard-data-size

 

Pro requested size:
devblogs.microsoft.com/oldnewthing/20120316-00/?p=8083
www.labri.fr/perso/betrema/winnt/heapmm.html
www.joelonsoftware.com/2001/11/20/a-hard-drill-makes-an-easy-battle/

GlobalAlloc rounds the requested size up to the next multiple of 8 (at least), so it is normal for GlobalSize to return more than the requested size if that is not a multiple of the used granularity. In fact the MS docs for GlobalAlloc explicitely state that GlobalSize should be used to get the allocated size of the block requested. Depending on the use of the block you may have to store the actual data size with the data itself if the extra bytes allocated by GlobalAlloc may cause a problem for the data recipient.

Note that the granularity used may depend on OS version, Microsoft is pretty vague on this.

Share this post


Link to post
Posted (edited)

Thank you, initially I thought the same (as stated in MS docs), but so far I could not confirm that GlobalSize() returns a larger size.
Did you also read the given link to oldnewthing which contains "bonus chatter"?

 

And I cannot believe that MS made such a mistake but has not corrected this.
In my use case, the clipboard format, used in getClipboardData(format), refers to a MIME type (a file in memory).
The clipboard reader needs to save each received stream to a file, which is easy if the file size is known. But interpreting every data format
(more than 20 different MIME types) to find the correct file size is very cumbersome.

I just hope that globalSize() returns the same as heapSize()

 

If the clipboard is used for a MIME type (file (png, svg, ...)), then the file size is not stored additionally
(because this would break the MIME format). therefore I need globalSize() to give the correct filesize.

Edited by pcoder

Share this post


Link to post
2 hours ago, pcoder said:

And I cannot believe that MS made such a mistake but has not corrected this.

What mistake is that? It's by design. Did you not read the articles you linked to?

Share this post


Link to post
Posted (edited)

Here is an excerpt from linked oldNewThing:

Quote

Bonus chatter: It appears that at some point, the kernel folks decided that these “bonus bytes” were more hassle than they were worth, and now they spend extra effort remembering not only the actual size of the memory block but also the requested size. When you ask, “How big is this memory block?” they lie and return the requested size rather than the actual size. In other words, the free bonus bytes are no longer exposed to applications by the kernel heap functions.

With mistake I mean, globalSize() would be much useless without giving the requested size (clipboard content size).

And I just wanted to know if anyone of the forum members got a larger size than requested, because I don't.

Edited by pcoder

Share this post


Link to post

GlobalSize isn't useless just because it doesn't behave the way you want it to or expect it to.

From what I can tell you can only rely on the returned size to be >= requested size. Regardless of whatever it might return right now on your system.

That said, I can't remember having GlobalSize return a value I didn't expect - but I might also just have forgotten about it.

 

Anyway, if you are reading data from the clipboard then you can try to request the TYMED_ISTREAM medium instead of TYMED_HGLOBAL. If you are lucky the returned IStream will report the correct size. I doubt it though; I think the IStream is just a wrapper around a HGLOBAL.

Share this post


Link to post
On 3/29/2024 at 8:10 AM, pcoder said:

In my use case, the clipboard format, used in getClipboardData(format), refers to a MIME type (a file in memory).

The clipboard reader needs to save each received stream to a file, which is easy if the file size is known. But interpreting every data format
(more than 20 different MIME types) to find the correct file size is very cumbersome.

Are you the one putting the data on the clipboard to begin with? If so, then why not store the required file size explicitly? If you can't put it in the MIME data itself, you can store it as a second format alongside the MIME data. The clipboard can hold more than one data item at a time.

Share this post


Link to post

Essentially I need to copy/paste MIME formats as defined in urlMon.h and others.
I've seen a few clipboard readers which use GlobalSize(handle) as file size.

The alternative would be having a correct reader for all possible file types, just for finding the file size.

I believe Microsoft is aware of these and other challenges and has corrected globalSize(), but I have no proof.

Share this post


Link to post

I think you can safely assume that:

  • GlobalSize returns the correct size.
  • Any additional memory it might return (which I don't believe it will) will be zeroed.

I've been working with drag/drop and the clipboard through COM for 25 years and none of my tools has any handling of extra data and they assume that GlobalSize returns the requested size (which is has so far).

  • Like 1

Share this post


Link to post
7 hours ago, pcoder said:

I believe Microsoft is aware of these and other challenges and has corrected globalSize(), but I have no proof.

Is Raymond Chen's word not proof enough for you?

Quote

Bonus chatter: It appears that at some point, the kernel folks decided that these “bonus bytes” were more hassle than they were worth, and now they spend extra effort remembering not only the actual size of the memory block but also the requested size. When you ask, “How big is this memory block?” they lie and return the requested size rather than the actual size.

 

Share this post


Link to post
Posted (edited)
5 hours ago, Remy Lebeau said:

Is Raymond Chen's word not proof enough for you? 

 

Close enough for me, because a larger size would lead to more hassle, and MS is aware of this.

Edited by pcoder

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×