#include "stdafx.h"
#include <tchar.h>
#include <stdlib.h>
#include <time.h>
#include <stdarg.h>
#include "hwapi.h"
#define FILL_RANDOM_COMMAND _T("Selection Example\\Fill Random Bytes")
#define CLIP_SELECTION_COMMAND _T("Selection Example\\Clip to Selection")
#define COPY_NEW_FILE_COMMAND _T("Selection Example\\Copy to New Document")
#define COPY_BLOCK_SIZE 0x10000
BOOL doFillRandom(HWSESSION hSession, HWDOCUMENT hDoc) ;
BOOL doClipSelection(HWSESSION hSession, HWDOCUMENT hDoc) ;
BOOL doCopyToNewFile(HWSESSION hSession, HWDOCUMENT hDoc) ;
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
return TRUE;
}
HWAPIEP BOOL HWPLUGIN_Identify(LPTSTR lpstrPluginCommand,
size_t nMaxPluginCommand)
{
_sntprintf(lpstrPluginCommand, nMaxPluginCommand,
_T("%s;%s;%s"),
FILL_RANDOM_COMMAND,
CLIP_SELECTION_COMMAND,
COPY_NEW_FILE_COMMAND) ;
return TRUE ;
}
HWAPIEP DWORD HWPLUGIN_RequestCapabilities(LPCTSTR lpstrPluginCommand)
{
if (_tcsicmp(lpstrPluginCommand, FILL_RANDOM_COMMAND) == 0)
{
return HWPLUGIN_CAP_FILE_REQUIRE | HWPLUGIN_CAP_SELECTION_REQUIRE ;
}
else if (_tcsicmp(lpstrPluginCommand, CLIP_SELECTION_COMMAND) == 0)
{
return HWPLUGIN_CAP_FILE_REQUIRE | HWPLUGIN_CAP_SELECTION_REQUIRE ;
}
else if (_tcsicmp(lpstrPluginCommand, COPY_NEW_FILE_COMMAND) == 0)
{
return HWPLUGIN_CAP_FILE_REQUIRE ;
}
return 0 ;
}
HWAPIEP BOOL HWPLUGIN_Execute( LPCTSTR lpstrPluginCommand,
HWSESSION hSession,
HWDOCUMENT hDocument )
{
if (_tcsicmp(lpstrPluginCommand, FILL_RANDOM_COMMAND) == 0)
{
return doFillRandom(hSession, hDocument) ;
}
else if (_tcsicmp(lpstrPluginCommand, CLIP_SELECTION_COMMAND) == 0)
{
return doClipSelection(hSession, hDocument) ;
}
else if (_tcsicmp(lpstrPluginCommand, COPY_NEW_FILE_COMMAND) == 0)
{
return doCopyToNewFile(hSession, hDocument) ;
}
else
{
return FALSE ;
}
}
BOOL doFillRandom(HWSESSION hSession, HWDOCUMENT hDoc)
{
BOOL bRC = FALSE ;
QWORD qwStartPosition ;
QWORD qwLength ;
BOOL bReadOnly = TRUE ;
hwGetReadOnly(hDoc, &bReadOnly) ;
if (bReadOnly)
{
MessageBox(hwGetWindowHandle(hSession),
_T("Document is read-only; cannot perform operation."),
_T("Error"),
MB_ICONSTOP | MB_APPLMODAL) ;
}
else
{
srand( (unsigned)time( NULL ) );
if ((hwGetCaretPosition(hDoc, &qwStartPosition) == HWAPI_RESULT_SUCCESS) &&
(hwGetSelection(hDoc, &qwLength) == HWAPI_RESULT_SUCCESS))
{
bRC = TRUE ;
hwUndoBeginGroup(hDoc) ;
for (QWORD i=0; i<qwLength; i++)
{
char cByte = rand() % 256 ;
if (hwReplaceAt(hDoc, qwStartPosition + i, &cByte, 1, 1) !=
HWAPI_RESULT_SUCCESS)
{
hwOutputLog(hSession, HWLOG_ERR,
_T("Failed to replace byte at offset %08I64X"), qwStartPosition+i) ;
bRC = FALSE ;
break ;
}
if ((i % 1024) == 0)
{
TCHAR cStatus[256] ;
_sntprintf(cStatus, sizeof(cStatus) / sizeof(TCHAR),
_T("Random Fill: %I64d of %I64d"), i, qwLength) ;
QWORD percentComplete = (i * 100) / qwLength ;
if (hwUpdateProgress(hSession, (int) percentComplete, cStatus) !=
HWAPI_RESULT_SUCCESS)
{
hwOutputLog(hSession, HWLOG_INFO,
_T("User aborted operation")) ;
bRC = FALSE ;
break ;
}
}
}
if (bRC)
{
hwOutputLog(hSession, HWLOG_INFO,
_T("Replaced byte range [%08I64X .. %08I64X] with random bytes"),
qwStartPosition, qwStartPosition+qwLength) ;
}
hwUndoEndGroup(hDoc) ;
}
}
return bRC ;
}
BOOL doClipSelection(HWSESSION hSession, HWDOCUMENT hDoc)
{
BOOL bRC = FALSE ;
QWORD qwStartPosition ;
QWORD qwLength ;
QWORD qwDocSize ;
BOOL bReadOnly = TRUE ;
hwGetReadOnly(hDoc, &bReadOnly) ;
if (bReadOnly)
{
MessageBox(hwGetWindowHandle(hSession),
_T("Document is read-only; cannot perform operation."),
_T("Error"),
MB_ICONSTOP) ;
}
else
{
if ((hwGetCaretPosition(hDoc, &qwStartPosition) == HWAPI_RESULT_SUCCESS) &&
(hwGetSelection(hDoc, &qwLength) == HWAPI_RESULT_SUCCESS) &&
(hwGetDocumentSize(hDoc, &qwDocSize) == HWAPI_RESULT_SUCCESS))
{
bRC = TRUE ;
hwUndoBeginGroup(hDoc) ;
QWORD qwCutLength = qwDocSize - (qwStartPosition + qwLength) ;
if (qwCutLength > 0)
{
if (hwDeleteAt(hDoc, qwStartPosition + qwLength, qwCutLength)
!= HWAPI_RESULT_SUCCESS)
{
hwOutputLog(hSession, HWLOG_ERR,
_T("Failed to delete range [%08I64X .. %08I64X]"),
qwStartPosition + qwLength,
qwStartPosition + qwLength + qwCutLength) ;
bRC = FALSE ;
}
}
if (qwStartPosition > 0)
{
if (hwDeleteAt(hDoc, 0, qwStartPosition)
!= HWAPI_RESULT_SUCCESS)
{
hwOutputLog(hSession, HWLOG_ERR,
_T("Failed to delete range [%08I64X .. %08I64X]"),
0,
qwStartPosition) ;
bRC = FALSE ;
}
}
hwUndoEndGroup(hDoc) ;
hwSetCaretPosition(hDoc, 0) ;
hwSetSelection(hDoc, qwLength) ;
bRC = TRUE ;
}
}
return bRC ;
}
BOOL doCopyToNewFile(HWSESSION hSession, HWDOCUMENT hDoc)
{
BOOL bRC = FALSE ;
QWORD qwStartPosition ;
QWORD qwLength ;
QWORD qwDocSize ;
if ((hwGetCaretPosition(hDoc, &qwStartPosition) == HWAPI_RESULT_SUCCESS) &&
(hwGetSelection(hDoc, &qwLength) == HWAPI_RESULT_SUCCESS) &&
(hwGetDocumentSize(hDoc, &qwDocSize) == HWAPI_RESULT_SUCCESS))
{
if (qwLength == 0)
{
qwStartPosition = 0 ;
qwLength = qwDocSize ;
}
HWDOCUMENT hNewDoc = hwNewDocument(hSession) ;
if (hNewDoc != NULL)
{
bRC = TRUE ;
hwUndoDisable(hNewDoc) ;
QWORD qwBytesLeft = qwLength ;
QWORD qwBytesCopied = 0 ;
char cBuffer[COPY_BLOCK_SIZE] ;
DWORD dwNextProgress = GetTickCount() + 1000 ;
QWORD qwLastProgressCount = 0 ;
while (qwBytesLeft > 0)
{
QWORD qwBytesToCopy = __min(COPY_BLOCK_SIZE, qwLength - qwBytesCopied) ;
if (hwReadAt(hDoc, qwStartPosition + qwBytesCopied, cBuffer, qwBytesToCopy)
== HWAPI_RESULT_SUCCESS)
{
if (hwInsertAt(hNewDoc, qwBytesCopied, cBuffer, qwBytesToCopy) == HWAPI_RESULT_SUCCESS)
{
qwBytesLeft -= qwBytesToCopy ;
qwBytesCopied += qwBytesToCopy ;
}
else
{
hwOutputLog(hSession, HWLOG_ERR,
_T("Failed to insert at offset %08I64X"),
qwBytesCopied) ;
bRC = FALSE ;
break ;
}
}
else
{
hwOutputLog(hSession, HWLOG_ERR,
_T("Failed to read at offset %08I64X"),
qwStartPosition + qwBytesCopied) ;
bRC = FALSE ;
break ;
}
if (GetTickCount() > dwNextProgress)
{
dwNextProgress = GetTickCount() + 1000 ;
QWORD qwCopied = qwBytesCopied - qwLastProgressCount ;
qwLastProgressCount = qwBytesCopied ;
TCHAR cStatus[256] ;
_sntprintf(cStatus, sizeof(cStatus) / sizeof(TCHAR),
_T("Copying: %I64d of %I64d (%I64d KB/sec)"),
qwBytesCopied, qwLength, qwCopied / 1024) ;
QWORD percentComplete = (qwBytesCopied * 100) / qwLength ;
if (hwUpdateProgress(hSession, (int) percentComplete, cStatus) !=
HWAPI_RESULT_SUCCESS)
{
hwOutputLog(hSession, HWLOG_INFO,
_T("User aborted operation")) ;
bRC = FALSE ;
break ;
}
}
}
hwUndoEnable(hNewDoc) ;
}
}
return bRC ;
}