史萊姆論壇

返回   史萊姆論壇 > 教學文件資料庫 > 作業系統操作技術文件
忘記密碼?
論壇說明

歡迎您來到『史萊姆論壇』 ^___^

您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的!

請點擊這裡:『註冊成為我們的一份子!』

Google 提供的廣告


 
 
主題工具 顯示模式
舊 2003-12-11, 08:01 PM   #1
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設 小禮物,微軟"搜尋目標的實現」附帶三個小工具

一直使用VC++6.0,很希望自己實現一個插件能開啟包含VC中開啟文件的資料夾。以前用ShellExecuteEx實現過,但效果不理想,原因有1,同一個資料夾會開啟多個實例,2.目標文件在資料夾中不會被選。後來在網上發現可以通過執行explore /select <target folder>來完成上述功能,但還不夠理想,原因是,如果資料夾已被開啟,目標文件在資料夾中不會被選。

我看了不少有關Windows Shell的編程方面的書也沒有找到答案。

在Windows桌面上的圖示,右按下,選「內容」,按「搜尋目標」可以非常理想的完成上述功能。但是它是怎樣實現的呢?

先開啟內容對話視窗,在SoftICE下下萬能斷點hmemcpy, 經過幾次F12, 來到Shell32.dll中,記下其虛擬位址,用IDA開啟Shell32.dll:

.text:7FD04025 CreateShortcutPage proc near ; CODE XREF: sub_7FD05C24+159p
.text:7FD04025
.text:7FD04025 var_34 = PROPSHEETPAGEA ptr -34h
.text:7FD04025 var_4 = dword ptr -4
.text:7FD04025 arg_0 = dword ptr 8
.text:7FD04025 lpString2 = dword ptr 0Ch
.text:7FD04025 arg_8 = dword ptr 10h
.text:7FD04025 arg_C = dword ptr 14h
.text:7FD04025
.text:7FD04025 push ebp
.text:7FD04026 mov ebp, esp
.text:7FD04028 sub esp, 34h
.text:7FD0402B push esi
.text:7FD0402C push edi
.text:7FD0402D push [ebp+lpString2]
.text:7FD04030 call IsLnkFile
.text:7FD04035 test eax, eax
.text:7FD04037 jz loc_7FD040F6
.text:7FD0403D lea eax, [ebp+var_4]
.text:7FD04040 push eax
.text:7FD04041 push offset dword_7FCBCE50
.text:7FD04046 push 0
.text:7FD04048 call sub_7FCBCA41
.text:7FD0404D test eax, eax
.text:7FD0404F jl loc_7FD040F6
.text:7FD04055 push 220h ; uBytes
.text:7FD0405A push 40h ; uFlags
.text:7FD0405C call ds:LocalAlloc
.text:7FD04062 mov esi, eax
.text:7FD04064 test esi, esi
.text:7FD04066 jz loc_7FD040ED
.text:7FD0406C mov eax, ds:hModule
.text:7FD04071 push 104h ; iMaxLength
.text:7FD04076 push [ebp+lpString2] ; lpString2
.text:7FD04079 mov [ebp+var_34.hInstance], eax
.text:7FD0407C lea eax, [esi+18h]
.text:7FD0407F mov [ebp+var_34.dwSize], 30h
.text:7FD04086 push eax ; lpString1
.text:7FD04087 mov [ebp+var_34.dwFlags], 80h
.text:7FD0408E mov dword ptr [ebp+var_34.anonymous_0], 1040
.text:7FD04095 mov [ebp+var_34.pfnDlgProc], offset PropDlgProc 注意這裡!
.text:7FD0409C mov [ebp+var_34.pfnCallback], offset loc_7FD03FFF
.text:7FD040A3 mov [ebp+var_34.lParam], esi
.text:7FD040A6 call ds:lstrcpynA
.text:7FD040AC mov eax, [ebp+arg_0]
.text:7FD040AF or dword ptr [esi+14h], 0FFFFFFFFh
.text:7FD040B3 mov [esi], eax
.text:7FD040B5 mov eax, [ebp+var_4]
.text:7FD040B8 mov [esi+4], eax
.text:7FD040BB lea eax, [ebp+var_34]
.text:7FD040BE push eax ; LPCPROPSHEETPAGEA
.text:7FD040BF call ds:CreatePropertySheetPageA
.text:7FD040C5 mov edi, eax
.text:7FD040C7 test edi, edi
.text:7FD040C9 jz short loc_7FD040E6
.text:7FD040CB push [ebp+arg_C]
.text:7FD040CE push edi
.text:7FD040CF call [ebp+arg_8]
.text:7FD040D2 test eax, eax
.text:7FD040D4 jz short loc_7FD040DF
.text:7FD040D6 push 1
.text:7FD040D8 pop eax
.text:7FD040D9
.text:7FD040D9 loc_7FD040D9: ; CODE XREF: CreateShortcutPage+D3j
.text:7FD040D9 pop edi
.text:7FD040DA pop esi
.text:7FD040DB leave
.text:7FD040DC retn 10h
.text:7FD040DF ;
.text:7FD040DF
.text:7FD040DF loc_7FD040DF: ; CODE XREF: CreateShortcutPage+AFj
.text:7FD040DF push edi ; HPROPSHEETPAGE
.text:7FD040E0 call dsestroyPropertySheetPage
.text:7FD040E6
.text:7FD040E6 loc_7FD040E6: ; CODE XREF: CreateShortcutPage+A4j
.text:7FD040E6 push esi ; hMem
.text:7FD040E7 call ds:LocalFree
.text:7FD040ED
.text:7FD040ED loc_7FD040ED: ; CODE XREF: CreateShortcutPage+41j
.text:7FD040ED mov eax, [ebp+var_4]
.text:7FD040F0 push eax
.text:7FD040F1 mov ecx, [eax]
.text:7FD040F3 call dword ptr [ecx+8]
.text:7FD040F6
.text:7FD040F6 loc_7FD040F6: ; CODE XREF: CreateShortcutPage+12j
.text:7FD040F6 ; CreateShortcutPage+2Aj
.text:7FD040F6 xor eax, eax
.text:7FD040F8 jmp short loc_7FD040D9
.text:7FD040F8 CreateShortcutPage endp

經過整整4天的艱苦挖掘,得到了後面的來源碼。這些來源碼和作者(微軟)手裡的因該是完全等價的。說實在的,裡面有些東西是值得學習的。從中我們可以發現問題的關鍵在於SHDOCVW.DLL中的SHGetIDispatchForFolder這個未公開函數,我曾試著在google搜尋它,發現只有一個不能開啟的網站上有它。雖然我極其佩服微軟,但從這個例子中我們可以看出微軟的技術壟斷的痕跡。

為了幹這活,我還做了一個工具CLSIDSEE, 它可以從4個dword搜尋CLS_ID, ProgID...,用於破解COM程式碼非常有用。
用這些程式碼我還做了一個VC插件,實現開始提到的功能,我個人覺得非常有用。
用這些程式碼我還做了一個Shell擴展,將搜尋目標這個功能直接放到桌面圖示右按下的表單中,我也覺得非常有用。
這三個小工具我會放到CrackABC的FTP上。
int GetNumberOfSelected(HGLOBAL hMem)
{
int ret = 0;
int* pInt;

if ((pInt = (int*)GlobalLock(hMem)) != NULL) {
ret = *pInt;
GlobalUnlock(hMem);
}

return ret;
}

BOOL _7FD0276A(DWORD* vp, DWORD var)
{
if (var <= vp[0])
return SHELL32_25((BYTE*)vp + vp[1], (BYTE*)vp + vp[var + 2]);

return FALSE;
}

LPCITEMIDLIST GetPIDL(HGLOBAL hGlobal, int var)
{
LPVOID vp;

if ((vp = GlobalLock(hGlobal)) != NULL) {
LPCITEMIDLIST pidl = _7FD0276A(vp, var);
GlobalUnlock(hGlobal);
return pidl;
}

return NULL;
}

BOOL GetTargetInfo(HGLOBAL hGlobal, int var, char FilePath[MAX_PATH], WIN32_FIND_DATA* lpFindData)
{
LPCITEMIDLIST pidl;

PathName[0] = '\0';
if ((pidl = GetPIDL(hGlobal, var)) != NULL) {
if (SHGetPathFromIDList(pidl, FilePath)) {
if (lpFindData) {
if ((hFff = FindFirstFile(FilePath, lpFindData)) == INVALID_HANDLE_VALUE)
memset(lpFindData, 0, sizeof(WIN32_FIND_DATA));
else
CloseHandle(hFff);
}

SHELL32_155_FreePidl(pidl);
return TRUE;
}
else {
SHELL32_155_FreePidl(pidl);
return FALSE;
}
}

return FALSE;
}

int CreatePropDialog(p1, pfn, IDataObject* pDataObj)
{
FORMATETC formatetc;
STGMEDIUM medium;
PROPSHEETPAGE psp;
HLOCAL hLocal;
HGLOBAL hGlobal;
WIN32_FIND_DATA ffd;
HPROPSHEETPAGE hPsp;
char PathName[MAX_PATH];

BOOL var_4;
int var_8;

formatetc.lindex = -1;
formatetc.cfFormat = gcfFormat;
formatetc.ptd = 0;
formatetc.dwAspect = 1;
formatetc.tymed = TYMED_HGLOBAL;

var_4 = FALSE;
var_8 = 0;

if (FAILED(pDataObj->GetData(&formatetc, &medium)))
return FALSE;

PathName[0] = 0;
psp.hInstance = ghModule;
psp.dwSize = 952; //NOT sizeof(psp); !!!
psp.dwFlags = PSP_USECALLBACK; //0x80;
psp.pfnCallback = PropCallback;
var_2a0 = 1;
var_3a8 = 0;
var_34 = 0;
var_30 = 0;

hGlobal = medium.hGlobal;
if (hGlobal) {
hLocal = LocalAlloc(LPTR, GlobalSize(hGlobal));
if (hLocal)
memmove(hLocal, hGlobal, GlobalSize(hGlobal));
}
else
hLocal = NULL;

if (GetNumberOfSelected(hGlobal) == 1) { // else 7fd05dd5
if (GetTargetInfo(hGlobal, 0, &PathName, &ffd)) { // else 7fd05d9f
psp.pfnDlgProc = ConventionalDlgProc;
psp.pResource = MAKEINTRESOURCE(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY? 1044 : 1041);
if ((hPsp = CreatePropertySheetPage(&psp)) != NULL) { // else loc_7FD05D9F
if (pfn(hPsp, p1)) { // else loc_7FD05E07
var_4 = 1;
if (CreateShortcutPage(hGlobal, &PathName, pfn, p1))
var_8 = 2;
CreateVersionPage(&PathName, pfn, p1);
}
else // loc_7FD05E07
DestroyPropertySheetPage(hPsp);
}
}
}
else { // loc_7FD05DD5
psp.pResource = MAKEINTRESOURCE(1043);
psp.pfnDlgProc = MultiSelDlgProc;
if ((hPsp = CreatePropertySheetPage(&psp)) != NULL) { // else loc_7FD05D9F
if (pfn(hPsp, p1))
var_4 = 1;
else
DestroyPropertySheetPage(hPsp);
}
}

// loc_7FD05D9F
_7FCC6204(&medium);
if (!var_4 && hLocal)
LocalFree(hLocal);

return var_8;
}

BOOL IsLnkFile(char* PathName)
{
if (PathName)
return lstrcmpi(PathFindExtension(PathName), ".lnk") == 0;

return FALSE;
}


HRESULT CreateShellInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv)
{
CShellFactory* pCShellFactory;
HRESULT hr;

if (pUnknownOuter)
return CLASS_E_NOAGGREGATION;

pCShellFactory = new CShellFactory;

if (pCShellFactory == NULL)
return E_OUTOFMEMORY;

pCShellFactory->m_cRef = 1;
pCShellFactory->Init();

hr = pCShellFactory->CreateInstance(iid, ppv);

pCShellFactory->Release();

return hr;
}

typedef struct FindTargetData
{
HGLOBAL hGlobal; // 0
IShellLinkA* pIShellLink; // 4
int hDlgWnd; // 8
int dwc; // c
int dw10; // 10
int dw14; // 14
int dw18; // 18
char Path[MAX_PATH]; // 1c
};

BOOL CreateShortcutPage(HGLOBAL hGlobal, char PathName[MAX_MATH], pfn, p1)
{
PROPSHEETPAGE psp;
IShellLink* pIShellLink;
FindTargetData* pFtd;
HPROPSHEETPAGE hPsp;

if (IsLinkFile(PathName) &&
SUCCEEDED(CreateShellInstance(NULL, IID_IShellLink, &pIShellLink)))
{ // else loc_7FD040F6
pFtd = (FindTargetData*) LocalAlloc(LPTR, sizeof(FindTargetData));
if (pFtd != NULL) { // else loc_7FD040ED
psp.hInstance = ghModule;
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_USECALLBACK;
psp.pResource = MAKEINTRESOURCE(1040);
psp.pfnDlgProc = ShortcutDlgProc;
psp.pfnCallback = CallbackProc;
psp.lParam = pFtd;
lstrcpyn(pFtd->Path, PathName, MAX_PATH);
pFtd->dw14 = -1;
pFtd->hGlobal = hGlobal;
pFtd->pIShellLink = pIShellLink;
if ((hPsp = CreatePropertySheetPage(&psp)) != NULL) {
if (pfn(hPsp, p1))
return TRUE;
DestroyPropertySheetPage(hPsp);
}
LocalFree(pFtd);
}
pObj->Release();
}

return FALSE;
}

#define IDC_
#define IDC_Name 0x66 // 名稱
#define IDC_StartLocation 0x3002 // 起始位置
#define IDC_Target 0x3302 // 目標
#define IDC_TargetType 0x3303 // 目標類型
#define IDC_TargetLocation 0x3309 // 目標位置
#define IDC_Shortcut 0x3404 // 快捷鍵
#define IDC_FindTarget 0x3406 // 搜尋目標
#define IDC_ChangeIcon 0x3407 // 更改圖示
#define IDC_RunMode 0x3408 // 執行方式

BOOL CALLBACK ShortcutDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LPPROPSHEETPAGE psp;
FindTargetData* pFtd;
LPNMHDR pnmh;
LPHELPINFO lphi;

pFtd = GetWindowLong(hWnd, DWL_USER);

switch (uMsg)
{
case WM_INITDIALOG:
psp = (LPPROPSHEETPAGE)lParam;
pFtd = psp->lParam;
SetWindowLong(hWnd, DWL_USER, pFtd);
pFtd->hDlgWnd = hWnd;

SendDlgItemMessage(hWnd, 0x3302/*ID for 目標*/, WM_LIMITTEXT, MAX_PATH - 1, 0);
COMCTL32_384(GetDlgItem(hWnd, 0x3302), 1);
SendDlgItemMessage(hWnd, 0x3002/*ID for 起始位置*/, EM_LIMITTEXT, MAX_PATH - 1, 0);
COMCTL32_384(GetDlgItem(hWnd, 0x3002), 1);

SendDlgItemMessage(hWnd, 0x3404/*ID for 快捷鍵*/, 0x403, 0xf, 6);

FindTargetInit(pFtd, 0);
return TRUE;

case WM_NOTIFY:
// If the message handler is in a dialog box procedure, you must use
// the SetWindowLong function with DWL_MSGRESULT to set a return value.
pnmh = (LPNMHDR) lParam;
if (pnmh->code != -202) {
if (pnmh->code == -201)
SetWindowLong(hwnd, DWL_MSGRESULT, !_7FD03BDA(pFtd));
}
else if (FAILED(_7FD03A38(pFtd)))
SetWindowLong(hWnd, DWL_MSGRESULT, 2);

return TRUE;

case WM_HELP:
lphi = (LPHELPINFO) lParam;
// HELP_WM_HELP:
// Displays the topic for the control identified
// by the hWndMain parameter in a pop-up window.
// HelpData:
// Address of an array of double word pairs.
// The first double word in each pair is a control identifier,
// and the second is a context identifier for a topic.
// The array must be terminated by a pair of zeros {0,0}.
// If you do not want to add Help to a particular control,
// set its context identifier to -1.
WinHelp(lphi->hItemHandle, NULL, HELP_WM_HELP, &HelpData);
break;

case WM_CONTEXTMENU:
WinHelp(lParam, NULL, HELP_CONTEXTMENU, &HelpData);
break;

case WM_COMMAND:
switch (LOWORD(wParam))
{
case 3002: // 起始位置
case 3302: // 目標
case 3404: // 快捷鍵
if (HIWORD(wParam) == 0x300) {
SendMessage(GetParent(hWnd), 0x468, hWnd, 0);
pFtd->dw10 = 1;
}
return TRUE;

case 3406: // 搜尋目標
OnCmdFindTarget(pFtd);
return TRUE;

case 3407: // 更改圖示
if (OnCmdChangeIcon(pFtd))
pFtd->dw10 = TURE;
return TRUE;

case 3408: // 執行方式
if (HIWORD(wParam) == 1)
SendMessage(GetParent(hWnd), 0x468, hWnd, 0);
return TRUE;
}
return FALSE;

case 0x464:
SwitchToThisWindow(GetLastActivePopup(lParam), TRUE);
SetForegroundWindow(uMsg); // 奇怪!
break;
}

return FALSE;
}
int gdwShowCmds[] = {1, 7, 3};
void FindTargetInit(FindTargetData* pFtd, BOOL bFlag)
{
HRESULT hr;
OLECHAR wPath[MAX_PATH];
char Path[MAX_PATH];
char TargetPath[MAX_PATH];
char Msg[MAX_PATH];
SHFILEINFO ShellFileInfo;
SHDWORD ShDw;
WORD Hotkey;
int ShowCmd;
ITEMIDLIST* pidl;

IPersistFile* pIPersistFile;

if (!bFlag &&
SUCCEEDED(pFtd->pIShellLink->QueryInterface(IID_IPersistFile, &pIPersistFile))
{ // else loc_7FD032B3
SHELL32_163(wPath, &pFtd->dw18);
hr = pIPersistFile->Load(wPath, STGM_DIRECT);
pIPersistFile->Release();
if (FAILED(hr)) {
LoadString(ghModule, 4216/*ID for 不是有效的建立捷逕。*/, &Msg, MAX_PATH);
SetDlgItemText(pFtd->hDlgWnd, 0x3303/*ID for "目標類型"*/, Msg);
_7FD031BF(pFtd->hDlgWnd);
return;
}
}

//loc_7FD032B3
if (pFtd->pIShellLink->b7d & FILE_ATTRIBUTE_DIRECTORY) {
GetTargetIcon(pFtd, 0);
GetTargetName(pFtd->hGlobal, 0, &Msg);
SetDlgItemText(pFtd->hDlgWnd, 0x66/*ID for 圖示旁邊的名稱*/, &Msg);
EnableWindow(GetDlgItem(pFtd->hDlgWnd, 0x3012/*ID for*/), FALSE);
EnableWindow(GetDlgItem(pFtd->hDlgWnd, 0x3302/*ID for*/), FALSE);
EnableWindow(GetDlgItem(pFtd->hDlgWnd, 0x3002/*ID for*/), FALSE);
EnableWindow(GetDlgItem(pFtd->hDlgWnd, 0x3404/*ID for*/), FALSE);
EnableWindow(GetDlgItem(pFtd->hDlgWnd, 0x3408/*ID for*/), FALSE);
EnableWindow(GetDlgItem(pFtd->hDlgWnd, 0x3406/*ID for*/), FALSE);
EnableWindow(GetDlgItem(pFtd->hDlgWnd, 0x3407/*ID for*/), FALSE);
return;
} // goto loc_Return

GetTargetName(pFtd->hGlobal, 0, &Msg);
SetDlgItemText(pFtd->hDlgWnd, 0x66/*ID for 圖示旁邊的名稱*/, &Msg);

if (SUCCEEDED(hr = pFtd->pIShellLink->GetPath(&TargetPath, MAX_PATH, NULL, SLGP_RAWPATH)) || // else loc_7FD033C0
SUCCEEDED(hr = pFtd->pIShellLink->GetPath(&TargetPath, MAX_PATH, NULL, 0)) && hr != S_FALSE)
{// else loc_7FD035B7
pFtd->dwc = TRUE;
if (!SHGetFileInfo(TargetPath, 0, &ShellFileInfo, sizeof(SHFILEINFO), SHGFI_TYPENAME)) { // loc_7FD03424
ExpandEnvironmentStrings(TargetPath, Path, MAX_PATH);
SHGetFileInfo(Path, 0, ShellFileInfo, sizeof(SHFILEINFO), SHGFI_TYPENAME);
}
SetDlgItemText(pFtd->hDlgWnd, 0x3303/*ID for "目標類型"*/, ShellFileInfo.szTypeName);
lstrcpy(Msg, TargetPath);
PathRemoveFileSpec(Msg);
SetDlgItemText(pFtd->hDlgWnd, 0x3309/*ID for "目標位置"*/, PathFindFileName(Msg));
pFtd->pIShellLink->GetArguments(Msg, MAX_PATH);
_7FD030E9(TargetPath, Msg);
GetDlgItemText(pFtd->hDlgWnd, 0x3302/*ID for "目標"*/, Msg, MAX_PATH);
if (lstrcmp(TargetPath, Msg))
// loc_7FD034C0
SetDlgItemText(pFtd->hDlgWnd, 0x3302/*ID for "目標"*/, TargetPath);
}
else { // loc_7FD035B7
pFtd->dwc = FALSE;
EnableWindow(GetDlgItem(pFtd->hDlgWnd, 0x3302/*ID for*/), FALSE);
EnableWindow(GetDlgItem(pFtd->hDlgWnd, 0x3002/*ID for*/), FALSE);
pFtd->pIShellLink->GetIDList(&pidl);
if (pidl) { // else loc_7FD034D1
SHELL32_15(pidl, &TargetPath);
SHELL32_17(pidl);
SHELL32_186(0, pidl, &Msg, 1);
SHELL32_155_FreePidl(pidl);
SetDlgItemText(pFtd->hDlgWnd, 0x3309, Msg);
SetDlgItemText(pFtd->hDlgWnd, 0x3303, TargetPath);

// optimized as jmp loc_7FD034C0
SetDlgItemText(pFtd->hDlgWnd, 0x3302/*ID for "目標"*/, TargetPath);
}
}

// loc_7FD034D1
if (!bFlag) { // else loc_Return
pFtd->pIShellLink->GetWorkingDirectory(Msg, MAX_PATH);
_7FD03173(pFtd->hDlgWnd, 0x3002, Msg);
pFtd->pIShellLink->GetHotkey(&Hotkey);
SendDlgItemMessage(pFtd->hDlgWnd, 0x3404/*ID for 快捷鍵*/, 0x401, (WPARAM)Hotkey, 0);

for (uID = 0x1034; /*ID for 一般視窗*/ uID <= 0x1036; uID++) {
LoadString(ghModule, uID, Msg, MAX_PATH);
SendDlgItemMessage(pFtd->hDlgWnd, 0x3408, CB_ADDSTRING, 0, (LPARAM)&Msg);
uID++;
}
pFtd->pIShellLink->GetShowCmd(&ShowCmd);

for (int i = 0; i < 3; i++)
if (gdwShowCmd[i] == ShowCmd) break;

if (i == 3) i = 0;

SendDlgItemMessage(pFtd->hDlgWnd, 0x3408, CB_SETCURSEL, 0, 0);
GetTargetIcon(pFtd, 0);
}
}

HRESULT GetSHGetIDispatchForFolderFunc(ITEMIDLIST* pidl, IWebBrowserApp* ppIWebBrowserApp)
{
if (ghSHDOCVW == NULL)
ghSHDOCVW = LoadLibrary("SHDOCVW.DLL");

if (ghSHDOCVW == NULL)
return E_FAIL;

if (gpfSHGetIDispatchForFolder == NULL) {
gpfSHGetIDispatchForFolder = GetProcAddress(ghModule, "SHGetIDispatchForFolder");
if (gpfSHGetIDispatchForFolder == NULL)
return E_FAIL;
}

return gpfSHGetIDispatchForFolder(pidl, ppIWebBrowserApp);
}

HRESULT GetShellFolderViewDual(ITEMIDLIST* pidl, IShellFolderViewDual** ppIShellFolderViewDual)
{
IWebBrowserApp* pIWebBrowserApp;
IDispatch* pDoc;
HWND hWnd;
HRESULT hr;

*ppIShellFolderViewDual = NULL;

if (SUCCEEDED(hr = GetSHGetIDispatchForFolderFunc(pidl, &pIWebBrowserApp)) {
if (SUCCEEDED(pIWebBrowserApp->get_HWND(&hWnd)) {
SetForegroundWindow(hWnd);
ShowWindow(hWnd, SW_SHOWNORMAL);
}
if (SUCCEEDED(hr = pIWebBrowserApp->get_Document(&pDoc)) {
pDoc->QueryInterface(IID_IShellFolderViewDual, ppIShellFolderViewDual);
pDoc->Release();
}

pIWebBrowserApp->Release();
}

return hr;
}

ITEMIDLIST* SHELL32_16_GetFilePidl(ITEMIDLIST* pidl)
{
ITEMIDLIST* pIdlFile = pidl;
USHORT cb;

if (pIdlFile) {
while (cb = pidl->mkid.cb) {
pIdlFile = pidl;
pidl = (ITEMIDLIST*)((BYTE*)pidl + cb);
}
}

return pIdlFile;
}

int SHELL32_152_GetPidlSize(ITEMIDLIST* pidl)
{
int sz = 0;
USHORT cb;

if (pidl) {
sz = 2;
while (cb = pidl->mkid.cb) {
sz += cb;
pidl = (ITEMIDLIST*)((BYTE*)pidl + cb);
}
}

return sz;
}

SAFEARRAY* CreateSaveArray(VARTYPE vt, long lLbound, unsigned int cElements)
{
if (ghOleAut32 == NULL)
LoadLibrary("OLEAUT32.DLL");

if (ghOleAut32) {
if (pfnSafeArrayCreateVector == NULL)
pfnSafeArrayCreateVector = GetProcAddress(ghOleAut32, "SafeArrayCreateVector");

if (pfnSafeArrayCreateVector != NULL)
return pfnSafeArrayCreateVector(vt, lLbound, cElements);
}

return NULL;
}

SAFEARRAY* AllocSafeArrayForPidl(ITEMIDLIST* pidl, int sz)
{
SAFEARRAY* parray;

if (pidl && sz) {
parray = CreateSaveArray(VT_UI1, 0, sz);
if (parray)
memcpy(parray->pvData, pidl, sz);
return parray;
}

return NULL;
}

BOOL SetVariantArg(VARIANTARG* pVariantArg, ITEMIDLIST* pidl)
{
SAFEARRAY* parray;

if ((parray = AllocSafeArrayForPidl(pidl, SHELL32_153_GetPidlSize(pidl))) != NULL) {
memset(pVariantArg, sizeof(VARIANTARG));
pVariantArg->vt = VT_ARRAY | VT_UI1);
pVariantArg->parray = parray;
return TRUE;
}

return FALSE;
}

HRESULT ClearVariantArg(VARIANTARG* pVariantArg)
{
if (ghOleAut32 == NULL)
LoadLibrary("OLEAUT32.DLL");

if (ghOleAut32) {
if (pfnVariantClear == NULL)
pfnVariantClear = GetProcAddress(ghOleAut32, "VariantClear");

if (pfnVariantClear != NULL)
return pfnVariantClear(pVariantArg);
}

return E_FAIL;
}

HRESULT SelectItem(IShellFolderViewDual* pIShellFolderViewDual, ITEMIDLIST* pidl, int dwFlags)
{
HRESULT hr = E_FAIL;
VARIANTARG VariantArg;

if (SetVariantArg(&VariantArg, pidl)) {
hr = pIShellFolderViewDual->SelectItem(&VariantArg, dwFlags);
ClearVariantArg(&VariantArg);
}

return hr;
}

void OnCmdFindTarget(FindTargetData* pFtd)
{
ITEMIDLIST* pidl, *pidl2;
USHORT cb;
IShellFolderViewDual* pIShellFolderViewDual;
int var_8;

if (pFtd->pIShellLink->Resolve(pFtd->hDlgWnd, 0) == NOERROR) { // 0? 奇怪!
FindTargetInit(pFtd, TRUE);
pFtd->pIShellLink->GetIDList(&pidl);
if (pidl == NULL) return;

var_10 = 0x1000000;
if (FAILED(_7FCD197A(pidl, 0, 0, 0, &var_10)) {
Msg(ghModule, pFtd->hDlgWnd, 6456/*ID for "找不到 %1!ls!"*/, NULL, 0x10030);
SHELL32_155_FreePidl(pidl);
return;
}

// Get the pidl for the item in its folder
pidl2 = SHELL32_16_GetFilePidl(pidl);

if (pidl2 != pidl)
cb = pidl2->mkid.cb, pidl2->mkid.cb = 0;
else
cb = 0;

EnterCriticalSec();
if ((tmp = _7FCB255B(0, 0x10, 0)) != 0) {
tmp = SHELL32_21(pidl, tmp);
var_8 = 1;
if (!tmp) var_8 = 0;
}
else
var_8 = 0;
LeaveCriticalSec();

if (var_8 == 0 && cb != 0) { // else loc_7FD03761
DoOleInitialize();
if (SUCCEEDED(GetShellFolderViewDual(pidl, &pIShellFolderViewDual)) {
pidl2->mkid.cb = cb;

// 0 Deselect the item.
// 1 Select the item.
// 3 Put the item in edit mode.
// 4 Deselect all but the specified item.
// 8 Ensure the item is displayed in the view.
// 0x10 Give the item the focus.
SelectItem(pIShellFolderViewDual, pidl2, 0x1d);
pIShellFolderViewDual->Release();
}
}
else { // loc_7FD03761, target is on the desktop
HWND hwnd;
// 6457: 文件位於桌面上。要找到它,請用滑鼠右鍵按下
// 工作列的空白區域,然後按下「最小化所有視窗
Msg(ghModule, pFtd->hDlgWnd, 6457, NULL, 0);
if ((hwnd = FindWindow("Progman", NULL)) != NULL)
PostMessage(pFtd->hDlgWnd, 0x464, 0, hwnd);
}

SHELL32_155_FreePidl(pidl);
return;
}
}
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次
 



發表規則
不可以發文
不可以回覆主題
不可以上傳附加檔案
不可以編輯您的文章

論壇啟用 BB 語法
論壇啟用 表情符號
論壇啟用 [IMG] 語法
論壇禁用 HTML 語法
Trackbacks are 禁用
Pingbacks are 禁用
Refbacks are 禁用


所有時間均為台北時間。現在的時間是 01:19 PM


Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2024, Jelsoft Enterprises Ltd.


SEO by vBSEO 3.6.1