mirror of
https://github.com/reactos/reactos.git
synced 2025-07-25 23:24:01 +00:00
145 lines
3.3 KiB
C
145 lines
3.3 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS Clip Command
|
|
* FILE: base/applications/cmdutils/clip/clip.c
|
|
* PURPOSE: Provides clipboard management for command-line programs.
|
|
* PROGRAMMERS: Ricardo Hanke
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <windef.h>
|
|
#include <winbase.h>
|
|
#include <winuser.h>
|
|
|
|
#include "resource.h"
|
|
|
|
static void PrintError(void)
|
|
{
|
|
DWORD dwError;
|
|
LPWSTR lpMsgBuf = NULL;
|
|
|
|
dwError = GetLastError();
|
|
if (dwError == NO_ERROR)
|
|
return;
|
|
|
|
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL, dwError, 0, (LPWSTR)&lpMsgBuf, 0, NULL);
|
|
wprintf(L"%s", lpMsgBuf);
|
|
LocalFree(lpMsgBuf);
|
|
}
|
|
|
|
static void PrintResourceString(UINT uID)
|
|
{
|
|
WCHAR buff[500];
|
|
|
|
if (LoadStringW(GetModuleHandle(NULL), uID, buff, ARRAYSIZE(buff)))
|
|
{
|
|
wprintf(L"%s", buff);
|
|
}
|
|
}
|
|
|
|
static BOOL IsDataUnicode(HGLOBAL hGlobal)
|
|
{
|
|
BOOL bReturn;
|
|
LPVOID lpBuffer;
|
|
|
|
lpBuffer = GlobalLock(hGlobal);
|
|
bReturn = IsTextUnicode(lpBuffer, GlobalSize(hGlobal), NULL);
|
|
GlobalUnlock(hGlobal);
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
int wmain(int argc, wchar_t** argv)
|
|
{
|
|
HANDLE hInput;
|
|
DWORD dwBytesRead;
|
|
BOOL bStatus;
|
|
HGLOBAL hBuffer;
|
|
HGLOBAL hTemp;
|
|
LPBYTE lpBuffer;
|
|
SIZE_T dwSize = 0;
|
|
|
|
hInput = GetStdHandle(STD_INPUT_HANDLE);
|
|
|
|
/* Check for usage */
|
|
if (argc > 1 && wcsncmp(argv[1], L"/?", 2) == 0)
|
|
{
|
|
PrintResourceString(IDS_HELP);
|
|
return 0;
|
|
}
|
|
|
|
if (GetFileType(hInput) == FILE_TYPE_CHAR)
|
|
{
|
|
PrintResourceString(IDS_USAGE);
|
|
return 0;
|
|
}
|
|
|
|
/* Initialize a growable buffer for holding clipboard data */
|
|
hBuffer = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096);
|
|
if (!hBuffer)
|
|
{
|
|
PrintError();
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* Read data from the input stream by chunks of 4096 bytes
|
|
* and resize the buffer each time when needed.
|
|
*/
|
|
do
|
|
{
|
|
lpBuffer = GlobalLock(hBuffer);
|
|
if (!lpBuffer)
|
|
goto cleanup;
|
|
|
|
bStatus = ReadFile(hInput, lpBuffer + dwSize, 4096, &dwBytesRead, NULL);
|
|
dwSize += dwBytesRead;
|
|
GlobalUnlock(hBuffer);
|
|
|
|
hTemp = GlobalReAlloc(hBuffer, GlobalSize(hBuffer) + 4096, GMEM_ZEROINIT);
|
|
if (!hTemp)
|
|
goto cleanup;
|
|
|
|
hBuffer = hTemp;
|
|
}
|
|
while (dwBytesRead > 0 && bStatus);
|
|
|
|
/*
|
|
* Resize the buffer to the total size of data read.
|
|
* Note that, if the call fails, we still have the old buffer valid.
|
|
* The old buffer would be larger than the actual size of data it contains,
|
|
* but this is not a problem for us.
|
|
*/
|
|
hTemp = GlobalReAlloc(hBuffer, dwSize + sizeof(WCHAR), GMEM_ZEROINIT);
|
|
if (hTemp)
|
|
hBuffer = hTemp;
|
|
|
|
/* Attempt to open the clipboard */
|
|
if (!OpenClipboard(NULL))
|
|
goto cleanup;
|
|
|
|
/* Empty it, copy our data, then close it */
|
|
|
|
EmptyClipboard();
|
|
|
|
if (IsDataUnicode(hBuffer))
|
|
{
|
|
SetClipboardData(CF_UNICODETEXT, hBuffer);
|
|
}
|
|
else
|
|
{
|
|
// TODO: Convert text from current console page to standard ANSI.
|
|
// Alternatively one can use CF_OEMTEXT as done here.
|
|
SetClipboardData(CF_OEMTEXT, hBuffer);
|
|
}
|
|
|
|
CloseClipboard();
|
|
return 0;
|
|
|
|
cleanup:
|
|
GlobalFree(hBuffer);
|
|
PrintError();
|
|
return -1;
|
|
}
|