ReactOS 0.4.15-dev-7842-g558ab78
shlextdbg.cpp File Reference
#include <windows.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlstr.h>
#include <atlsimpcoll.h>
#include <conio.h>
#include <shellutils.h>
#include <shlwapi_undoc.h>
Include dependency graph for shlextdbg.cpp:

Go to the source code of this file.

Classes

struct  ExplorerInstance
 

Enumerations

enum  WaitType {
  Wait_None , Wait_Infinite , Wait_OpenWindows , Wait_Input ,
  Wait_ExplorerInstance
}
 

Functions

static void PrintHelp (PCWSTR ExtraLine=NULL)
 
static LONG StrToNum (PCWSTR in)
 
static int ErrMsg (int Error)
 
template<class T >
static bool CLSIDPrefix (T &String, CLSID &Clsid)
 
static HRESULT GetUIObjectOfAbsolute (LPCITEMIDLIST pidl, REFIID riid, void **ppv)
 
static HRESULT CreateShellItemFromParse (PCWSTR Path, IShellItem **ppSI)
 
static void GetAssocClass (LPCWSTR Path, LPCITEMIDLIST pidl, HKEY &hKey)
 
static void DumpBytes (const void *Data, SIZE_T cb)
 
static HRESULT GetCommandString (IContextMenu &CM, UINT Id, UINT Type, LPWSTR buf, UINT cchMax)
 
static void DumpMenu (HMENU hMenu, UINT IdOffset, IContextMenu *pCM, BOOL FakeInit, UINT Indent)
 
static int SHGFI (PCWSTR Path)
 
static HRESULT AssocQ (int argc, WCHAR **argv)
 
HRESULT CreateIDataObject (CComHeapPtr< ITEMIDLIST > &pidl, CComPtr< IDataObject > &dataObject, PCWSTR FileName)
 
HRESULT LoadAndInitialize (REFIID riid, LPVOID *ppv)
 
BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam)
 
void WaitWindows ()
 
static void Wait ()
 
static BOOL CALLBACK cb_AddPage (HPROPSHEETPAGE page, LPARAM lParam)
 
static bool isCmdWithArg (int argc, WCHAR **argv, int &n, PCWSTR check, PCWSTR &arg)
 
static bool isCmd (int argc, WCHAR **argv, int n, PCWSTR check)
 
int wmain (int argc, WCHAR **argv)
 

Variables

CLSID g_CLSID = { 0 }
 
CStringW g_DLL
 
CStringW g_ShellExtInit
 
bool g_bIShellPropSheetExt = false
 
CStringA g_ContextMenu
 
WaitType g_Wait = Wait_ExplorerInstance
 
CSimpleArray< HWNDg_Windows
 
HWND g_ConsoleWindow
 
ExplorerInstance g_EI
 
CSimpleArray< HPROPSHEETPAGEg_Pages
 

Enumeration Type Documentation

◆ WaitType

Enumerator
Wait_None 
Wait_Infinite 
Wait_OpenWindows 
Wait_Input 
Wait_ExplorerInstance 

Definition at line 385 of file shlextdbg.cpp.

386{
387 Wait_None,
392};
@ Wait_OpenWindows
Definition: shlextdbg.cpp:389
@ Wait_Input
Definition: shlextdbg.cpp:390
@ Wait_Infinite
Definition: shlextdbg.cpp:388
@ Wait_ExplorerInstance
Definition: shlextdbg.cpp:391
@ Wait_None
Definition: shlextdbg.cpp:387

Function Documentation

◆ AssocQ()

static HRESULT AssocQ ( int  argc,
WCHAR **  argv 
)
static

Definition at line 281 of file shlextdbg.cpp.

282{
283 UINT qtype = StrToNum(argv[2]);
284 ASSOCF iflags = StrToNum(argv[3]);
285 ASSOCF qflags = StrToNum(argv[4]);
286 PCWSTR extra = (argc > 6 && *argv[6]) ? argv[6] : NULL;
287 WCHAR buf[MAX_PATH * 2];
288 DWORD maxSize = (argc > 7 && *argv[7]) ? StrToNum(argv[7]) : sizeof(buf);
289
290 HRESULT hr;
292 PWSTR path = argv[0];
293 if (*path)
294 {
295 CLSID clsid, *pclsid = NULL;
296 if (CLSIDPrefix(path, clsid))
297 pclsid = &clsid;
300 {
301 hr = si->BindToHandler(NULL, pclsid ? *pclsid : BHID_AssociationArray, IID_PPV_ARG(IQueryAssociations, &qa));
302 if (FAILED(hr) && !pclsid)
303 hr = si->BindToHandler(NULL, BHID_SFUIObject, IID_PPV_ARG(IQueryAssociations, &qa));
304 }
305 }
306 else
307 {
308 hr = AssocCreate(CLSID_QueryAssociations, IID_PPV_ARG(IQueryAssociations, &qa));
309 }
310 if (FAILED(hr))
311 return ErrMsg(hr);
312 hr = qa->Init(iflags, argv[5], NULL, NULL);
313 if (FAILED(hr))
314 return ErrMsg(hr);
315
316 DWORD size = maxSize;
317 if (!wcsicmp(argv[1], L"string"))
318 {
319 if (!wcsicmp(argv[2], L"COMMAND"))
320 qtype = ASSOCSTR_COMMAND;
321 if (!wcsicmp(argv[2], L"EXECUTABLE"))
322 qtype = ASSOCSTR_EXECUTABLE;
323 if (!wcsicmp(argv[2], L"FRIENDLYDOCNAME") || !wcsicmp(argv[2], L"FriendlyTypeName"))
325 if (!wcsicmp(argv[2], L"DEFAULTICON"))
326 qtype = ASSOCSTR_DEFAULTICON;
327
328 buf[0] = UNICODE_NULL;
329 size /= sizeof(buf[0]); // Convert to number of characters
330 hr = qa->GetString(qflags, (ASSOCSTR)qtype, extra, buf, &size);
331 size *= sizeof(buf[0]); // Convert back to bytes
332 if (SUCCEEDED(hr) ||
334 {
335 wprintf(L"0x%.8X: %s\n", hr, buf);
336 }
337 else
338 {
339 wprintf(size != maxSize ? L"%u " : L"", size);
340 ErrMsg(hr);
341 }
342 }
343 else if (!wcsicmp(argv[1], L"data"))
344 {
345 if (!wcsicmp(argv[2], L"EDITFLAGS"))
346 qtype = ASSOCDATA_EDITFLAGS;
347 if (!wcsicmp(argv[2], L"VALUE"))
348 qtype = ASSOCDATA_VALUE;
349
350 hr = qa->GetData(qflags, (ASSOCDATA)qtype, extra, buf, &size);
351 if (SUCCEEDED(hr))
352 {
353 wprintf(L"0x%.8X: %u byte(s) ", hr, size);
354 DumpBytes(buf, min(size, maxSize));
355 }
356 else
357 {
358 wprintf(size != maxSize ? L"%u " : L"", size);
359 ErrMsg(hr);
360 }
361 }
362 else if (!wcsicmp(argv[1], L"key"))
363 {
364 HKEY hKey = NULL;
365 hr = qa->GetKey(qflags, (ASSOCKEY)qtype, extra, &hKey);
366 if (SUCCEEDED(hr))
367 {
368 wprintf(L"0x%.8X: hKey %p\n", hr, hKey);
369 RegQueryValueExW(hKey, L"shlextdbg", 0, NULL, NULL, NULL); // Filter by this in Process Monitor
371 }
372 else
373 {
374 ErrMsg(hr);
375 }
376 }
377 else
378 {
379 PrintHelp(L"Unknown query");
381 }
382 return hr;
383}
static int argc
Definition: ServiceArgs.c:12
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define NULL
Definition: types.h:112
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define MAX_PATH
Definition: compat.h:34
#define wcsicmp
Definition: compat.h:15
HRESULT WINAPI AssocCreate(CLSID clsid, REFIID refiid, void **lpInterface)
Definition: assoc.c:98
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
@ extra
Definition: id3.c:95
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
void PrintHelp()
Definition: appwiz.c:21
#define min(a, b)
Definition: monoChain.cc:55
#define argv
Definition: mplay32.c:18
REFCLSID clsid
Definition: msctf.c:82
unsigned int UINT
Definition: ndis.h:50
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
static bool CLSIDPrefix(T &String, CLSID &Clsid)
Definition: shlextdbg.cpp:89
static LONG StrToNum(PCWSTR in)
Definition: shlextdbg.cpp:64
static void DumpBytes(const void *Data, SIZE_T cb)
Definition: shlextdbg.cpp:166
static HRESULT CreateShellItemFromParse(PCWSTR Path, IShellItem **ppSI)
Definition: shlextdbg.cpp:114
static int ErrMsg(int Error)
Definition: shlextdbg.cpp:71
HRESULT hr
Definition: shlfolder.c:183
ASSOCDATA
Definition: shlwapi.h:632
@ ASSOCDATA_EDITFLAGS
Definition: shlwapi.h:637
@ ASSOCDATA_VALUE
Definition: shlwapi.h:638
ASSOCSTR
Definition: shlwapi.h:602
@ ASSOCSTR_COMMAND
Definition: shlwapi.h:603
@ ASSOCSTR_FRIENDLYDOCNAME
Definition: shlwapi.h:605
@ ASSOCSTR_EXECUTABLE
Definition: shlwapi.h:604
@ ASSOCSTR_DEFAULTICON
Definition: shlwapi.h:617
ASSOCKEY
Definition: shlwapi.h:623
DWORD ASSOCF
Definition: shlwapi.h:599
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define wprintf(...)
Definition: whoami.c:18
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define IID_PPV_ARG(Itype, ppType)
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by wmain().

◆ cb_AddPage()

static BOOL CALLBACK cb_AddPage ( HPROPSHEETPAGE  page,
LPARAM  lParam 
)
static

Definition at line 599 of file shlextdbg.cpp.

600{
601 g_Pages.Add(page);
602 if (lParam != (LPARAM)&g_Pages)
603 {
604 wprintf(L"Propsheet failed to pass lParam, got: 0x%Ix\n", lParam);
605 }
606 return TRUE;
607}
LPARAM lParam
Definition: combotst.c:139
#define TRUE
Definition: types.h:120
CSimpleArray< HPROPSHEETPAGE > g_Pages
Definition: shlextdbg.cpp:598
Definition: module.h:576
LONG_PTR LPARAM
Definition: windef.h:208

Referenced by wmain().

◆ CLSIDPrefix()

template<class T >
static bool CLSIDPrefix ( T String,
CLSID Clsid 
)
static

Definition at line 89 of file shlextdbg.cpp.

90{
91 WCHAR buf[38 + 1];
92 if (String[0] == '{')
93 {
95 if (SUCCEEDED(CLSIDFromString(buf, &Clsid)))
96 {
97 String = String + 38;
98 return true;
99 }
100 }
101 return false;
102}
#define lstrcpynW
Definition: compat.h:738
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
#define _countof(array)
Definition: sndvol32.h:68
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433

Referenced by AssocQ(), and wmain().

◆ CreateIDataObject()

HRESULT CreateIDataObject ( CComHeapPtr< ITEMIDLIST > &  pidl,
CComPtr< IDataObject > &  dataObject,
PCWSTR  FileName 
)

Definition at line 401 of file shlextdbg.cpp.

402{
404 if (!SUCCEEDED(hr))
405 {
406 wprintf(L"Failed to create pidl from '%s': 0x%x\n", FileName, hr);
407 return hr;
408 }
409
410 CComPtr<IShellFolder> shellFolder;
411 PCUITEMID_CHILD childs;
412 hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shellFolder), &childs);
413 if (!SUCCEEDED(hr))
414 {
415 wprintf(L"Failed to bind to parent: 0x%x\n", hr);
416 return hr;
417 }
418 hr = shellFolder->GetUIObjectOf(NULL, 1, &childs, IID_IDataObject, NULL, (PVOID*)&dataObject);
419 if (!SUCCEEDED(hr))
420 {
421 wprintf(L"Failed to query IDataObject: 0x%x\n", hr);
422 }
423 return hr;
424}
const GUID IID_IDataObject
HRESULT WINAPI SHParseDisplayName(LPCWSTR pszName, IBindCtx *pbc, LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut)
Definition: pidl.c:1396
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1352
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70

Referenced by LoadAndInitialize().

◆ CreateShellItemFromParse()

static HRESULT CreateShellItemFromParse ( PCWSTR  Path,
IShellItem **  ppSI 
)
static

Definition at line 114 of file shlextdbg.cpp.

115{
116 PIDLIST_ABSOLUTE pidl = NULL;
117 HRESULT hr = SHParseDisplayName(Path, NULL, &pidl, 0, NULL);
118 if (SUCCEEDED(hr))
119 {
120 hr = SHCreateShellItem(NULL, NULL, pidl, ppSI);
121 SHFree(pidl);
122 }
123 return hr;
124}
EXTERN_C HRESULT WINAPI SHCreateShellItem(PCIDLIST_ABSOLUTE pidlParent, IShellFolder *psfParent, PCUITEMID_CHILD pidl, IShellItem **ppsi)
Definition: CShellItem.cpp:264
PRTL_UNICODE_STRING_BUFFER Path
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326

Referenced by AssocQ(), and wmain().

◆ DumpBytes()

static void DumpBytes ( const void Data,
SIZE_T  cb 
)
static

Definition at line 166 of file shlextdbg.cpp.

167{
168 for (SIZE_T i = 0; i < cb; ++i)
169 {
170 wprintf(L"%s%.2X", i ? L" " : L"", ((LPCBYTE)Data)[i]);
171 }
172 wprintf(L"\n");
173}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
ULONG_PTR SIZE_T
Definition: typedefs.h:80
const BYTE * LPCBYTE
Definition: winscard.h:34

Referenced by AssocQ().

◆ DumpMenu()

static void DumpMenu ( HMENU  hMenu,
UINT  IdOffset,
IContextMenu pCM,
BOOL  FakeInit,
UINT  Indent 
)
static

Definition at line 194 of file shlextdbg.cpp.

195{
196 bool recurse = Indent != UINT(-1);
198 MENUITEMINFOW mii;
199 mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem);
200
201 for (UINT i = 0, defid = GetMenuDefaultItem(hMenu, FALSE, 0); ; ++i)
202 {
203 mii.fMask = MIIM_STRING;
204 mii.dwTypeData = buf;
205 mii.cch = _countof(buf);
206 *buf = UNICODE_NULL;
207 if (!GetMenuItemInfo(hMenu, i, TRUE, &mii))
208 lstrcpynW(buf, L"?", _countof(buf)); // Tolerate string failure
210 mii.hSubMenu = NULL;
211 mii.dwTypeData = NULL;
212 mii.cch = 0;
213 if (!GetMenuItemInfo(hMenu, i, TRUE, &mii))
214 break;
215
216 BOOL sep = mii.fType & MFT_SEPARATOR;
217 wprintf(L"%-4d", (sep || mii.wID == UINT(-1)) ? mii.wID : (mii.wID - IdOffset));
218 for (UINT j = 0; j < Indent && recurse; ++j)
219 wprintf(L" ");
220 wprintf(L"%s%s", mii.hSubMenu ? L">" : L"|", sep ? L"----------" : buf);
221 if (!sep && pCM && SUCCEEDED(GetCommandString(*pCM, mii.wID - IdOffset,
222 GCS_VERB, buf, _countof(buf))))
223 {
224 wprintf(L" [%s]", buf);
225 }
226 wprintf(L"%s\n", (defid == mii.wID && defid != UINT(-1)) ? L" (Default)" : L"");
227 if (mii.hSubMenu && recurse)
228 {
229 if (FakeInit)
231 DumpMenu(mii.hSubMenu, IdOffset, pCM, FakeInit, Indent + 1);
232 }
233 }
234}
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define LOWORD(l)
Definition: pedump.c:82
HRESULT WINAPI SHForwardContextMenuMsg(IUnknown *pUnk, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pResult, BOOL useIContextMenu2)
Definition: rosordinal.c:11
static HRESULT GetCommandString(IContextMenu &CM, UINT Id, UINT Type, LPWSTR buf, UINT cchMax)
Definition: shlextdbg.cpp:175
static void DumpMenu(HMENU hMenu, UINT IdOffset, IContextMenu *pCM, BOOL FakeInit, UINT Indent)
Definition: shlextdbg.cpp:194
LPWSTR dwTypeData
Definition: winuser.h:3269
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
UINT_PTR WPARAM
Definition: windef.h:207
UINT WINAPI GetMenuDefaultItem(_In_ HMENU hMenu, _In_ UINT fByPos, _In_ UINT gmdiFlags)
#define MIIM_STRING
Definition: winuser.h:727
#define MIIM_ID
Definition: winuser.h:722
#define MIIM_FTYPE
Definition: winuser.h:729
#define MFT_SEPARATOR
Definition: winuser.h:744
#define MIIM_SUBMENU
Definition: winuser.h:723
#define WM_INITMENUPOPUP
Definition: winuser.h:1746
#define GetMenuItemInfo
Definition: winuser.h:5788

Referenced by DumpMenu(), and wmain().

◆ EnumWindowsProc()

BOOL CALLBACK EnumWindowsProc ( HWND  hwnd,
LPARAM  lParam 
)

Definition at line 500 of file shlextdbg.cpp.

501{
502 if (hwnd != g_ConsoleWindow)
503 {
504 DWORD pid = 0;
506 if (pid == GetCurrentProcessId())
507 {
508 g_Windows.Add(hwnd);
509 }
510 }
511 return TRUE;
512}
CSimpleArray< HWND > g_Windows
Definition: shlextdbg.cpp:498
HWND g_ConsoleWindow
Definition: shlextdbg.cpp:499
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837

Referenced by WaitWindows().

◆ ErrMsg()

static int ErrMsg ( int  Error)
static

Definition at line 71 of file shlextdbg.cpp.

72{
73 WCHAR buf[400];
74 for (UINT e = Error, cch; ;)
75 {
76 lstrcpynW(buf, L"?", _countof(buf));
78 while (cch && buf[cch - 1] <= ' ')
79 buf[--cch] = UNICODE_NULL; // Remove trailing newlines
80 if (cch || HIWORD(e) != HIWORD(HRESULT_FROM_WIN32(1)))
81 break;
82 e = HRESULT_CODE(e); // "WIN32_FROM_HRESULT"
83 }
84 wprintf(Error < 0 ? L"Error 0x%.8X %s\n" : L"Error %d %s\n", Error, buf);
85 return Error;
86}
BOOL Error
Definition: chkdsk.c:66
#define e
Definition: ke_i.h:82
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
#define HIWORD(l)
Definition: typedefs.h:247
#define FormatMessage
Definition: winbase.h:3730
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:420
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423
#define HRESULT_CODE(hr)
Definition: winerror.h:76

Referenced by AssocQ(), FatOpenVolume(), KdbpEvaluateExpression(), KdbpInsertBreakPoint(), KdbpRpnEvaluateExpression(), KdbpRpnEvaluateParsedExpression(), KdbpRpnParseExpression(), RpnpEvaluateStack(), RpnpParseExpression(), SHGFI(), and wmain().

◆ GetAssocClass()

static void GetAssocClass ( LPCWSTR  Path,
LPCITEMIDLIST  pidl,
HKEY hKey 
)
static

Definition at line 126 of file shlextdbg.cpp.

127{
128 hKey = NULL;
129 IQueryAssociations* pQA;
130 if (SUCCEEDED(GetUIObjectOfAbsolute(pidl, IID_PPV_ARG(IQueryAssociations, &pQA))))
131 {
132 pQA->GetKey(0, ASSOCKEY_CLASS, NULL, &hKey); // Not implemented in ROS
133 pQA->Release();
134 }
135 if (!hKey)
136 {
137 DWORD cb;
141 info.dwAttributes = 0;
143 if (info.dwAttributes & SFGAO_FOLDER)
144 {
145 ext = const_cast<LPWSTR>(L"Directory");
146 }
147 else if (info.dwAttributes & SFGAO_BROWSABLE)
148 {
149 ext = const_cast<LPWSTR>(L"Folder"); // Best guess
150 }
151 else
152 {
153 cb = sizeof(buf);
155 {
157 }
158 }
159 if (!hKey)
160 {
162 }
163 }
164}
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
static const WCHAR *const ext[]
Definition: module.c:53
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
DWORD WINAPI SHGetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
Definition: reg.c:1236
#define KEY_READ
Definition: nt_native.h:1023
DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
Definition: shell32_main.c:415
#define SHGFI_ATTRIBUTES
Definition: shellapi.h:168
#define SHGFI_PIDL
Definition: shellapi.h:180
static HRESULT GetUIObjectOfAbsolute(LPCITEMIDLIST pidl, REFIID riid, void **ppv)
Definition: shlextdbg.cpp:104
@ ASSOCKEY_CLASS
Definition: shlwapi.h:626
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by LoadAndInitialize().

◆ GetCommandString()

static HRESULT GetCommandString ( IContextMenu CM,
UINT  Id,
UINT  Type,
LPWSTR  buf,
UINT  cchMax 
)
static

Definition at line 175 of file shlextdbg.cpp.

176{
177 if (cchMax < 1) return E_INVALIDARG;
178 *buf = UNICODE_NULL;
179
180 // First try to retrieve the UNICODE string directly
181 HRESULT hr = CM.GetCommandString(Id, Type | GCS_UNICODE, 0, (char*)buf, cchMax);
182 if (FAILED(hr))
183 {
184 // It failed, try to retrieve an ANSI string instead then convert it to UNICODE
185 STRRET sr;
186 sr.uType = STRRET_CSTR;
187 hr = CM.GetCommandString(Id, Type & ~GCS_UNICODE, 0, sr.cStr, _countof(sr.cStr));
188 if (SUCCEEDED(hr))
189 hr = StrRetToBufW(&sr, NULL, buf, cchMax);
190 }
191 return hr;
192}
DWORD Id
UINT cchMax
Type
Definition: Type.h:7
#define E_INVALIDARG
Definition: ddrawi.h:101
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:1522
HRESULT GetCommandString([in] UINT_PTR idCmd, [in] UINT uType, [out] UINT *pwReserved, [out, size_is(cchMax)] LPSTR pszName, [in] UINT cchMax)
@ STRRET_CSTR
Definition: shtypes.idl:87
char cStr[MAX_PATH]
Definition: shtypes.idl:98
UINT uType
Definition: shtypes.idl:93

Referenced by DumpMenu().

◆ GetUIObjectOfAbsolute()

static HRESULT GetUIObjectOfAbsolute ( LPCITEMIDLIST  pidl,
REFIID  riid,
void **  ppv 
)
static

Definition at line 104 of file shlextdbg.cpp.

105{
106 CComPtr<IShellFolder> shellFolder;
108 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shellFolder), &child);
109 if (SUCCEEDED(hr))
110 hr = shellFolder->GetUIObjectOf(NULL, 1, &child, riid, NULL, ppv);
111 return hr;
112}
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
static HWND child
Definition: cursoricon.c:298

Referenced by GetAssocClass().

◆ isCmd()

static bool isCmd ( int  argc,
WCHAR **  argv,
int  n,
PCWSTR  check 
)
static

Definition at line 633 of file shlextdbg.cpp.

634{
635 return !wcsicmp(argv[n] + 1, check);
636}
#define check(expected, result)
Definition: dplayx.c:32
GLdouble n
Definition: glext.h:7729

Referenced by wmain().

◆ isCmdWithArg()

static bool isCmdWithArg ( int  argc,
WCHAR **  argv,
int n,
PCWSTR  check,
PCWSTR arg 
)
static

Definition at line 609 of file shlextdbg.cpp.

610{
611 arg = NULL;
612 size_t len = wcslen(check);
613 if (!_wcsnicmp(argv[n] + 1, check, len))
614 {
615 PCWSTR cmd = argv[n] + len + 1;
616 if (*cmd == ':' || *cmd == '=')
617 {
618 arg = cmd + 1;
619 return true;
620 }
621 if (n + 1 < argc)
622 {
623 arg = argv[n+1];
624 n++;
625 return true;
626 }
627 wprintf(L"Command %s has no required argument!\n", check);
628 return false;
629 }
630 return false;
631}
GLenum GLsizei len
Definition: glext.h:6722
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
Definition: ftp_var.h:139

Referenced by wmain().

◆ LoadAndInitialize()

HRESULT LoadAndInitialize ( REFIID  riid,
LPVOID ppv 
)

Definition at line 426 of file shlextdbg.cpp.

427{
428 CComPtr<IShellExtInit> spShellExtInit;
429 HRESULT hr;
430 if (g_DLL.IsEmpty())
431 {
432 hr = CoCreateInstance(g_CLSID, NULL, CLSCTX_ALL, IID_PPV_ARG(IShellExtInit, &spShellExtInit));
433 if (!SUCCEEDED(hr))
434 {
435 WCHAR Buffer[100];
437 wprintf(L"Failed to Create %s:IShellExtInit: 0x%x\n", Buffer, hr);
438 return hr;
439 }
440 }
441 else
442 {
443 typedef HRESULT (STDAPICALLTYPE *tDllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
445 if (!mod)
446 {
447 wprintf(L"Failed to Load %s:(0x%x)\n", g_DLL.GetString(), GetLastError());
448 return E_FAIL;
449 }
450 tDllGetClassObject DllGet = (tDllGetClassObject)GetProcAddress(mod, "DllGetClassObject");
451 if (!DllGet)
452 {
453 wprintf(L"%s does not export DllGetClassObject\n", g_DLL.GetString());
454 return E_FAIL;
455 }
456 CComPtr<IClassFactory> spClassFactory;
457 hr = DllGet(g_CLSID, IID_PPV_ARG(IClassFactory, &spClassFactory));
458 if (!SUCCEEDED(hr))
459 {
460 wprintf(L"Failed to create IClassFactory: 0x%x\n", hr);
461 return hr;
462 }
463 hr = spClassFactory->CreateInstance(NULL, IID_PPV_ARG(IShellExtInit, &spShellExtInit));
464 if (!SUCCEEDED(hr))
465 {
466 wprintf(L"Failed to Request IShellExtInit from IClassFactory: 0x%x\n", hr);
467 return hr;
468 }
469 }
470
471 CComPtr<IDataObject> spDataObject;
473 hr = CreateIDataObject(pidl, spDataObject, g_ShellExtInit.GetString());
474 if (!SUCCEEDED(hr))
475 return hr;
476
477 HKEY hKey = NULL;
479 hr = spShellExtInit->Initialize(pidl, spDataObject, hKey);
480 if (hKey)
482 if (!SUCCEEDED(hr))
483 {
484 wprintf(L"IShellExtInit->Initialize failed: 0x%x\n", hr);
485 return hr;
486 }
487 hr = spShellExtInit->QueryInterface(riid, ppv);
488 if (!SUCCEEDED(hr))
489 {
490 WCHAR Buffer[100];
492 wprintf(L"Failed to query %s from IShellExtInit: 0x%x\n", Buffer, hr);
493 }
494 return hr;
495}
bool IsEmpty() const noexcept
Definition: atlsimpstr.h:394
PXSTR GetString() noexcept
Definition: atlsimpstr.h:367
Definition: bufpool.h:45
#define E_FAIL
Definition: ddrawi.h:102
#define GetProcAddress(x, y)
Definition: compat.h:753
#define LoadLibraryW(x)
Definition: compat.h:747
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
#define STDAPICALLTYPE
Definition: guid.c:3
static int mod
Definition: i386-dis.c:1288
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
CLSID g_CLSID
Definition: shlextdbg.cpp:394
static void GetAssocClass(LPCWSTR Path, LPCITEMIDLIST pidl, HKEY &hKey)
Definition: shlextdbg.cpp:126
CStringW g_ShellExtInit
Definition: shlextdbg.cpp:396
HRESULT CreateIDataObject(CComHeapPtr< ITEMIDLIST > &pidl, CComPtr< IDataObject > &dataObject, PCWSTR FileName)
Definition: shlextdbg.cpp:401
CStringW g_DLL
Definition: shlextdbg.cpp:395
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by wmain().

◆ PrintHelp()

static void PrintHelp ( PCWSTR  ExtraLine = NULL)
static

Definition at line 19 of file shlextdbg.cpp.

20{
21 if (ExtraLine)
22 wprintf(L"%s\n\n", ExtraLine);
23
24 wprintf(L"shlextdbg /clsid={clsid} [/dll=dllname] /IShellExtInit=filename |shlextype| |waitoptions|\n");
25 wprintf(L" {clsid}: The CLSID or ProgID of the object to create\n");
26 wprintf(L" dll: Optional dllname to create the object from, instead of CoCreateInstance\n");
27 wprintf(L" filename: The filename to pass to IShellExtInit->Initialze\n");
28 wprintf(L" shlextype: The type of shell extention to run:\n");
29 wprintf(L" /IShellPropSheetExt to create a property sheet\n");
30 wprintf(L" /IContextMenu=verb to activate the specified verb\n");
31 wprintf(L" waitoptions: Specify how to wait:\n");
32 wprintf(L" /explorerinstance: Wait for SHGetInstanceExplorer (Default)\n");
33 wprintf(L" /infinite: Keep on waiting infinitely\n");
34 wprintf(L" /openwindows: Wait for all windows from the current application to close\n");
35 wprintf(L" /input: Wait for input\n");
36 wprintf(L" /nowait\n");
37 wprintf(L"\n");
38 wprintf(L"shlextdbg /shgfi=path\n");
39 wprintf(L" Call SHGetFileInfo. Prefix path with $ to parse as a pidl.\n");
40 wprintf(L"\n");
41 wprintf(L"shlextdbg /assocq <[{bhid}]path> <string|data|key> <type> <initflags> <queryflags> <initstring> [extra] [maxsize]\n");
42 wprintf(L" Uses the default implementation from AssocCreate if path is empty.\n");
43 wprintf(L"\n");
44 wprintf(L"shlextdbg /shellexec=path [/see] [verb] [class]\n");
45 wprintf(L"\n");
46 wprintf(L"shlextdbg /dumpmenu=[{clsid}]path [/cmf]\n");
47}

◆ SHGFI()

static int SHGFI ( PCWSTR  Path)
static

Definition at line 236 of file shlextdbg.cpp.

237{
238 PIDLIST_ABSOLUTE pidl = NULL;
239 UINT flags = 0, ret = 0;
240
241 if (*Path == L'$')
242 {
243 HRESULT hr = SHParseDisplayName(++Path, NULL, &pidl, 0, NULL);
244 if (FAILED(hr))
245 return ErrMsg(hr);
246 flags |= SHGFI_PIDL;
247 Path = (LPCWSTR)pidl;
248 }
250 {
252 }
254 if (!SHGetFileInfoW(Path, 0, &info, sizeof(info), flags |
256 {
257 info.szDisplayName[0] = info.szTypeName[0] = UNICODE_NULL;
258 info.dwAttributes = 0;
260 }
261 wprintf(L"Display: %s\n", info.szDisplayName);
262 wprintf(L"Attributes: 0x%x\n", info.dwAttributes);
263 wprintf(L"Type: %s\n", info.szTypeName);
264
265 if (!SHGetFileInfoW(Path, 0, &info, sizeof(info), flags | SHGFI_ICONLOCATION))
266 {
267 info.szDisplayName[0] = UNICODE_NULL;
268 info.iIcon = -1;
269 }
270 wprintf(L"Icon: %s,%d\n", info.szDisplayName, info.iIcon);
271
272 if (!SHGetFileInfoW(Path, 0, &info, sizeof(info), flags | SHGFI_SYSICONINDEX))
273 {
274 info.iIcon = -1;
275 }
276 wprintf(L"Index: %d\n", info.iIcon);
277 SHFree(pidl);
278 return ret;
279}
GLbitfield flags
Definition: glext.h:7161
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define SHGFI_SYSICONINDEX
Definition: shellapi.h:171
#define SHGFI_ICONLOCATION
Definition: shellapi.h:169
#define SHGFI_DISPLAYNAME
Definition: shellapi.h:166
#define SHGFI_TYPENAME
Definition: shellapi.h:167
#define SHGFI_USEFILEATTRIBUTES
Definition: shellapi.h:181
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
int ret
#define GetFileAttributes
Definition: winbase.h:3750
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by wmain().

◆ StrToNum()

static LONG StrToNum ( PCWSTR  in)
static

Definition at line 64 of file shlextdbg.cpp.

65{
66 PWCHAR end;
67 LONG v = wcstol(in, &end, 0);
68 return (end > in) ? v : 0;
69}
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint end
Definition: gl.h:1545
GLuint in
Definition: glext.h:9616
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
long LONG
Definition: pedump.c:60
uint16_t * PWCHAR
Definition: typedefs.h:56

Referenced by AssocQ().

◆ Wait()

static void Wait ( )
static

Definition at line 572 of file shlextdbg.cpp.

573{
574 LPCWSTR nag = L"(Please use SHGetInstanceExplorer in your code instead)";
575 switch (g_Wait)
576 {
577 case Wait_None:
578 break;
579 case Wait_Infinite:
580 _putws(nag);
581 while (true)
582 Sleep(1000);
583 break;
584 case Wait_OpenWindows:
585 _putws(nag);
586 WaitWindows();
587 break;
588 case Wait_Input:
589 wprintf(L"Press any key to continue... %s\n", nag);
590 _getch();
591 break;
593 g_EI.Wait();
594 break;
595 }
596}
_Check_return_opt_ _CRTIMP int __cdecl _putws(_In_z_ const wchar_t *_Str)
int _getch()
Definition: getch.c:16
WaitType g_Wait
Definition: shlextdbg.cpp:399
ExplorerInstance g_EI
void WaitWindows()
Definition: shlextdbg.cpp:514
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790

Referenced by wmain().

◆ WaitWindows()

void WaitWindows ( )

Definition at line 514 of file shlextdbg.cpp.

515{
516 /* Give the windows some time to spawn */
517 Sleep(2000);
519 while (true)
520 {
521 g_Windows.RemoveAll();
523 if (g_Windows.GetSize() == 0)
524 break;
525 Sleep(500);
526 }
527 wprintf(L"All windows closed (ignoring console window)\n");
528}
HWND WINAPI DECLSPEC_HOTPATCH GetConsoleWindow(VOID)
Definition: console.c:2729
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
Definition: shlextdbg.cpp:500
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)

Referenced by Wait().

◆ wmain()

int wmain ( int  argc,
WCHAR **  argv 
)

Definition at line 639 of file shlextdbg.cpp.

640{
644 SHSetInstanceExplorer(static_cast<IUnknown*>(&g_EI));
645
646 bool failArgs = false;
647 for (int n = 1; n < argc; ++n)
648 {
649 WCHAR* cmd = argv[n];
650 if (cmd[0] == '-' || cmd[0] == '/')
651 {
652 PCWSTR arg;
653 if (isCmdWithArg(argc, argv, n, L"shgfi", arg))
654 {
655 failArgs = true;
656 if (*arg)
657 return SHGFI(arg);
658 }
659 else if (isCmd(argc, argv, n, L"assocq"))
660 {
661 failArgs = true;
662 if (argc - (n + 1) >= 6 && argc - (n + 1) <= 8)
663 return AssocQ(argc - (n + 1), &argv[(n + 1)]);
664 }
665 else if (isCmdWithArg(argc, argv, n, L"shellexec", arg))
666 {
667 PIDLIST_ABSOLUTE pidl = NULL;
668 HRESULT hr = SHParseDisplayName(arg, NULL, &pidl, 0, NULL);
669 if (FAILED(hr))
670 return ErrMsg(hr);
671 SHELLEXECUTEINFOW sei = { sizeof(sei), SEE_MASK_IDLIST | SEE_MASK_UNICODE };
672 sei.lpIDList = pidl;
673 sei.nShow = SW_SHOW;
674 while (++n < argc)
675 {
676 if (argv[n][0] != '-' && argv[n][0] != '/')
677 break;
678 else if (isCmd(argc, argv, n, L"INVOKE"))
680 else if (isCmd(argc, argv, n, L"NOUI"))
682 else if (isCmd(argc, argv, n, L"ASYNCOK"))
683 sei.fMask |= SEE_MASK_ASYNCOK ;
684 else if (isCmd(argc, argv, n, L"NOASYNC"))
685 sei.fMask |= SEE_MASK_NOASYNC;
686 else
687 wprintf(L"WARN: Ignoring switch %s\n", argv[n]);
688 }
689 if (n < argc && *argv[n++])
690 {
691 sei.lpVerb = argv[n - 1];
692 }
693 if (n < argc && *argv[n++])
694 {
695 sei.lpClass = argv[n - 1];
697 }
698 UINT succ = ShellExecuteExW(&sei), gle = GetLastError();
699 SHFree(pidl);
700 if (!succ)
701 return ErrMsg(gle);
702 Wait();
703 return 0;
704 }
705 else if (isCmdWithArg(argc, argv, n, L"dumpmenu", arg))
706 {
707 HRESULT hr;
709 if (CLSIDPrefix(arg, g_CLSID))
710 {
713 }
714 else
715 {
718 if (SUCCEEDED(hr))
719 hr = si->BindToHandler(NULL, BHID_SFUIObject, IID_PPV_ARG(IContextMenu, &cm));
720 }
721 if (SUCCEEDED(hr))
722 {
723 UINT first = 10, last = 9000;
724 UINT cmf = 0, nosub = 0, fakeinit = 0;
725 while (++n < argc)
726 {
727 if (argv[n][0] != '-' && argv[n][0] != '/')
728 break;
729 else if (isCmd(argc, argv, n, L"DEFAULTONLY"))
730 cmf |= CMF_DEFAULTONLY;
731 else if (isCmd(argc, argv, n, L"NODEFAULT"))
732 cmf |= CMF_NODEFAULT;
733 else if (isCmd(argc, argv, n, L"DONOTPICKDEFAULT"))
734 cmf |= CMF_DONOTPICKDEFAULT;
735 else if (isCmd(argc, argv, n, L"EXTENDED") || isCmd(argc, argv, n, L"EXTENDEDVERBS"))
736 cmf |= CMF_EXTENDEDVERBS;
737 else if (isCmd(argc, argv, n, L"SYNCCASCADEMENU"))
738 cmf |= CMF_SYNCCASCADEMENU;
739 else if (isCmd(argc, argv, n, L"EXPLORE"))
740 cmf |= CMF_EXPLORE;
741 else if (isCmd(argc, argv, n, L"VERBSONLY"))
742 cmf |= CMF_VERBSONLY;
743 else if (isCmd(argc, argv, n, L"NOVERBS"))
744 cmf |= CMF_NOVERBS;
745 else if (isCmd(argc, argv, n, L"DISABLEDVERBS"))
746 cmf |= CMF_DISABLEDVERBS;
747 else if (isCmd(argc, argv, n, L"OPTIMIZEFORINVOKE"))
748 cmf |= CMF_OPTIMIZEFORINVOKE;
749 else if (isCmd(argc, argv, n, L"CANRENAME"))
750 cmf |= CMF_CANRENAME;
751 else if (isCmd(argc, argv, n, L"NOSUBMENU"))
752 nosub++;
753 else if (isCmd(argc, argv, n, L"INITMENUPOPUP"))
754 fakeinit++; // Tickle async submenus
755 else
756 wprintf(L"WARN: Ignoring switch %s\n", argv[n]);
757 }
758 HMENU hMenu = CreatePopupMenu();
759 hr = cm->QueryContextMenu(hMenu, 0, first, last, cmf);
760 if (SUCCEEDED(hr))
761 {
762 DumpMenu(hMenu, first, cm, fakeinit, nosub ? -1 : 0);
763 }
764 DestroyMenu(hMenu);
765 }
766 if (FAILED(hr))
767 return ErrMsg(hr);
768 return 0;
769 }
770 else if (isCmdWithArg(argc, argv, n, L"clsid", arg))
771 {
773 if (!SUCCEEDED(hr))
774 {
775 wprintf(L"Failed to convert %s to CLSID\n", arg);
776 failArgs = true;
777 }
778 }
779 else if (isCmdWithArg(argc, argv, n, L"dll", arg))
780 {
781 g_DLL = arg;
782 }
783 else if (isCmdWithArg(argc, argv, n, L"IShellExtInit", arg))
784 {
786 }
787 else if (isCmd(argc, argv, n, L"IShellPropSheetExt"))
788 {
790 }
791 else if (isCmdWithArg(argc, argv, n, L"IContextMenu", arg))
792 {
794 }
795 else if (isCmd(argc, argv, n, L"infinite"))
796 {
798 }
799 else if (isCmd(argc, argv, n, L"openwindows"))
800 {
802 }
803 else if (isCmd(argc, argv, n, L"input"))
804 {
806 }
807 else if (isCmd(argc, argv, n, L"explorerinstance"))
808 {
810 }
811 else if (isCmd(argc, argv, n, L"nowait"))
812 {
814 }
815 else
816 {
817 wprintf(L"Unknown argument: %s\n", cmd);
818 failArgs = true;
819 }
820 }
821 }
822
823 if (failArgs)
824 {
826 return E_INVALIDARG;
827 }
828
829 CLSID EmptyCLSID = { 0 };
830 if (EmptyCLSID == g_CLSID)
831 {
832 PrintHelp(L"No CLSID specified");
833 return E_INVALIDARG;
834 }
835
837 {
838 PrintHelp(L"No filename specified");
839 return E_INVALIDARG;
840 }
841
842 HRESULT hr;
844 {
847 if (!SUCCEEDED(hr))
848 return hr;
849
850 hr = spSheetExt->AddPages(cb_AddPage, (LPARAM)&g_Pages);
851 if (!SUCCEEDED(hr))
852 {
853 wprintf(L"IShellPropSheetExt->AddPages failed: 0x%x\n", hr);
854 return hr;
855 }
856
857 USHORT ActivePage = HRESULT_CODE(hr);
858 PROPSHEETHEADERW psh = { 0 };
859
860 psh.dwSize = sizeof(psh);
862 psh.pszCaption = L"shlextdbg";
863 psh.phpage = g_Pages.GetData();
864 psh.nPages = g_Pages.GetSize();
865 psh.nStartPage = ActivePage ? (ActivePage-1) : 0;
866 hr = PropertySheetW(&psh);
867
868 wprintf(L"PropertySheetW returned: 0x%x\n", hr);
869 }
870 if (!g_ContextMenu.IsEmpty())
871 {
872 CComPtr<IContextMenu> spContextMenu;
873 hr = LoadAndInitialize(IID_PPV_ARG(IContextMenu, &spContextMenu));
874 if (!SUCCEEDED(hr))
875 return hr;
876
877 // FIXME: Must call QueryContextMenu before InvokeCommand?
878
879 CMINVOKECOMMANDINFO cm = { sizeof(cm), 0 };
880 cm.lpVerb = g_ContextMenu.GetString();
881 cm.nShow = SW_SHOW;
882 hr = spContextMenu->InvokeCommand(&cm);
883
884 if (!SUCCEEDED(hr))
885 {
886 wprintf(L"IContextMenu->InvokeCommand failed: 0x%x\n", hr);
887 return hr;
888 }
889 wprintf(L"IContextMenu->InvokeCommand returned: 0x%x\n", hr);
890 }
891
892 Wait();
893 return 0;
894}
BOOL WINAPI InitCommonControlsEx(const INITCOMMONCONTROLSEX *lpInitCtrls)
Definition: commctrl.c:893
INT_PTR WINAPI PropertySheetW(LPCPROPSHEETHEADERW lppsh)
Definition: propsheet.c:2913
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
const GLint * first
Definition: glext.h:5794
if(dx< 0)
Definition: linetemp.h:194
static UINT UINT last
Definition: font.c:45
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
unsigned short USHORT
Definition: pedump.c:61
#define PSH_PROPTITLE
Definition: prsht.h:40
#define ICC_STANDARD_CLASSES
Definition: commctrl.h:73
#define ICC_LINK_CLASS
Definition: commctrl.h:74
#define SEE_MASK_UNICODE
Definition: shellapi.h:37
#define SEE_MASK_CLASSNAME
Definition: shellapi.h:25
#define SEE_MASK_ASYNCOK
Definition: shellapi.h:54
#define SEE_MASK_IDLIST
Definition: shellapi.h:27
#define SEE_MASK_NOASYNC
Definition: shellapi.h:33
#define SEE_MASK_INVOKEIDLIST
Definition: shellapi.h:28
#define SEE_MASK_FLAG_NO_UI
Definition: shellapi.h:36
VOID WINAPI SHSetInstanceExplorer(LPUNKNOWN lpUnknown)
Definition: shellord.c:1496
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2391
CStringA g_ContextMenu
Definition: shlextdbg.cpp:398
static BOOL CALLBACK cb_AddPage(HPROPSHEETPAGE page, LPARAM lParam)
Definition: shlextdbg.cpp:599
static void Wait()
Definition: shlextdbg.cpp:572
static bool isCmdWithArg(int argc, WCHAR **argv, int &n, PCWSTR check, PCWSTR &arg)
Definition: shlextdbg.cpp:609
static bool isCmd(int argc, WCHAR **argv, int n, PCWSTR check)
Definition: shlextdbg.cpp:633
HRESULT LoadAndInitialize(REFIID riid, LPVOID *ppv)
Definition: shlextdbg.cpp:426
bool g_bIShellPropSheetExt
Definition: shlextdbg.cpp:397
static int SHGFI(PCWSTR Path)
Definition: shlextdbg.cpp:236
static HRESULT AssocQ(int argc, WCHAR **argv)
Definition: shlextdbg.cpp:281
DWORD dwSize
Definition: prsht.h:293
DWORD dwFlags
Definition: prsht.h:294
HPROPSHEETPAGE * phpage
Definition: prsht.h:309
UINT nStartPage
Definition: prsht.h:304
LPCWSTR pszCaption
Definition: prsht.h:301
void * arg
Definition: msvc.h:10
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define SW_SHOW
Definition: winuser.h:775

Variable Documentation

◆ g_bIShellPropSheetExt

bool g_bIShellPropSheetExt = false

Definition at line 397 of file shlextdbg.cpp.

Referenced by wmain().

◆ g_CLSID

CLSID g_CLSID = { 0 }

Definition at line 394 of file shlextdbg.cpp.

Referenced by LoadAndInitialize(), and wmain().

◆ g_ConsoleWindow

HWND g_ConsoleWindow

Definition at line 499 of file shlextdbg.cpp.

Referenced by EnumWindowsProc(), and WaitWindows().

◆ g_ContextMenu

CStringA g_ContextMenu

Definition at line 398 of file shlextdbg.cpp.

Referenced by wmain().

◆ g_DLL

CStringW g_DLL

Definition at line 395 of file shlextdbg.cpp.

Referenced by LoadAndInitialize(), and wmain().

◆ g_EI

Referenced by Wait(), and wmain().

◆ g_Pages

Definition at line 598 of file shlextdbg.cpp.

Referenced by cb_AddPage(), and wmain().

◆ g_ShellExtInit

CStringW g_ShellExtInit

Definition at line 396 of file shlextdbg.cpp.

Referenced by LoadAndInitialize(), and wmain().

◆ g_Wait

◆ g_Windows

CSimpleArray<HWND> g_Windows

Definition at line 498 of file shlextdbg.cpp.

Referenced by EnumWindowsProc(), and WaitWindows().