-2

In the example below, I successfully overwrote data. Does that mean the data is stored in local memory rather than global memory? So GetClipboardData() makes a local copy of the clipboard's memory? If that is the case, then what is the point of requiring the use of GlobalLock() before reading that memory. Also, why don't I have to free() that local memory?

This is a excerpt from the section called: Getting Text from the Clipboard

"The handle you receive from GetClipboardData doesn't belong to your program—it belongs to the clipboard. ... You can't free that handle or alter the data it references. If you need to have continued access to the data, you should [manually using malloc()] make a copy of the memory block."

#include <stdio.h>
#include <windows.h>

int main(void)
{
    if (IsClipboardFormatAvailable(CF_TEXT) != 0)
    {
        if (OpenClipboard(NULL) != 0)
        {
            HANDLE hData = GetClipboardData(CF_TEXT);
            if (hData != NULL)
            {
                char *content = GlobalLock(hData);
                if(content == NULL)
                    puts("GlobalLock()");
                else
                {
                    size_t length = strlen(content);

                    printf("Before: %s\n", content);
                    FillMemory(content + (length / 2), (length / 2), '*');//Hello World!
                    printf("After : %s\n", content);

                    if (GlobalUnlock(hData) == 0)
                    {
                        if (GetLastError() != NO_ERROR)
                            puts("GlobalUnlock()");
                    }
                }
            }
            else
            {
                if (GetLastError() != ERROR_SUCCESS)
                    puts("GetClipboardData()");
            }

            if (CloseClipboard() == 0)
                puts("CloseClipboard()");
        }
        else
            puts("OpenClipboard()");
    }

    getchar();

    return 0;
}

First execution:
Before: Hello World!
After : Hello ******

Second execution:
Before: Hello World!
After : Hello ******

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • `GetClipboardData()` doesn't make a local copy of the clipboard's memory, but it returns a handle that needs to be used with `GlobalLock`. That is required because the API has been designed that way. And `free` can be used only on memory that has been allocated by your process using `malloc` and friends. – Jabberwocky Jul 12 '18 at 09:53
  • 1
    The terms local and global are not helpful, dating back to Win16. Most of your confusion stems from you trying to infer meaning from those terms, which renders the question somewhat moot. – David Heffernan Jul 12 '18 at 09:56
  • @Jabberwocky If there is no local copy, then why is Hello World! being overwritten on first execution but those changes are not saved on the second execution? – Bill Paxtonn Jul 12 '18 at 10:10
  • 1
    *Does that mean the data is stored in local memory rather than global memory?* That question does not make any sense today. – David Heffernan Jul 12 '18 at 10:13
  • The output of the first execution and the second execution are the same. Read your question again and clarify. – Jabberwocky Jul 12 '18 at 10:17
  • Clarification for future readers: There is a copy of the clipboard memory being made, as proven by my sample code. But that copy is handled by the clipboard. – Bill Paxtonn Jul 12 '18 at 10:24
  • 1
    Clarification for future readers: The above comment is incorrect. – David Heffernan Jul 12 '18 at 10:32

1 Answers1

1
  1. You get access to a shared memory.
  2. Clipboard memory is allocated as GMEM_MOVEABLE! So to receive the actual pointer you need GlobalLock
  3. The Clipboard Memory (even the copy in your process) is owned by the Clipboard and freed by the Clipboard handler. You are never allowed to free the memory. The memory may be freed when calling CloseClipboard

For more internals about the clipboard please read this.

xMRi
  • 14,982
  • 3
  • 26
  • 59