win32 保存文件对话框的使用

实现

#include <afx.h>
#include <Shlobj.h>
#include <string>
#include <windows.h>
#include <iostream>
using namespace std;
int main(){
	setlocale(LC_ALL, "");
	CoInitialize(NULL);
	IFileSaveDialog* pOpenFileDlg = NULL;
	HRESULT hr = S_FALSE;
	hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_ALL, IID_IFileSaveDialog, (LPVOID*)&pOpenFileDlg);
	COMDLG_FILTERSPEC rgSpec[] ={{ L"JPG", L"*.jpg;*.jpeg" },{ L"BMP", L"*.bmp" },{ L"All", L"*.*" },};
	HRESULT SetFileTypes(UINT cFileTypes, const COMDLG_FILTERSPEC * rgFilterSpec);
	pOpenFileDlg->SetFileTypes(3, rgSpec);
	pOpenFileDlg->SetFileTypeIndex(3);
	if (SUCCEEDED(hr)){
		hr = pOpenFileDlg->Show(NULL);
		if (SUCCEEDED(hr)){
			//从对话框中获取文件名
			IShellItem* pItem;
			hr = pOpenFileDlg->GetResult(&pItem);
			if (SUCCEEDED(hr)){
				//结果成功,获取名字.
				LPWSTR filePath;
				LPWSTR fileName;
				hr = pItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &filePath);//获取文件的完整路径
				hr = pItem->GetDisplayName(SIGDN_NORMALDISPLAY, &fileName);///获取文件名
				if (SUCCEEDED(hr)){
					printf("%ws\n", filePath);
					printf("%ws\n", fileName);
					CoTaskMemFree(filePath);//释放内存
					CoTaskMemFree(fileName);//释放内存
				}
				pItem->Release();
			}
		}
		pOpenFileDlg->Release();//释放内存
	}
	CoUninitialize();

	return 0;
}

HOOK

IFileSaveDialog* g_myFileSaveDialog = NULL;
Hook hook_CoCreateInstance;
Hook hook_FileSaveDialog_show;
Hook hook_FileSaveDialog_GetResult;
class MyIShellItem : public IShellItem {
public:
	HRESULT STDMETHODCALLTYPE QueryInterface(
		/* [in] */ REFIID riid,
		/* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject) {
		return 0;
	}

	ULONG STDMETHODCALLTYPE AddRef(void) {
		return 0;
	}
	ULONG STDMETHODCALLTYPE Release(void) {
		return 0;
	}
	HRESULT STDMETHODCALLTYPE BindToHandler(
		/* [unique][in] */ __RPC__in_opt IBindCtx* pbc,
		/* [in] */ __RPC__in REFGUID bhid,
		/* [in] */ __RPC__in REFIID riid,
		/* [iid_is][out] */ __RPC__deref_out_opt void** ppv) {
		return FALSE;
	}

	HRESULT STDMETHODCALLTYPE GetParent(
		/* [out] */ __RPC__deref_out_opt IShellItem** ppsi) {
		return FALSE;
	}
	HRESULT STDMETHODCALLTYPE GetDisplayName(
		/* [in] */ SIGDN sigdnName,
		/* [annotation][string][out] */
		_Outptr_result_nullonfailure_  LPWSTR* ppszName) {
		///printf("GetDisplayName \n");
		LPWSTR lpPath = NULL;
		获取文件的完整路径
		if (SIGDN_DESKTOPABSOLUTEPARSING == sigdnName) {
			lpPath = (LPWSTR)CoTaskMemAlloc(30);
			memcpy(lpPath, L"c:\\log.txt", 22);
		}
		///获取文件名
		else if (SIGDN_NORMALDISPLAY == sigdnName) {
			lpPath = (LPWSTR)CoTaskMemAlloc(30);
			memcpy(lpPath, L"log.txt", 16);
		}
		*ppszName = lpPath;
		return TRUE;
	}
	HRESULT STDMETHODCALLTYPE GetAttributes(
		/* [in] */ SFGAOF sfgaoMask,
		/* [out] */ __RPC__out SFGAOF* psfgaoAttribs) {
		return FALSE;
	}
	HRESULT STDMETHODCALLTYPE Compare(
		/* [in] */ __RPC__in_opt IShellItem* psi,
		/* [in] */ SICHINTF hint,
		/* [out] */ __RPC__out int* piOrder) {
		return FALSE;
	}
};
//hr = pOpenFileDlg->GetResult(&pItem);
HRESULT _stdcall myFileSaveDialog_GetResult(PVOID obj, IShellItem** ppItem) {
	HRESULT rt;
	LPVOID func;

	if (obj == g_myFileSaveDialog) {
		*ppItem = new MyIShellItem();
		return TRUE;
	}
	else {
		func = hook_FileSaveDialog_GetResult.原函数地址;
		Hook_调用原函数开始(&hook_FileSaveDialog_GetResult);
		__asm {
			push ppItem
			push obj
			call dword ptr[func]
			mov dword ptr[rt], eax
		}
		Hook_调用原函数结束(&hook_FileSaveDialog_GetResult);
		return rt;
	}
}
//hr = pOpenFileDlg->Show(NULL);
HRESULT _stdcall myFileSaveDialog_show(PVOID obj, HWND hwnd) {
	HRESULT rt;
	LPVOID func;
	if (obj != g_myFileSaveDialog) {
		func = hook_FileSaveDialog_show.原函数地址;
		Hook_调用原函数开始(&hook_FileSaveDialog_show);
		__asm {
			push hwnd
			push obj
			call dword ptr[func]
			mov dword ptr[rt], eax
		}
		Hook_调用原函数结束(&hook_FileSaveDialog_show);
		return rt;
	}
	return TRUE;
}
// hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_ALL, IID_IFileSaveDialog, (LPVOID*)&pOpenFileDlg);
HRESULT _stdcall MyCoCreateInstance(_In_ REFCLSID rclsid, _In_opt_ LPUNKNOWN pUnkOuter, _In_ DWORD dwClsContext, _In_ REFIID riid, _COM_Outptr_ _At_(*ppv, _Post_readable_size_(_Inexpressible_(varies))) LPVOID  FAR* ppv) {
	HRESULT ret;
	DWORD obj;
	DWORD call;
	Hook_调用原函数开始(&hook_CoCreateInstance);
	ret = CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
	Hook_调用原函数结束(&hook_CoCreateInstance);
	if (CLSID_FileSaveDialog == rclsid && !g_myFileSaveDialog) {
		g_myFileSaveDialog = (IFileSaveDialog*)*ppv;

		// 001F3308 6A 00                push        0
		// 001F330A 50                   push        eax #g_myFileSaveDialog
		// 001F330B 8B 08                mov         ecx, dword ptr[eax]
		// 001F330D FF 51 0C             call        dword ptr[ecx + 0Ch]
		 //show
		obj = *(DWORD*)g_myFileSaveDialog;
		call = *(DWORD*)(obj + 0x0C);
		Hook_inHook(&hook_FileSaveDialog_show, (PVOID)call, &myFileSaveDialog_show);
		//GetResult
		call = *(DWORD*)(obj + 0x50);
		Hook_inHook(&hook_FileSaveDialog_GetResult, (PVOID)call, &myFileSaveDialog_GetResult);
		printf("FileSaveDialog已备份 %X\n", obj);
	}
	return ret;
}

void hook() {
	Hook_inHook(&hook_CoCreateInstance, CoCreateInstance, &MyCoCreateInstance);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值