0CCh Blog

获得使用打开保存对话框操作文件的记录

今天无意中看到了HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU这个键值的用途,虽然感觉没啥实际用途,但是也挺有趣的,于是写了个小程序读取它。这个键值的意义非常明确,就是记录打开保存对话框的最近操作的文件的PIDL。所以我们可以通过PIDL来获得文件路径,就这么简单,确实没啥特别的实际用途吧,就当娱乐了。枚举的效果如下:

20141117231005

代码也很简单:


#include "stdafx.h"
#include <atlbase.h>
#include <atlstr.h>
#include <Shlobj.h>
#include <locale.h>
#include <vector>

#pragma comment(lib, "shell32.lib")

const TCHAR mru_path[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSavePidlMRU");

void EnumMRUValue(HKEY subkey, std::vector &mru;_files)
{
ULONG i = 0, j = 0;
TCHAR value_name[MAX_PATH];
ULONG value_name_length = MAX_PATH;
UCHAR data_buffer[1024];
ULONG data_length = sizeof(data_buffer);
while (RegEnumValue(subkey, i++, value_name, &value;_name_length, 0, NULL, data_buffer, &data;_length) == ERROR_SUCCESS)
{
if (_tcscmp(value_name, TEXT("MRUListEx")) != 0) {
CComPtr malloc_ptr;
HRESULT hr = SHGetMalloc(&malloc;_ptr);
LPITEMIDLIST file_pidl = (LPITEMIDLIST)malloc_ptr->Alloc(sizeof(UCHAR) + data_length);

if (file_pidl) {
memcpy(file_pidl, data_buffer, data_length);
WCHAR file_path[MAX_PATH] = { 0 };
if (SHGetPathFromIDList(file_pidl, file_path)) {
mru_files.push_back(file_path);

}
malloc_ptr->Free(file_pidl);
}
}

value_name_length = MAX_PATH;
data_length = sizeof(data_buffer);
}
}

BOOL PrintMRUFiles()
{
HKEY subkey;
LSTATUS l = RegOpenKeyEx(HKEY_CURRENT_USER, mru_path, 0, KEY_READ, &subkey;);
if (l != ERROR_SUCCESS) {
return FALSE;
}
ULONG i = 0;
TCHAR key_name[MAX_PATH];
ULONG key_name_length = MAX_PATH;
while (RegEnumKeyEx(subkey, i++, key_name, &key;_name_length, 0, NULL, NULL, NULL) == ERROR_SUCCESS)
{
HKEY ext_key;
LSTATUS l = RegOpenKeyEx(subkey, key_name, 0, KEY_READ, &ext;_key);
if (l == ERROR_SUCCESS) {

std::vector mru_files;
EnumMRUValue(ext_key, mru_files);
if (mru_files.size() > 0) {
_tprintf(TEXT("Extension Name : %s\n"), key_name);
ULONG j = 0;
for (std::vector::iterator it = mru_files.begin(); it != mru_files.end(); ++it) {

WIN32_FILE_ATTRIBUTE_DATA attribute_data = { 0 };

if (GetFileAttributesEx(it->GetString(), GetFileExInfoStandard, &attribute;_data)) {
ULONGLONG file_size = ((ULONGLONG)attribute_data.nFileSizeHigh) << 32 | attribute_data.nFileSizeLow;
_tprintf(TEXT("\t %u %s % 11I64u KB] %s\n"), j++,
(attribute_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 ? TEXT("[FILE") : TEXT("[DIR "),
(file_size + 1023) / 1024,
it->GetString());
}
else {
_tprintf(TEXT("\t %u [ERROR_FILE_NOT_FOUND] %s\n"), j++,
it->GetString());
}

}
}

RegCloseKey(ext_key);
}

key_name_length = MAX_PATH;
}

RegCloseKey(subkey);
return TRUE;
}


int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL, "chs");
PrintMRUFiles();
return 0;
}