page06ntfileinfo.cpp
来自「This ZIP archive includes the sources (a」· C++ 代码 · 共 1,751 行 · 第 1/5 页
CPP
1,751 行
pliValue->LowPart = (ULONG)StrToInt(szItemText + 1, &szItemText, 16);
}
else
{
pliValue->HighPart = 0;
pliValue->LowPart = ulValue;
}
return (*szItemText == 0) ? ERROR_SUCCESS : ERROR_BAD_FORMAT;
}
case TYPE_FRI_NAME:
{
PFILE_RENAME_INFORMATION FileInfo;
// We have to take the whole structure and get the length
// (the name must not be zero terminated)
FileInfo = (PFILE_RENAME_INFORMATION)
(pMember->pDataPtr - FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName));
FileInfo->FileNameLength = (ULONG)(wcslen(szItemText) * sizeof(WCHAR));
memcpy(FileInfo->FileName, szItemText, FileInfo->FileNameLength);
return ERROR_SUCCESS;
}
}
return ERROR_NOT_SUPPORTED;
}
static HTREEITEM InsertTreeItemByDataType(
HWND hTreeView,
HTREEITEM hParentItem,
TStructMember * pMember,
PBYTE pDataPtr)
{
TStructMember * pMemberInfo = new TStructMember;
HTREEITEM hNewItem = NULL;
TCHAR szItemText[1024] = _T("");
// Fill the item data structure
pMemberInfo->szMemberName = pMember->szMemberName;
pMemberInfo->nDataType = pMember->nDataType;
pMemberInfo->nMemberSize = pMember->nMemberSize;
pMemberInfo->pDataPtr = pDataPtr;
// Get the item text
if(DataToItemText(pMemberInfo, szItemText, _tsize(szItemText), TRUE) == ERROR_SUCCESS)
hNewItem = InsertTreeItem(hTreeView, hParentItem, szItemText, pMemberInfo);
return hNewItem;
}
static int GetStructLength(TStructMember * pMember)
{
int nStructLength = 0;
// We don't need recursion here; structure members in structures
// have also their size present, so we just add it
for(; pMember->szMemberName != NULL; pMember++)
nStructLength += pMember->nMemberSize;
// If the structure size is greater than 4 bytes,
// we have to align it to 8-byte boundary
if(nStructLength > 0x04)
nStructLength = ALIGN_INT64(nStructLength);
return nStructLength;
}
static int ReloadTreeViewItems(HWND hDlg, HWND hTreeView, HTREEITEM hParentItem)
{
TStructMember * pMemberInfo;
HTREEITEM hItem = TreeView_GetNextItem(hTreeView, hParentItem, TVGN_CHILD);
TVITEM tvi;
TCHAR szItemText[1024];
ZeroMemory(&tvi, sizeof(TVITEM));
// Process all items at the same level
while(hItem != NULL)
{
// Retrieve data struct associated with treeview item
tvi.mask = TVIF_PARAM;
tvi.hItem = hItem;
tvi.lParam = 0;
TreeView_GetItem(hTreeView, &tvi);
pMemberInfo = (TStructMember *)tvi.lParam;
// If any structure associated, get its text
if(pMemberInfo != NULL)
{
// Get the item text
if(DataToItemText(pMemberInfo, szItemText, _tsize(szItemText), TRUE) == ERROR_SUCCESS)
{
tvi.mask = TVIF_TEXT;
tvi.pszText = szItemText;
TreeView_SetItem(hTreeView, &tvi);
}
}
// If the tree view item has a subitem, we have to recursively
// reload subtree too
if(TreeView_GetNextItem(hTreeView, hItem, TVGN_CHILD) != NULL)
ReloadTreeViewItems(hDlg, hTreeView, hItem);
// And finally, move to the next item at the same level
hItem = TreeView_GetNextItem(hTreeView, hItem, TVGN_NEXT);
}
return TRUE;
}
static int FillStructureMembers(
HWND hTreeView,
HTREEITEM hParentItem,
TStructMember * pMembers,
LPBYTE pbData)
{
int nTotalLength = 0; // Length, in bytes, of the structure member
for(; pMembers->szMemberName != NULL; pMembers++)
{
int nDataLength = 0;
if(pMembers->nDataType == TYPE_STRUCT)
{
HTREEITEM hSubItem;
assert(pMembers->pSubItems != NULL);
hSubItem = InsertTreeItem(hTreeView, hParentItem, pMembers->szMemberName, NULL);
nDataLength = FillStructureMembers(hTreeView, hSubItem, pMembers->pSubItems, pbData);
}
else
{
InsertTreeItemByDataType(hTreeView, hParentItem, pMembers, pbData);
nDataLength = pMembers->nMemberSize;
}
// Move the data pointer and total length by the item size
nTotalLength += nDataLength;
pbData += nDataLength;
}
// If the structure size is greater than 4 bytes,
// we have to align it to 8-byte boundary
if(nTotalLength > 0x04)
nTotalLength = ALIGN_INT64(nTotalLength);
// At the end, we have to round the structure size up to 8-byte boundary
TreeView_Expand(hTreeView, hParentItem, TVE_EXPAND);
return nTotalLength;
}
// This function fills a variable length structure
// The data structure must contain "ULONG NextEntryOffset"
// as its very first member
static int FillVarLengthStructMembers(
HWND hTreeView,
HTREEITEM hParentItem,
TStructMember * pMembers,
LPBYTE pbData)
{
HTREEITEM hItem;
TCHAR szItemName[128];
ULONG NextEntryOffset;
int nStructLength = 0;
int nDataLength = 0;
int nIndex = 0;
// Insert infos about the streams
do
{
NextEntryOffset = *(PULONG)pbData;
_stprintf(szItemName, _T("[%u]"), nIndex++);
hItem = InsertTreeItem(hTreeView, hParentItem, szItemName, pbData);
nStructLength = FillStructureMembers(hTreeView, hItem, pMembers, pbData);
// Move to the next structure by simply adding the NextEntryOffset
// to the current pointer. Also add NextEntryOffset to data size
nDataLength += (NextEntryOffset != 0) ? NextEntryOffset : nStructLength;
pbData += NextEntryOffset;
}
while(NextEntryOffset != 0);
// At the end, we have to round the structure size up to 8-byte boundary
// Return the total length of the stream info
TreeView_Expand(hTreeView, hParentItem, TVE_EXPAND);
return nDataLength;
}
static int FillDialogWithFileInfo(HWND hDlg, FILE_INFORMATION_CLASS FileInfoClass)
{
TPropSheetData * pData = (TPropSheetData *)GetWindowLongPtr(hDlg, DWLP_USER);
TFileInfoData * pFileInfoData;
HTREEITEM hRootItem = NULL;
HWND hTreeView = GetDlgItem(hDlg, IDC_FILE_INFO);
HWND hComment = GetDlgItem(hDlg, IDC_COMMENT);
UINT nInputLength = 0;
BOOL bEnable = FALSE;
BOOL bShowTreeView = FALSE;
int nIndex = (int)FileInfoClass - 1;
// Delete all items in the tree view
TreeView_DeleteAllItems(hTreeView);
// Fill the tree view.
// For some structures (like FILE_STREAM_INFORMATION),
// we have to do it manually, because our data struct description
// don't allow us to process the variable structs following each other
pFileInfoData = &FileInfoData[nIndex];
if(pFileInfoData->szStructName != NULL)
{
hRootItem = InsertTreeItem(hTreeView, TVI_ROOT, pFileInfoData->szStructName, NULL);
if(hRootItem != NULL && pFileInfoData->pStructMembers != NULL)
{
// Chained structures, like FILE_DIRECTORY_INFORMATION,
// require different approach.
if(pFileInfoData->bIsChain == FALSE)
{
nInputLength = FillStructureMembers(hTreeView,
hRootItem,
pFileInfoData->pStructMembers,
pData->pbFileInfoBuff);
}
else
{
nInputLength = FillVarLengthStructMembers(hTreeView,
hRootItem,
pFileInfoData->pStructMembers,
pData->pbFileInfoBuff);
}
// Expand all subitems
bShowTreeView = TRUE;
bEnable = TRUE;
}
}
// Enable/disable input length and setinfo button
EnableDlgItems(hDlg, bEnable, IDC_INPUT_LENGTH_TITLE,
IDC_INPUT_LENGTH,
IDC_DEFAULT,
0);
// Enable/disable the "SetInfo" button
if(bEnable)
bEnable = IsHandleValid(pData->hFile);
EnableDlgItems(hDlg, bEnable, IDC_QUERYINFO, IDC_QUERYDIR, IDC_SETINFO, 0);
// Show/hide the tree view
if(bShowTreeView != IsWindowVisible(hTreeView))
{
ShowWindow(hTreeView, bShowTreeView ? SW_SHOW : SW_HIDE);
ShowWindow(hComment, bShowTreeView ? SW_HIDE : SW_SHOW);
}
return nInputLength;
}
static void EnableExitButton(HWND hDlg, BOOL bEnable)
{
HWND hCancelButton = GetDlgItem(GetParent(hDlg), IDCANCEL);
// Initialize the buttons
// Hide "OK" button and change "Cancel" to "Exit"
if(hCancelButton != NULL)
EnableWindow(hCancelButton, bEnable);
g_bDisableDialogDispatch = !bEnable;
}
static void UpdateDialog(HWND hDlg)
{
TPropSheetData * pData = (TPropSheetData *)GetWindowLongPtr(hDlg, DWLP_USER);
BOOL bEnable = FALSE;
// Controls on the dialog will be enabled only if the
// handle is valid and it is a NT handle
if(IsHandleValid(pData->hFile))
bEnable = TRUE;
EnableDlgItems(hDlg, bEnable, IDC_QUERYINFO, IDC_QUERYDIR, IDC_SETINFO, 0);
}
//-----------------------------------------------------------------------------
// Message handlers
static int OnInitDialog(HWND hDlg, LPARAM lParam)
{
FILE_INFORMATION_CLASS InitialFileInfo = FileBasicInformation;
TPropSheetData * pData;
PROPSHEETPAGE * pPage = (PROPSHEETPAGE *)lParam;
HWND hCombo = GetDlgItem(hDlg, IDC_FILE_INFO_CLASS);
int nInputLength;
// Allocate the buffer for file information class.
// Hopefully the struct size will never exceed 32 KB
pData = (TPropSheetData *)pPage->lParam;
ZeroMemory(pData->pbFileInfoBuff, pData->cbFileInfoBuff);
// Initialize the dialog
SetWindowLongPtr(hDlg, DWLP_USER, (LONG)pPage->lParam);
// Fill the combo box with names of file information classes
for(int i = 0; FileInfoData[i].szFileInfoClass != NULL; i++)
ComboBox_AddString(hCombo, FileInfoData[i].szFileInfoClass);
ComboBox_SetCurSel(hCombo, (int)InitialFileInfo - 1);
// Initialize tree view with structure for current
// file information class
nInputLength = FillDialogWithFileInfo(hDlg, InitialFileInfo);
SetDlgItemInt(hDlg, IDC_INPUT_LENGTH, nInputLength, FALSE);
UpdateDialog(hDlg);
return TRUE;
}
// Posted when the item label has been edited.
// We will fix the tree item to contain "Name: Value" text
static int OnReloadItems(HWND hDlg, HWND hTreeView, HTREEITEM hTreeItem)
{
// If the treeview edit process has not been completed yet,
// post the processing again
if(TreeView_GetEditControl(hTreeView) != NULL)
{
PostMessage(hDlg, WM_RELOADITEMS, (WPARAM)hTreeView, (LPARAM)hTreeItem);
return TRUE;
}
ReloadTreeViewItems(hDlg, hTreeView, hTreeItem);
return TRUE;
}
static int OnSetActive(HWND hDlg)
{
UpdateDialog(hDlg);
return TRUE;
}
static int OnBeginLabelEdit(HWND hDlg, NMTVDISPINFO * pTVDispInfo)
{
FILE_INFORMATION_CLASS FileInfoClass;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?