Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

438 lines
12 KiB

/*++
Copyright (C) Microsoft Corporation
All rights reserved.
Module Name: clip.cpp
Abstract
Clip.exe copies input from console standard input (stdin)
to the Windows clipboard in CF_TEXT format.
Author:
Author: Charles Stacy Harris III
Date: 15 March 1995
Revision History:
Oct 1996 - (a-martih)
Resolved bug 15274 - reporting errors did not work.
Feb 1997 - (a-josehu)
Resolved bug 69727 - app hangs when clip typed on cmd line
Add -? /? Help message
Remove MessageBox from ReportError
July 2nd 2001 - Wipro Technologies
Changed to have the localization.
Handled for exceptions.
--*/
#include "pch.h"
#include "resource.h"
//
// function prototypes
//
BOOL DisplayHelp();
DWORD Clip_OnCreate();
BYTE* ReadFileIntoMemory( HANDLE hFile, DWORD *cb );
BOOL SaveDataToClipboard( IN LPVOID pvData, IN DWORD dwSize, UINT uiFormat );
DWORD ProcessOptions( DWORD argc, LPCWSTR argv[], PBOOL pbUsage );
//
// implementation
//
DWORD
__cdecl wmain( IN DWORD argc,
IN LPCWSTR argv[] )
/*++
Routine description : main function which calls necessary functions to copy the
contents of standart input file onto clipboard
Arguments : Standard arguments for wmain
Return Value : DWORD
0 : if it is successful
1 : if it is failure
--*/
{
DWORD dwStatus = 0;
BOOL bUsage = FALSE;
// process the command line options
dwStatus = ProcessOptions( argc, argv, &bUsage );
// check the result
if( EXIT_FAILURE == dwStatus )
{
ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
}
// parser will not allow this situation -- but still better to check
else if( TRUE == bUsage && argc > 2 )
{
SetLastError( (DWORD) MK_E_SYNTAX );
ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
ShowMessage( stderr, GetResString2( IDS_HELP_MESSAGE, 0 ) );
dwStatus = EXIT_FAILURE;
}
// user requested to display the usage
else if( TRUE == bUsage )
{
dwStatus = EXIT_SUCCESS;
DisplayHelp();
}
// original functionality
else if ( dwStatus == EXIT_SUCCESS )
{
dwStatus = Clip_OnCreate();
}
ReleaseGlobals();
return dwStatus;
}
DWORD
Clip_OnCreate()
/*++
Routine Description : copies the contents of clipboard
1. Open the clipboard
2. Empty the clipboard
3. Copy stdin into memory
4. Set the clipboard data
Arguments:
[ in ] argc : argument count
[ in ] argv : a pointer to command line argument
Return Type : DWORD
returns EXIT_SUCCESS or EXIT_FAILURE according copying to clipboard
successful or not.
--*/
{
DWORD dwSize = 0;
LONG lLength = 0;
LPVOID pvData = NULL;
LPWSTR pwszBuffer = NULL;
HANDLE hStdInput = NULL;
BOOL bResult = FALSE;
UINT uiFormat = 0;
hStdInput = GetStdHandle( STD_INPUT_HANDLE );
if( INVALID_HANDLE_VALUE == hStdInput )
{
return EXIT_FAILURE;
}
if ( FILE_TYPE_CHAR == GetFileType( hStdInput ) ) // bug 69727
{
// error with GetStdHandle()
ShowMessageEx( stdout, 2, TRUE, L"\n%s %s",
TAG_INFORMATION, GetResString2( IDS_HELP_MESSAGE, 0 ) );
return EXIT_SUCCESS;
}
//place the contents in a global memory from stdin
pvData = ReadFileIntoMemory( hStdInput, &dwSize );
//check for allocation failed or not
if( NULL == pvData )
{
ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
return EXIT_FAILURE;
}
//convert contents into console code page if they are unicode
uiFormat = CF_UNICODETEXT;
if ( IsTextUnicode( pvData, dwSize, NULL ) == FALSE )
{
lLength = MultiByteToWideChar(
GetConsoleOutputCP(), 0, (LPCSTR) pvData, -1, NULL, 0);
if( lLength > 0 )
{
pwszBuffer = (LPWSTR) AllocateMemory( (lLength + 5) * sizeof(WCHAR) );
if( pwszBuffer == NULL )
{
ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
FreeMemory( &pvData );
return EXIT_FAILURE;
}
lLength = MultiByteToWideChar(
GetConsoleOutputCP(), 0, (LPCSTR) pvData, -1, pwszBuffer, lLength );
if ( lLength <= 0 )
{
ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
FreeMemory( &pvData );
FreeMemory( (LPVOID*) &pwszBuffer );
return EXIT_FAILURE;
}
dwSize = lLength * sizeof( WCHAR );
FreeMemory( &pvData );
pvData = pwszBuffer;
}
else
{
uiFormat = CF_TEXT;
}
}
bResult = SaveDataToClipboard( pvData, dwSize, uiFormat );
if ( bResult == FALSE )
{
ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
}
// release the memory
FreeMemory( &pvData );
return (bResult == TRUE ) ? EXIT_SUCCESS : EXIT_FAILURE;
}
BOOL
SaveDataToClipboard( IN LPVOID pvData,
IN DWORD dwSize,
UINT uiFormat )
/*++
Routine Description :
It places the data into clipboard.
Arguments:
[ in ] pvData : Pointer to memory block whose contents are to
be placed into clipboard.
[ in ] dwSize : Size of the memory block.
[ in ] uiFormat : format that needs to copied onto the clipboard
Return Value:
Returns TRUE if successfully saves,
FALSE otherwise.
--*/
{
// local variables
HANDLE hClipData = NULL;
HGLOBAL hGlobalMemory = NULL;
LPVOID pvGlobalMemoryBuffer = NULL;
// check the input
if ( pvData == NULL || dwSize == 0 )
{
SetLastError( ERROR_INVALID_PARAMETER );
SaveLastError();
return FALSE;
}
//open the clipboard and display error if it fails
if( OpenClipboard( NULL ) == FALSE )
{
SaveLastError();
return FALSE;
}
//take the ownership for this window on clipboard and display
//error if it fails
if( EmptyClipboard() == FALSE )
{
SaveLastError();
CloseClipboard();
return FALSE;
}
hGlobalMemory = GlobalAlloc( GMEM_SHARE | GMEM_MOVEABLE, dwSize + 10 );
if( hGlobalMemory == NULL )
{
SaveLastError();
CloseClipboard();
return FALSE;
}
if ( (pvGlobalMemoryBuffer = GlobalLock( hGlobalMemory )) == NULL )
{
SaveLastError();
GlobalFree( hGlobalMemory );
CloseClipboard();
return FALSE;
}
SecureZeroMemory( pvGlobalMemoryBuffer, dwSize + 10 );
CopyMemory( pvGlobalMemoryBuffer, pvData, dwSize );
if( FALSE == GlobalUnlock( hGlobalMemory ) )
{
if ( GetLastError() != NO_ERROR )
{
SaveLastError();
GlobalFree( hGlobalMemory );
CloseClipboard();
return FALSE;
}
}
hClipData = SetClipboardData( uiFormat, hGlobalMemory );
if( NULL == hClipData )
{
SaveLastError();
GlobalFree( hGlobalMemory );
CloseClipboard();
return FALSE;
}
//close the clipboard and display error if it fails
CloseClipboard();
GlobalFree( hGlobalMemory );
return TRUE;
}
DWORD
ProcessOptions( IN DWORD argc,
IN LPCWSTR argv[],
OUT PBOOL pbUsage )
/*++
Routine Description : Function used to process the main options
Arguments:
[ in ] argc : Number of command line arguments
[ in ] argv : Array containing command line arguments
[ out ] pbUsage : Pointer to boolean variable returns true if
usage option specified in the command line.
Return Type : DWORD
A Integer value indicating EXIT_SUCCESS on successful parsing of
command line else EXIT_FAILURE
--*/
{
DWORD dwOptionsCount = 0;
TCMDPARSER2 cmdOptions[ 1 ];
dwOptionsCount = SIZE_OF_ARRAY( cmdOptions );
SecureZeroMemory( cmdOptions, sizeof( TCMDPARSER2 ) * dwOptionsCount );
StringCopyA( cmdOptions[ 0 ].szSignature, "PARSER2", 8 );
cmdOptions[ 0 ].dwCount = 1;
cmdOptions[ 0 ].dwFlags = CP2_USAGE;
cmdOptions[ 0 ].dwType = CP_TYPE_BOOLEAN;
cmdOptions[ 0 ].pValue = pbUsage;
cmdOptions[ 0 ].pwszOptions = L"?";
if( DoParseParam2( argc, argv, -1,
dwOptionsCount, cmdOptions, 0 ) == FALSE )
{
return EXIT_FAILURE;
}
SetLastError( ERROR_SUCCESS );
return EXIT_SUCCESS;
}
/*
ReadFileIntoMemory
~~~~~~~~~~~~~~~~~~
Read the contents of a file into GMEM_SHARE memory.
This function could be modified to take allocation flags
as a parameter.
*/
BYTE*
ReadFileIntoMemory( IN HANDLE hFile,
OUT DWORD* pdwBytes )
/*++
Routine Description : Read the contents of a file into GMEM_SHARE memory.
This function could be modified to take allocation
flags as a parameter.
Arguments:
[ in ] hFile : Handle to a file which is nothing but handle to
stdin file.
[ out] cb : returns the copied buffer length
Return Type : Handle to memory object.
--*/
{
BYTE* pb = NULL;
DWORD dwNew = 0;
DWORD dwRead = 0;
DWORD dwAlloc = 0;
const size_t dwGrow = 1024;
// check the inputs
if ( hFile == NULL || pdwBytes == NULL )
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
do
{
if ( dwAlloc - dwRead < dwGrow )
{
dwAlloc += dwGrow;
if( NULL == pb )
{
pb = (BYTE*) AllocateMemory( dwAlloc + 10 );
}
else if( FALSE == ReallocateMemory( (LPVOID*) &pb, dwAlloc + 10 ) )
{
FreeMemory( (LPVOID*) &pb );
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
}
if ( FALSE == ReadFile( hFile, pb + dwRead, (dwAlloc - dwRead), &dwNew, 0 ) )
{
break;
}
dwRead += dwNew;
} while (dwNew != 0 );
*pdwBytes = dwRead;
SecureZeroMemory( pb + dwRead, (dwAlloc - dwRead) );
SetLastError( ERROR_SUCCESS );
return pb;
}
BOOL
DisplayHelp()
/*++
Routine Description : Displays the help usage to console or to file
if redirected.
Arguments:
Return Type : EXIT_SUCCESS if successful,EXIT_FAILURE otherwise.
--*/
{
//changing the help by taking the strings from resource file
for( DWORD dw=IDS_MAIN_HELP_BEGIN;dw<=IDS_MAIN_HELP_END;dw++)
{
ShowMessage( stdout, GetResString2( dw, 0 ) );
}
SetLastError( ERROR_SUCCESS );
return TRUE;
}