Files
ladislav-zezula-FileTest/DlgEaEditor.cpp
Ladislav Zezula f7b8b667a7 Test
2023-11-23 10:54:15 +01:00

428 lines
12 KiB
C++

/*****************************************************************************/
/* DlgEaEditor.cpp Copyright (c) Ladislav Zezula 2005 */
/*---------------------------------------------------------------------------*/
/* Description : */
/*---------------------------------------------------------------------------*/
/* Date Ver Who Comment */
/* -------- ---- --- ------- */
/* 16.08.05 1.00 Lad Created */
/*****************************************************************************/
#include "FileTest.h"
#include "resource.h"
//-----------------------------------------------------------------------------
// Local functions
static int nChangingEdit = 0;
static DWORD TwoDigitsToBinValue(LPCTSTR szBinValue)
{
TCHAR chDigit1;
TCHAR chDigit2;
// Verify the digits
if(!isxdigit(szBinValue[0]) || !isxdigit(szBinValue[1]))
return (DWORD)0x100;
chDigit2 = (TCHAR)(UINT_PTR)CharUpper((LPTSTR)szBinValue[0]);
chDigit1 = (TCHAR)(UINT_PTR)CharUpper((LPTSTR)szBinValue[1]);
if(chDigit1 > '9')
chDigit1 -= 'A' - '9' - 1;
if(chDigit2 > '9')
chDigit2 -= 'A' - '9' - 1;
return ((chDigit2 - '0') << 0x04) | (chDigit1 - '0');
}
static int CTextToBinArray(LPTSTR szTextValue, LPBYTE pbBinValue)
{
DWORD dwBinValue;
int nLength = 0;
while(*szTextValue != 0)
{
if(*szTextValue == _T('\\'))
{
szTextValue++;
switch(*szTextValue)
{
case _T('\\'):
*pbBinValue = '\\';
break;
case _T('x'):
case _T('X'):
szTextValue++;
dwBinValue = TwoDigitsToBinValue(szTextValue);
if(dwBinValue == 0x0100)
return -1;
*pbBinValue = (BYTE)dwBinValue;
szTextValue++;
break;
}
}
else
*pbBinValue = (BYTE)(*szTextValue);
szTextValue++;
pbBinValue++;
nLength++;
}
return nLength;
}
static int BinTextToBinArray(LPTSTR szBinValue, LPBYTE pbBinValue)
{
DWORD dwBinValue;
int nLength = 0;
while(*szBinValue != 0)
{
// Skip spaces
while(0 < *szBinValue && *szBinValue <= 0x20)
szBinValue++;
dwBinValue = TwoDigitsToBinValue(szBinValue);
if(dwBinValue == 0x0100)
return -1;
*pbBinValue++ = (BYTE)dwBinValue;
szBinValue += 2;
nLength++;
// Must be a space there
if(*szBinValue > 0x20)
return -1;
// Skip spaces
while(0 < *szBinValue && *szBinValue <= 0x20)
szBinValue++;
}
return nLength;
}
static int BinArrayToBinText(LPBYTE pbBinValue, int nBinLength, LPTSTR szBinValue, size_t cchBinValue)
{
LPTSTR szBinValueEnd = szBinValue + cchBinValue;
for(int i = 0; i < nBinLength; i++, pbBinValue++)
{
StringCchPrintf(szBinValue, (szBinValueEnd - szBinValue), _T("%02lX "), (*pbBinValue & 0x000000FF));
szBinValue += 3;
}
*szBinValue = 0;
return nBinLength;
}
static int BinArrayToCText(LPBYTE pbBinValue, int nBinLength, LPTSTR szTextValue, size_t cchTextLength)
{
LPTSTR szTextEnd = szTextValue + cchTextLength;
for(int i = 0; i < nBinLength; i++, pbBinValue++)
{
if(0x20 <= *pbBinValue && *pbBinValue < 0x80)
{
*szTextValue++ = (TCHAR)*pbBinValue;
}
else
{
StringCchPrintf(szTextValue, (szTextEnd - szTextValue), _T("\\x%02lX"), (*pbBinValue & 0x000000FF));
szTextValue += 4;
}
}
*szTextValue = 0;
return nBinLength;
}
static void UpdateDialog(HWND hDlg)
{
BOOL bEnable;
nChangingEdit++;
bEnable = (IsDlgButtonChecked(hDlg, IDC_RADIO1) == BST_CHECKED);
EnableWindow(GetDlgItem(hDlg, IDC_DATA_VALUE_TEXT), bEnable);
bEnable = (IsDlgButtonChecked(hDlg, IDC_RADIO2) == BST_CHECKED);
EnableWindow(GetDlgItem(hDlg, IDC_DATA_VALUE_BIN), bEnable);
nChangingEdit--;
}
static void SetDlgItemCText(HWND hDlg, UINT nIDCtrl, LPBYTE pbData, int nLength)
{
LPTSTR szBinText;
size_t cchLength = nLength * 4 + 1;
szBinText = new TCHAR[cchLength];
if(szBinText != NULL)
{
BinArrayToCText(pbData, nLength, szBinText, cchLength);
SetDlgItemText(hDlg, nIDCtrl, szBinText);
delete [] szBinText;
}
}
static void SetDlgItemBin(HWND hDlg, UINT nIDCtrl, LPBYTE pbData, int nLength)
{
LPTSTR szBinText;
size_t cchLength = nLength * 4 + 1;
szBinText = new TCHAR[cchLength];
if(szBinText != NULL)
{
BinArrayToBinText(pbData, nLength, szBinText, cchLength);
SetDlgItemText(hDlg, nIDCtrl, szBinText);
delete [] szBinText;
}
}
// Text value has changed
static int UpdateEaValueBin(HWND hDlg)
{
LPTSTR szTextValue;
LPTSTR szBinValue;
LPBYTE pbBinValue;
HWND hSrcEdit = GetDlgItem(hDlg, IDC_DATA_VALUE_TEXT);
HWND hTrgEdit = GetDlgItem(hDlg, IDC_DATA_VALUE_BIN);
int nTextLength = GetWindowTextLength(hSrcEdit);
int cchTextLength = nTextLength * 3 + 1;
int nBinLength;
szTextValue = new TCHAR[nTextLength + 1];
szBinValue = new TCHAR[cchTextLength];
pbBinValue = new BYTE[nTextLength + 1];
GetWindowText(hSrcEdit, szTextValue, nTextLength + 1);
// Process the binary buffer and convert it to the binary data
nChangingEdit++;
nBinLength = CTextToBinArray(szTextValue, pbBinValue);
if(nBinLength != -1)
{
BinArrayToBinText(pbBinValue, nBinLength, szBinValue, cchTextLength);
SetWindowText(hTrgEdit, szBinValue);
}
else
SetWindowTextRc(hTrgEdit, IDS_CONVERSION_ERROR);
nChangingEdit--;
delete [] pbBinValue;
delete [] szBinValue;
delete [] szTextValue;
return TRUE;
}
// Binary value has changed
static int UpdateEaValueText(HWND hDlg)
{
LPTSTR szTextValue;
LPTSTR szBinValue;
LPBYTE pbBinValue;
HWND hSrcEdit = GetDlgItem(hDlg, IDC_DATA_VALUE_BIN);
HWND hTrgEdit = GetDlgItem(hDlg, IDC_DATA_VALUE_TEXT);
int nTextLength = GetWindowTextLength(hSrcEdit);
int cchTextLength = nTextLength * 4 + 1;
int nBinLength;
szTextValue = new TCHAR[cchTextLength];
szBinValue = new TCHAR[nTextLength + 1];
pbBinValue = new BYTE[nTextLength + 1];
GetWindowText(hSrcEdit, szBinValue, nTextLength + 1);
CharUpper(szBinValue);
// Process the binary buffer and convert it to the binary data
nChangingEdit++;
nBinLength = BinTextToBinArray(szBinValue, pbBinValue);
if(nBinLength != -1)
{
BinArrayToCText(pbBinValue, nBinLength, szTextValue, cchTextLength);
SetWindowText(hTrgEdit, szTextValue);
}
else
SetWindowTextRc(hTrgEdit, IDS_CONVERSION_ERROR);
nChangingEdit--;
delete [] pbBinValue;
delete [] szBinValue;
delete [] szTextValue;
return TRUE;
}
//-----------------------------------------------------------------------------
// Dialog handlers
static int OnInitDialog(HWND hDlg, LPARAM lParam)
{
PFILE_FULL_EA_INFORMATION * ppEaItem = (PFILE_FULL_EA_INFORMATION *)lParam;
PFILE_FULL_EA_INFORMATION pEaItem = *ppEaItem;
HWND hWndChild;
// Configure the dialog
SetWindowLongPtr(hDlg, DWLP_USER, lParam);
SetDialogIcon(hDlg, IDI_FILE_TEST);
CenterWindowToParent(hDlg);
// Set the dialog title to "Insert" or to "Edit"
SetWindowTextRc(hDlg, pEaItem ? IDS_EDIT_EA_TITLE : IDS_INSERT_EA_TITLE);
// Set the name and value limit
hWndChild = GetDlgItem(hDlg, IDC_DATA_NAME);
if(hWndChild != NULL)
Edit_LimitText(hWndChild, (BYTE)-1);
// Fill the dialog
nChangingEdit++;
CheckDlgButton(hDlg, IDC_RADIO1, BST_CHECKED);
if(pEaItem != NULL)
{
if(hWndChild != NULL)
SetWindowTextA(hWndChild, pEaItem->EaName);
SetDlgItemCText(hDlg,
IDC_DATA_VALUE_TEXT,
(LPBYTE)pEaItem->EaName + pEaItem->EaNameLength + 1,
pEaItem->EaValueLength);
SetDlgItemBin(hDlg,
IDC_DATA_VALUE_BIN,
(LPBYTE)pEaItem->EaName + pEaItem->EaNameLength + 1,
pEaItem->EaValueLength);
}
UpdateDialog(hDlg);
nChangingEdit--;
return TRUE;
}
static BOOL OnSaveDialog(HWND hDlg)
{
PFILE_FULL_EA_INFORMATION * PtrReturnEa = (PFILE_FULL_EA_INFORMATION *)GetWindowLongPtr(hDlg, DWLP_USER);
PFILE_FULL_EA_INFORMATION NewEaItem = NULL;
PFILE_FULL_EA_INFORMATION OldEaItem = PtrReturnEa[0];
LPTSTR szBinBuffer = NULL;
HWND hWndName = GetDlgItem(hDlg, IDC_DATA_NAME);
HWND hWndValue = GetDlgItem(hDlg, IDC_DATA_VALUE_BIN);
int nTotalLength;
int nValueLength = GetWindowTextLength(hWndValue);
int nNameLength = 0;
if(hWndName != NULL)
{
// Retrieve the name length
nNameLength = GetWindowTextLength(hWndName);
if(nNameLength == 0)
{
// Don't accept empty name
MessageBoxRc(hDlg, IDS_ERROR, IDS_NO_EA_NAME);
SetFocus(hWndName);
return FALSE;
}
// Make sure that the name length is not bigger than 255
if(nNameLength > 255)
nNameLength = 255;
}
// Create new EA entry
nTotalLength = sizeof(FILE_FULL_EA_INFORMATION) + nNameLength + nValueLength + 2;
szBinBuffer = new TCHAR[nValueLength + 1];
NewEaItem = (PFILE_FULL_EA_INFORMATION)(new char[nTotalLength]);
// Initialize the EA entry
ZeroMemory(NewEaItem, nTotalLength);
// Fill the name and value
if(hWndName != NULL)
GetWindowTextA(hWndName, NewEaItem->EaName, nNameLength + 1);
NewEaItem->EaNameLength = (UCHAR)nNameLength;
GetWindowText(hWndValue, szBinBuffer, nValueLength + 1);
NewEaItem->EaValueLength = (USHORT)BinTextToBinArray(szBinBuffer,
(LPBYTE)NewEaItem->EaName + NewEaItem->EaNameLength + 1);
if(NewEaItem->EaValueLength == (USHORT)-1)
{
MessageBoxRc(hDlg, IDS_ERROR, IDS_CONVERSION_ERROR_MSG);
delete [] szBinBuffer;
delete [] NewEaItem;
return FALSE;
}
// Set the correct length of the EA item
NewEaItem->NextEntryOffset = GetEaEntrySize(NewEaItem);
// Replace the item
if(OldEaItem != NULL)
delete OldEaItem;
PtrReturnEa[0] = NewEaItem;
delete [] szBinBuffer;
return TRUE;
}
static int OnCommand(HWND hDlg, UINT nNotify, UINT nIDCtrl)
{
if(nNotify == BN_CLICKED)
{
switch(nIDCtrl)
{
case IDC_RADIO1:
UpdateDialog(hDlg);
SetFocus(GetDlgItem(hDlg, IDC_DATA_VALUE_TEXT));
return TRUE;
case IDC_RADIO2:
UpdateDialog(hDlg);
SetFocus(GetDlgItem(hDlg, IDC_DATA_VALUE_BIN));
return TRUE;
case IDOK:
if(OnSaveDialog(hDlg) == FALSE)
return TRUE;
// No break here !!
case IDCANCEL:
EndDialog(hDlg, nIDCtrl);
break;
}
}
if(nNotify == EN_CHANGE && nChangingEdit == 0)
{
switch(nIDCtrl)
{
case IDC_DATA_VALUE_BIN:
return UpdateEaValueText(hDlg);
case IDC_DATA_VALUE_TEXT:
return UpdateEaValueBin(hDlg);
}
}
return FALSE;
}
static INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Dialog initialization
if(uMsg == WM_INITDIALOG)
return OnInitDialog(hDlg, lParam);
if(uMsg == WM_COMMAND)
return OnCommand(hDlg, HIWORD(wParam), LOWORD(wParam));
return FALSE;
}
INT_PTR EaEditorDialog(HWND hParent, PFILE_FULL_EA_INFORMATION * ppEaItem)
{
return DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_EA_EDITOR), hParent, DialogProc, (LPARAM)ppEaItem);
}