ReactOS 0.4.17-dev-684-ga6524ef
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  CLoggingServiceProvider
 
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 IServiceProviderGetLoggingServiceProvider ()
 
static HRESULT GetUIObjectOfAbsolute (LPCITEMIDLIST pidl, REFIID riid, void **ppv)
 
static HRESULT CreateShellItemFromParse (PCWSTR Path, IShellItem **ppSI, PIDLIST_ABSOLUTE *ppidl=NULL)
 
static void GetAssocClass (LPCWSTR Path, LPCITEMIDLIST pidl, HKEY &hKey)
 
static void DumpBytes (const void *Data, SIZE_T cb)
 
static CHAR SafeDumpChar (UINT Ch)
 
static void DumpHexBytes (LPCVOID Buffer, 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 DumpPidl (PCWSTR Path)
 
static HRESULT DumpFolderColumns (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 567 of file shlextdbg.cpp.

568{
569 Wait_None,
574};
@ Wait_OpenWindows
Definition: shlextdbg.cpp:571
@ Wait_Input
Definition: shlextdbg.cpp:572
@ Wait_Infinite
Definition: shlextdbg.cpp:570
@ Wait_ExplorerInstance
Definition: shlextdbg.cpp:573
@ Wait_None
Definition: shlextdbg.cpp:569

Function Documentation

◆ AssocQ()

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

Definition at line 463 of file shlextdbg.cpp.

464{
465 UINT qtype = StrToNum(argv[2]);
466 ASSOCF iflags = StrToNum(argv[3]);
467 ASSOCF qflags = StrToNum(argv[4]);
468 PCWSTR extra = (argc > 6 && *argv[6]) ? argv[6] : NULL;
469 WCHAR buf[MAX_PATH * 2];
470 DWORD maxSize = (argc > 7 && *argv[7]) ? StrToNum(argv[7]) : sizeof(buf);
471
472 HRESULT hr;
474 PWSTR path = argv[0];
475 if (*path)
476 {
477 CLSID clsid, *pclsid = NULL;
478 if (CLSIDPrefix(path, clsid))
479 pclsid = &clsid;
482 {
483 hr = si->BindToHandler(NULL, pclsid ? *pclsid : BHID_AssociationArray, IID_PPV_ARG(IQueryAssociations, &qa));
484 if (FAILED(hr) && !pclsid)
485 hr = si->BindToHandler(NULL, BHID_SFUIObject, IID_PPV_ARG(IQueryAssociations, &qa));
486 }
487 }
488 else
489 {
490 hr = AssocCreate(CLSID_QueryAssociations, IID_PPV_ARG(IQueryAssociations, &qa));
491 }
492 if (FAILED(hr))
493 return ErrMsg(hr);
494 hr = qa->Init(iflags, argv[5], NULL, NULL);
495 if (FAILED(hr))
496 return ErrMsg(hr);
497
498 DWORD size = maxSize;
499 if (!_wcsicmp(argv[1], L"string"))
500 {
501 if (!_wcsicmp(argv[2], L"COMMAND"))
502 qtype = ASSOCSTR_COMMAND;
503 if (!_wcsicmp(argv[2], L"EXECUTABLE"))
504 qtype = ASSOCSTR_EXECUTABLE;
505 if (!_wcsicmp(argv[2], L"FRIENDLYDOCNAME") || !_wcsicmp(argv[2], L"FriendlyTypeName"))
507 if (!_wcsicmp(argv[2], L"DEFAULTICON"))
508 qtype = ASSOCSTR_DEFAULTICON;
509
510 buf[0] = UNICODE_NULL;
511 size /= sizeof(buf[0]); // Convert to number of characters
512 hr = qa->GetString(qflags, (ASSOCSTR)qtype, extra, buf, &size);
513 size *= sizeof(buf[0]); // Convert back to bytes
514 if (SUCCEEDED(hr) ||
516 {
517 wprintf(L"0x%.8X: %s\n", hr, buf);
518 }
519 else
520 {
521 wprintf(size != maxSize ? L"%u " : L"", size);
522 ErrMsg(hr);
523 }
524 }
525 else if (!_wcsicmp(argv[1], L"data"))
526 {
527 if (!_wcsicmp(argv[2], L"EDITFLAGS"))
528 qtype = ASSOCDATA_EDITFLAGS;
529 if (!_wcsicmp(argv[2], L"VALUE"))
530 qtype = ASSOCDATA_VALUE;
531
532 hr = qa->GetData(qflags, (ASSOCDATA)qtype, extra, buf, &size);
533 if (SUCCEEDED(hr))
534 {
535 wprintf(L"0x%.8X: %u byte(s) ", hr, size);
536 DumpBytes(buf, min(size, maxSize));
537 }
538 else
539 {
540 wprintf(size != maxSize ? L"%u " : L"", size);
541 ErrMsg(hr);
542 }
543 }
544 else if (!_wcsicmp(argv[1], L"key"))
545 {
546 HKEY hKey = NULL;
547 hr = qa->GetKey(qflags, (ASSOCKEY)qtype, extra, &hKey);
548 if (SUCCEEDED(hr))
549 {
550 wprintf(L"0x%.8X: hKey %p\n", hr, hKey);
551 RegQueryValueExW(hKey, L"shlextdbg_ASSOCKEY", 0, NULL, NULL, NULL); // Filter by this in RegMon
553 }
554 else
555 {
556 ErrMsg(hr);
557 }
558 }
559 else
560 {
561 PrintHelp(L"Unknown query");
563 }
564 return hr;
565}
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
HRESULT hr
Definition: delayimp.cpp:582
#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
MonoAssembly int argc
Definition: metahost.c:107
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:164
HRESULT WINAPI AssocCreate(CLSID clsid, REFIID refiid, void **lpInterface)
Definition: assoc.c:213
#define L(x)
Definition: resources.c:13
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
unsigned int UINT
Definition: sysinfo.c:13
@ extra
Definition: id3.c:95
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
static SYSTEM_INFO si
Definition: virtual.c:39
#define min(a, b)
Definition: monoChain.cc:55
#define argv
Definition: mplay32.c:18
const CLSID * clsid
Definition: msctf.cpp:50
void PrintHelp(void)
Definition: nslookup.c:79
#define UNICODE_NULL
short WCHAR
Definition: pedump.c:58
ASSOCDATA
Definition: shlwapi.h:926
@ ASSOCDATA_EDITFLAGS
Definition: shlwapi.h:932
@ ASSOCDATA_VALUE
Definition: shlwapi.h:933
ASSOCSTR
Definition: shlwapi.h:885
@ ASSOCSTR_COMMAND
Definition: shlwapi.h:886
@ ASSOCSTR_FRIENDLYDOCNAME
Definition: shlwapi.h:888
@ ASSOCSTR_EXECUTABLE
Definition: shlwapi.h:887
@ ASSOCSTR_DEFAULTICON
Definition: shlwapi.h:901
ASSOCKEY
Definition: shlwapi.h:918
DWORD ASSOCF
Definition: shlwapi.h:967
static HRESULT CreateShellItemFromParse(PCWSTR Path, IShellItem **ppSI, PIDLIST_ABSOLUTE *ppidl=NULL)
Definition: shlextdbg.cpp:153
static bool CLSIDPrefix(T &String, CLSID &Clsid)
Definition: shlextdbg.cpp:96
static LONG StrToNum(PCWSTR in)
Definition: shlextdbg.cpp:71
static void DumpBytes(const void *Data, SIZE_T cb)
Definition: shlextdbg.cpp:208
static int ErrMsg(int Error)
Definition: shlextdbg.cpp:78
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define wprintf(...)
Definition: whoami.c:18
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define IID_PPV_ARG(Itype, ppType)

Referenced by wmain().

◆ cb_AddPage()

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

Definition at line 781 of file shlextdbg.cpp.

782{
783 g_Pages.Add(page);
784 if (lParam != (LPARAM)&g_Pages)
785 {
786 wprintf(L"Propsheet failed to pass lParam, got: 0x%Ix\n", lParam);
787 }
788 return TRUE;
789}
LPARAM lParam
Definition: combotst.c:139
#define TRUE
Definition: types.h:120
LONG_PTR LPARAM
Definition: minwindef.h:175
CSimpleArray< HPROPSHEETPAGE > g_Pages
Definition: shlextdbg.cpp:780
Definition: module.h:576

Referenced by wmain().

◆ CLSIDPrefix()

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

Definition at line 96 of file shlextdbg.cpp.

97{
98 WCHAR buf[38 + 1];
99 if (String[0] == '{')
100 {
102 if (SUCCEEDED(CLSIDFromString(buf, &Clsid)))
103 {
104 String = String + 38;
105 return true;
106 }
107 }
108 return false;
109}
HRESULT WINAPI CLSIDFromString(LPCOLESTR str, LPCLSID clsid)
Definition: combase.c:1470
#define lstrcpynW
Definition: compat.h:738
#define _countof(array)
Definition: sndvol32.h:70
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2439

Referenced by AssocQ(), and wmain().

◆ CreateIDataObject()

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

Definition at line 583 of file shlextdbg.cpp.

584{
586 if (!SUCCEEDED(hr))
587 {
588 wprintf(L"Failed to create pidl from '%s': 0x%x\n", FileName, hr);
589 return hr;
590 }
591
592 CComPtr<IShellFolder> shellFolder;
593 PCUITEMID_CHILD childs;
594 hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shellFolder), &childs);
595 if (!SUCCEEDED(hr))
596 {
597 wprintf(L"Failed to bind to parent: 0x%x\n", hr);
598 return hr;
599 }
600 hr = shellFolder->GetUIObjectOf(NULL, 1, &childs, IID_IDataObject, NULL, (PVOID*)&dataObject);
601 if (!SUCCEEDED(hr))
602 {
603 wprintf(L"Failed to query IDataObject: 0x%x\n", hr);
604 }
605 return hr;
606}
const GUID IID_IDataObject
HRESULT WINAPI SHParseDisplayName(LPCWSTR pszName, IBindCtx *pbc, LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut)
Definition: pidl.c:1548
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1504
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70

Referenced by LoadAndInitialize().

◆ CreateShellItemFromParse()

static HRESULT CreateShellItemFromParse ( PCWSTR  Path,
IShellItem **  ppSI,
PIDLIST_ABSOLUTE ppidl = NULL 
)
static

Definition at line 153 of file shlextdbg.cpp.

154{
155 PIDLIST_ABSOLUTE pidl = NULL;
156 HRESULT hr = SHParseDisplayName(Path, NULL, &pidl, 0, NULL);
157 if (SUCCEEDED(hr))
158 {
159 hr = SHCreateShellItem(NULL, NULL, pidl, ppSI);
160 if (ppidl)
161 *ppidl = pidl;
162 else
163 SHFree(pidl);
164 }
165 return hr;
166}
HRESULT WINAPI SHCreateShellItem(PCIDLIST_ABSOLUTE pidlParent, IShellFolder *psfParent, PCUITEMID_CHILD pidl, IShellItem **ppsi)
Definition: CShellItem.cpp:261
PRTL_UNICODE_STRING_BUFFER Path
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:370

Referenced by AssocQ(), DumpFolderColumns(), DumpPidl(), and wmain().

◆ DumpBytes()

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

Definition at line 208 of file shlextdbg.cpp.

209{
210 for (SIZE_T i = 0; i < cb; ++i)
211 {
212 wprintf(L"%s%.2X", i ? L" " : L"", ((LPCBYTE)Data)[i]);
213 }
214 wprintf(L"\n");
215}
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
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
ULONG_PTR SIZE_T
Definition: typedefs.h:80
const BYTE * LPCBYTE
Definition: winscard.h:34

Referenced by AssocQ().

◆ DumpFolderColumns()

static HRESULT DumpFolderColumns ( PCWSTR  Path)
static

Definition at line 401 of file shlextdbg.cpp.

402{
405 if (FAILED(hr))
406 {
407 wprintf(L"Can't parse %s\n", Path);
408 return hr;
409 }
411 if (FAILED(hr = si->BindToHandler(NULL, BHID_SFObject, IID_PPV_ARG(IShellFolder2, &sf))))
412 {
413 wprintf(L"Could not bind to IShellFolder2\n");
414 return hr;
415 }
416
417 ULONG columns, defSort, defDisp;
418 for (columns = 0; ; ++columns)
419 {
420 SHELLDETAILS sd = {};
421 if (FAILED(sf->GetDetailsOf(NULL, columns, &sd)))
422 break;
423 PWSTR str;
424 if (FAILED(StrRetToStrW(&sd.str, NULL, &str)))
425 str = NULL;
427 if (FAILED(sf->GetDefaultColumnState(columns, &flags)))
428 flags = 0;
429 wprintf(L"%lu: %s 0x%.4x %d 0x%.8x\n", columns, str ? str : L"", (UINT)sd.fmt, sd.cxChar, flags);
430 SHFree(str);
431 }
432
433 if (SUCCEEDED(sf->GetDefaultColumn(0, &defSort, &defDisp)))
434 wprintf(L"%lu is the default sort column and %lu is the default display column.\n", defSort, defDisp);
435
436 HRESULT (WINAPI* PSGNFPK)(SHCOLUMNID*, PWSTR*) = NULL;
437 if (HMODULE hPS = LoadLibraryW(L"propsys.dll"))
438 {
439 // HACKFIX: PSGetNameFromPropertyKey is a stub in ROS, we will crash if we call it
440 HRESULT (WINAPI* PSGPD)(SHCOLUMNID*, REFIID, void**);
441 (FARPROC&)PSGPD = GetProcAddress(hPS, "PSGetPropertyDescription");
443 SHCOLUMNID scid = {};
444 if (PSGPD && PSGPD(&scid, IID_PPV_ARG(IShellFolder2, &dummy)) != E_NOTIMPL)
445 (FARPROC&)PSGNFPK = GetProcAddress(hPS, "PSGetNameFromPropertyKey");
446 }
447 for (ULONG i = 0; i < max(columns, 999); ++i)
448 {
449 SHCOLUMNID scid = {};
450 if (FAILED(sf->MapColumnToSCID(i, &scid)))
451 continue;
452 WCHAR Buffer[100];
453 StringFromGUID2(scid.fmtid, Buffer, _countof(Buffer));
454 wprintf(L"%lu: %s,%-3lu", i, Buffer, scid.pid);
456 if (PSGNFPK && SUCCEEDED(PSGNFPK(&scid, &str)) && str)
457 wprintf(L" %s", (PWSTR)str);
458 wprintf(L"\n");
459 }
460 return columns ? S_OK : S_FALSE;
461}
Definition: bufpool.h:45
#define E_NOTIMPL
Definition: ddrawi.h:99
INT WINAPI StringFromGUID2(REFGUID guid, LPOLESTR str, INT cmax)
Definition: combase.c:1525
int(* FARPROC)()
Definition: compat.h:36
#define GetProcAddress(x, y)
Definition: compat.h:753
#define LoadLibraryW(x)
Definition: compat.h:747
HRESULT WINAPI StrRetToStrW(LPSTRRET lpStrRet, const ITEMIDLIST *pidl, LPWSTR *ppszName)
Definition: string.c:349
GLbitfield flags
Definition: glext.h:7161
#define S_OK
Definition: intsafe.h:52
static const WCHAR sd[]
Definition: suminfo.c:286
#define REFIID
Definition: guiddef.h:118
const WCHAR * str
DWORD SHCOLSTATEF
Definition: shtypes.idl:142
#define max(a, b)
Definition: svc.c:63
uint32_t ULONG
Definition: typedefs.h:59
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451

Referenced by wmain().

◆ DumpHexBytes()

static void DumpHexBytes ( LPCVOID  Buffer,
SIZE_T  cb 
)
static

Definition at line 222 of file shlextdbg.cpp.

223{
224 UINT cbPerLine = 16, cbLine;
225 for (SIZE_T i = 0, j; i < cb; i += cbLine)
226 {
227 cbLine = min(cbPerLine, cb - i);
228 for (j = 0; j < cbLine; ++j) wprintf(L" %.2X", ((BYTE*)Buffer)[i + j]);
229 for (j = 0; j < cbPerLine - cbLine; ++j) wprintf(L" ");
230 for (j = 0; j < cbLine; ++j) wprintf(L"%s%c", !j ? L" " : L"", SafeDumpChar(((BYTE*)Buffer)[i + j]));
231 for (j = 0; j < cbPerLine - cbLine; ++j) wprintf(L" ");
232 wprintf(L"\n");
233 }
234}
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
static CHAR SafeDumpChar(UINT Ch)
Definition: shlextdbg.cpp:217
unsigned char BYTE
Definition: xxhash.c:193

Referenced by DumpPidl().

◆ DumpMenu()

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

Definition at line 255 of file shlextdbg.cpp.

256{
257 bool recurse = Indent != UINT(-1);
259 MENUITEMINFOW mii;
260 mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem);
261
262 for (UINT i = 0, defid = GetMenuDefaultItem(hMenu, FALSE, 0); ; ++i)
263 {
264 mii.fMask = MIIM_STRING;
265 mii.dwTypeData = buf;
266 mii.cch = _countof(buf);
267 *buf = UNICODE_NULL;
268 if (!GetMenuItemInfo(hMenu, i, TRUE, &mii))
269 lstrcpynW(buf, L"?", _countof(buf)); // Tolerate string failure
271 mii.hSubMenu = NULL;
272 mii.dwTypeData = NULL;
273 mii.cch = 0;
274 if (!GetMenuItemInfo(hMenu, i, TRUE, &mii))
275 break;
276
277 BOOL sep = mii.fType & MFT_SEPARATOR;
278 wprintf(L"%-4d", (sep || mii.wID == UINT(-1)) ? mii.wID : (mii.wID - IdOffset));
279 for (UINT j = 0; j < Indent && recurse; ++j)
280 wprintf(L" ");
281 wprintf(L"%s%s", mii.hSubMenu ? L">" : L"|", sep ? L"----------" : buf);
282 if (!sep && pCM && SUCCEEDED(GetCommandString(*pCM, mii.wID - IdOffset,
283 GCS_VERB, buf, _countof(buf))))
284 {
285 wprintf(L" [%s]", buf);
286 }
287 wprintf(L"%s\n", (defid == mii.wID && defid != UINT(-1)) ? L" (Default)" : L"");
288 if (mii.hSubMenu && recurse)
289 {
290 if (FakeInit)
292 DumpMenu(mii.hSubMenu, IdOffset, pCM, FakeInit, Indent + 1);
293 }
294 }
295}
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
UINT_PTR WPARAM
Definition: minwindef.h:174
#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:236
static void DumpMenu(HMENU hMenu, UINT IdOffset, IContextMenu *pCM, BOOL FakeInit, UINT Indent)
Definition: shlextdbg.cpp:255
LPWSTR dwTypeData
Definition: winuser.h:3377
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
UINT WINAPI GetMenuDefaultItem(_In_ HMENU hMenu, _In_ UINT fByPos, _In_ UINT gmdiFlags)
#define MIIM_STRING
Definition: winuser.h:738
#define MIIM_ID
Definition: winuser.h:733
#define MIIM_FTYPE
Definition: winuser.h:740
#define MFT_SEPARATOR
Definition: winuser.h:755
#define MIIM_SUBMENU
Definition: winuser.h:734
#define WM_INITMENUPOPUP
Definition: winuser.h:1774
#define GetMenuItemInfo
Definition: winuser.h:5954

Referenced by DumpMenu(), and wmain().

◆ DumpPidl()

static HRESULT DumpPidl ( PCWSTR  Path)
static

Definition at line 342 of file shlextdbg.cpp.

343{
344 PIDLIST_ABSOLUTE pidl;
347 if (FAILED(hr))
348 {
349 wprintf(L"Can't parse %s\n", Path);
350 return hr;
351 }
352
353 UINT lvl = 0;
354 for (PUITEMID_CHILD p = pidl; p; ++lvl)
355 {
356 if (!p->mkid.cb && p > pidl)
357 break;
358 PUITEMID_CHILD pNext = ILGetNext(p);
359 const WORD save = pNext ? pNext->mkid.cb : 0;
360 if (pNext)
361 pNext->mkid.cb = 0;
362 wprintf(L"#%u %ub", lvl, p->mkid.cb);
363
364 WCHAR buf[100];
365 VARIANT v;
366 V_VT(&v) = VT_EMPTY;
367 static const SHCOLUMNID pkey_descriptionid = { FMTID_ShellDetails, PID_DESCRIPTIONID };
368 CComPtr<IShellFolder2> pParentFolder;
369 PCUITEMID_CHILD pidlChildSelf;
370 hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder2, &pParentFolder), &pidlChildSelf);
371 if (SUCCEEDED(hr) && SUCCEEDED(hr = pParentFolder->GetDetailsEx(pidlChildSelf, &pkey_descriptionid, &v)))
372 {
373 if (V_VT(&v) == (VT_UI1 | VT_ARRAY))
374 {
375 const SHDESCRIPTIONID &shdid = *(SHDESCRIPTIONID*)V_ARRAY(&v)->pvData;
377 PCWSTR did = L"?";
378 switch (shdid.dwDescriptionId)
379 {
380 case SHDID_ROOT_REGITEM: did = L"ROOT_REGITEM"; break;
381 case SHDID_FS_FILE: did = L"FS_FILE"; break;
382 case SHDID_FS_DIRECTORY: did = L"FS_DIRECTORY"; break;
383 case SHDID_FS_OTHER: did = L"FS_OTHER"; break;
384 case SHDID_COMPUTER_FIXED: did = L"COMPUTER_FIXED"; break;
385 }
386 wprintf(L" %s %s(%#.2x)", buf, did, shdid.dwDescriptionId);
387 }
388 PropVariantClear((PROPVARIANT*)&v); // No need to drag in oleaut32, ole32 knows how to handle this
389 }
390 wprintf(L"\n");
391 DumpHexBytes(p->mkid.abID, p->mkid.cb > 2 ? p->mkid.cb - 2 : 0);
392
393 if (pNext)
394 pNext->mkid.cb = save;
395 p = pNext;
396 }
397 SHFree(pidl);
398 return S_OK;
399}
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: combase.c:709
@ VT_ARRAY
Definition: compat.h:2341
@ VT_EMPTY
Definition: compat.h:2295
@ VT_UI1
Definition: compat.h:2311
unsigned short WORD
Definition: ntddk_ex.h:93
const GLdouble * v
Definition: gl.h:2040
GLfloat GLfloat p
Definition: glext.h:8902
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_VT(A)
Definition: oleauto.h:211
LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl)
Definition: pidl.c:977
static void DumpHexBytes(LPCVOID Buffer, SIZE_T cb)
Definition: shlextdbg.cpp:222
#define PID_DESCRIPTIONID
Definition: shlguid.h:175
#define SHDID_FS_DIRECTORY
Definition: shlobj.h:1474
#define SHDID_COMPUTER_FIXED
Definition: shlobj.h:1479
#define SHDID_FS_OTHER
Definition: shlobj.h:1475
#define SHDID_FS_FILE
Definition: shlobj.h:1473
#define SHDID_ROOT_REGITEM
Definition: shlobj.h:1472
ITEMID_CHILD UNALIGNED * PUITEMID_CHILD
Definition: shtypes.idl:68
DWORD dwDescriptionId
Definition: shlobj.h:1496

Referenced by wmain().

◆ EnumWindowsProc()

BOOL CALLBACK EnumWindowsProc ( HWND  hwnd,
LPARAM  lParam 
)

Definition at line 682 of file shlextdbg.cpp.

683{
684 if (hwnd != g_ConsoleWindow)
685 {
686 DWORD pid = 0;
688 if (pid == GetCurrentProcessId())
689 {
690 g_Windows.Add(hwnd);
691 }
692 }
693 return TRUE;
694}
CSimpleArray< HWND > g_Windows
Definition: shlextdbg.cpp:680
HWND g_ConsoleWindow
Definition: shlextdbg.cpp:681
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1155
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 78 of file shlextdbg.cpp.

79{
80 WCHAR buf[400];
81 for (UINT e = Error, cch; ;)
82 {
83 lstrcpynW(buf, L"?", _countof(buf));
85 while (cch && buf[cch - 1] <= ' ')
86 buf[--cch] = UNICODE_NULL; // Remove trailing newlines
87 if (cch || HIWORD(e) != HIWORD(HRESULT_FROM_WIN32(1)))
88 break;
89 e = HRESULT_CODE(e); // "WIN32_FROM_HRESULT"
90 }
91 wprintf(Error < 0 ? L"Error 0x%.8X %s\n" : L"Error %d %s\n", Error, buf);
92 return Error;
93}
BOOL Error
Definition: chkdsk.c:66
#define e
Definition: ke_i.h:82
_In_ UINT _In_ UINT cch
Definition: shellapi.h:432
#define HIWORD(l)
Definition: typedefs.h:247
#define FormatMessage
Definition: winbase.h:3516
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:397
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:400
#define HRESULT_CODE(hr)
Definition: winerror.h:188

Referenced by AssocQ(), SHGFI(), and wmain().

◆ GetAssocClass()

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

Definition at line 168 of file shlextdbg.cpp.

169{
170 hKey = NULL;
171 IQueryAssociations* pQA;
172 if (SUCCEEDED(GetUIObjectOfAbsolute(pidl, IID_PPV_ARG(IQueryAssociations, &pQA))))
173 {
174 pQA->GetKey(0, ASSOCKEY_CLASS, NULL, &hKey); // Not implemented in ROS
175 pQA->Release();
176 }
177 if (!hKey)
178 {
179 DWORD cb;
183 info.dwAttributes = 0;
185 if (info.dwAttributes & SFGAO_FOLDER)
186 {
187 ext = const_cast<LPWSTR>(L"Directory");
188 }
189 else if (info.dwAttributes & SFGAO_BROWSABLE)
190 {
191 ext = const_cast<LPWSTR>(L"Folder"); // Best guess
192 }
193 else
194 {
195 cb = sizeof(buf);
197 {
199 }
200 }
201 if (!hKey)
202 {
204 }
205 }
206}
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(const WCHAR *path)
Definition: path.c:1250
DWORD WINAPI SHGetValueW(HKEY hkey, const WCHAR *subkey, const WCHAR *value, DWORD *type, void *data, DWORD *data_len)
Definition: main.c:2222
#define KEY_READ
Definition: nt_native.h:1026
@ ASSOCKEY_CLASS
Definition: shlwapi.h:921
DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
Definition: shell32_main.c:430
#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:143
uint16_t * LPWSTR
Definition: typedefs.h:56
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10

Referenced by LoadAndInitialize().

◆ GetCommandString()

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

Definition at line 236 of file shlextdbg.cpp.

237{
238 if (cchMax < 1) return E_INVALIDARG;
239 *buf = UNICODE_NULL;
240
241 // First try to retrieve the UNICODE string directly
242 HRESULT hr = CM.GetCommandString(Id, Type | GCS_UNICODE, 0, (char*)buf, cchMax);
243 if (FAILED(hr))
244 {
245 // It failed, try to retrieve an ANSI string instead then convert it to UNICODE
246 STRRET sr;
247 sr.uType = STRRET_CSTR;
248 hr = CM.GetCommandString(Id, Type & ~GCS_UNICODE, 0, sr.cStr, _countof(sr.cStr));
249 if (SUCCEEDED(hr))
250 hr = StrRetToBufW(&sr, NULL, buf, cchMax);
251 }
252 return hr;
253}
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:248
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().

◆ GetLoggingServiceProvider()

static IServiceProvider * GetLoggingServiceProvider ( )
static

Definition at line 137 of file shlextdbg.cpp.

138{
139 static CLoggingServiceProvider g_SP;
140 return &g_SP;
141}

Referenced by wmain().

◆ GetUIObjectOfAbsolute()

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

Definition at line 143 of file shlextdbg.cpp.

144{
145 CComPtr<IShellFolder> shellFolder;
147 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shellFolder), &child);
148 if (SUCCEEDED(hr))
149 hr = shellFolder->GetUIObjectOf(NULL, 1, &child, riid, NULL, ppv);
150 return hr;
151}
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 815 of file shlextdbg.cpp.

816{
817 return !_wcsicmp(argv[n] + 1, check);
818}
#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 791 of file shlextdbg.cpp.

792{
793 arg = NULL;
794 size_t len = wcslen(check);
795 if (!_wcsnicmp(argv[n] + 1, check, len))
796 {
797 PCWSTR cmd = argv[n] + len + 1;
798 if (*cmd == ':' || *cmd == '=')
799 {
800 arg = cmd + 1;
801 return true;
802 }
803 if (n + 1 < argc)
804 {
805 arg = argv[n+1];
806 n++;
807 return true;
808 }
809 wprintf(L"Command %s has no required argument!\n", check);
810 return false;
811 }
812 return false;
813}
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
_ACRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:200
GLenum GLsizei len
Definition: glext.h:6722
Definition: ftp_var.h:139

Referenced by wmain().

◆ LoadAndInitialize()

HRESULT LoadAndInitialize ( REFIID  riid,
LPVOID ppv 
)

Definition at line 608 of file shlextdbg.cpp.

609{
610 CComPtr<IShellExtInit> spShellExtInit;
611 HRESULT hr;
612 if (g_DLL.IsEmpty())
613 {
614 hr = CoCreateInstance(g_CLSID, NULL, CLSCTX_ALL, IID_PPV_ARG(IShellExtInit, &spShellExtInit));
615 if (!SUCCEEDED(hr))
616 {
617 WCHAR Buffer[100];
619 wprintf(L"Failed to Create %s:IShellExtInit: 0x%x\n", Buffer, hr);
620 return hr;
621 }
622 }
623 else
624 {
625 typedef HRESULT (STDAPICALLTYPE *tDllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
627 if (!mod)
628 {
629 wprintf(L"Failed to Load %s:(0x%x)\n", g_DLL.GetString(), GetLastError());
630 return E_FAIL;
631 }
632 tDllGetClassObject DllGet = (tDllGetClassObject)GetProcAddress(mod, "DllGetClassObject");
633 if (!DllGet)
634 {
635 wprintf(L"%s does not export DllGetClassObject\n", g_DLL.GetString());
636 return E_FAIL;
637 }
638 CComPtr<IClassFactory> spClassFactory;
639 hr = DllGet(g_CLSID, IID_PPV_ARG(IClassFactory, &spClassFactory));
640 if (!SUCCEEDED(hr))
641 {
642 wprintf(L"Failed to create IClassFactory: 0x%x\n", hr);
643 return hr;
644 }
645 hr = spClassFactory->CreateInstance(NULL, IID_PPV_ARG(IShellExtInit, &spShellExtInit));
646 if (!SUCCEEDED(hr))
647 {
648 wprintf(L"Failed to Request IShellExtInit from IClassFactory: 0x%x\n", hr);
649 return hr;
650 }
651 }
652
653 CComPtr<IDataObject> spDataObject;
655 hr = CreateIDataObject(pidl, spDataObject, g_ShellExtInit.GetString());
656 if (!SUCCEEDED(hr))
657 return hr;
658
659 HKEY hKey = NULL;
661 hr = spShellExtInit->Initialize(pidl, spDataObject, hKey);
662 if (hKey)
664 if (!SUCCEEDED(hr))
665 {
666 wprintf(L"IShellExtInit->Initialize failed: 0x%x\n", hr);
667 return hr;
668 }
669 hr = spShellExtInit->QueryInterface(riid, ppv);
670 if (!SUCCEEDED(hr))
671 {
672 WCHAR Buffer[100];
674 wprintf(L"Failed to query %s from IShellExtInit: 0x%x\n", Buffer, hr);
675 }
676 return hr;
677}
std::map< E_MODULE, HMODULE > mod
Definition: LocaleTests.cpp:68
bool IsEmpty() const noexcept
Definition: atlsimpstr.h:394
PXSTR GetString() noexcept
Definition: atlsimpstr.h:367
#define E_FAIL
Definition: ddrawi.h:102
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
#define STDAPICALLTYPE
Definition: guid.c:3
#define REFCLSID
Definition: guiddef.h:117
CLSID g_CLSID
Definition: shlextdbg.cpp:576
static void GetAssocClass(LPCWSTR Path, LPCITEMIDLIST pidl, HKEY &hKey)
Definition: shlextdbg.cpp:168
CStringW g_ShellExtInit
Definition: shlextdbg.cpp:578
HRESULT CreateIDataObject(CComHeapPtr< ITEMIDLIST > &pidl, CComPtr< IDataObject > &dataObject, PCWSTR FileName)
Definition: shlextdbg.cpp:583
CStringW g_DLL
Definition: shlextdbg.cpp:577
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 wprintf(L"shlextdbg /dumpfoldercolumns=folder\n");
48 wprintf(L"shlextdbg /dumppidl=path\n");
49}

◆ SafeDumpChar()

static CHAR SafeDumpChar ( UINT  Ch)
inlinestatic

Definition at line 217 of file shlextdbg.cpp.

218{
219 return Ch <= 255 && isprint(static_cast<BYTE>(Ch)) ? (BYTE)Ch : '.';
220}
#define Ch(x, y, z)
Definition: sha2.c:141

Referenced by DumpHexBytes().

◆ SHGFI()

static int SHGFI ( PCWSTR  Path)
static

Definition at line 297 of file shlextdbg.cpp.

298{
299 PIDLIST_ABSOLUTE pidl = NULL;
300 UINT flags = 0, ret = 0;
301
302 if (*Path == L'$')
303 {
304 HRESULT hr = SHParseDisplayName(++Path, NULL, &pidl, 0, NULL);
305 if (FAILED(hr))
306 return ErrMsg(hr);
307 flags |= SHGFI_PIDL;
308 Path = (LPCWSTR)pidl;
309 }
311 {
313 }
315 if (!SHGetFileInfoW(Path, 0, &info, sizeof(info), flags |
317 {
318 info.szDisplayName[0] = info.szTypeName[0] = UNICODE_NULL;
319 info.dwAttributes = 0;
321 }
322 wprintf(L"Display: %s\n", info.szDisplayName);
323 wprintf(L"Attributes: 0x%x\n", info.dwAttributes);
324 wprintf(L"Type: %s\n", info.szTypeName);
325
326 if (!SHGetFileInfoW(Path, 0, &info, sizeof(info), flags | SHGFI_ICONLOCATION))
327 {
328 info.szDisplayName[0] = UNICODE_NULL;
329 info.iIcon = -1;
330 }
331 wprintf(L"Icon: %s,%d\n", info.szDisplayName, info.iIcon);
332
333 if (!SHGetFileInfoW(Path, 0, &info, sizeof(info), flags | SHGFI_SYSICONINDEX))
334 {
335 info.iIcon = -1;
336 }
337 wprintf(L"Index: %d\n", info.iIcon);
338 SHFree(pidl);
339 return ret;
340}
return ret
Definition: mutex.c:147
#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
const uint16_t * LPCWSTR
Definition: typedefs.h:57
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
#define GetFileAttributes
Definition: winbase.h:3536

Referenced by wmain().

◆ StrToNum()

static LONG StrToNum ( PCWSTR  in)
static

Definition at line 71 of file shlextdbg.cpp.

72{
73 PWCHAR end;
74 LONG v = wcstol(in, &end, 0);
75 return (end > in) ? v : 0;
76}
_ACRTIMP __msvcrt_long __cdecl wcstol(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2752
GLuint GLuint end
Definition: gl.h:1545
GLuint in
Definition: glext.h:9616
long LONG
Definition: pedump.c:60
uint16_t * PWCHAR
Definition: typedefs.h:56

Referenced by AssocQ().

◆ Wait()

static void Wait ( )
static

Definition at line 754 of file shlextdbg.cpp.

755{
756 LPCWSTR nag = L"(Please use SHGetInstanceExplorer in your code instead)";
757 switch (g_Wait)
758 {
759 case Wait_None:
760 break;
761 case Wait_Infinite:
762 _putws(nag);
763 while (true)
764 Sleep(1000);
765 break;
766 case Wait_OpenWindows:
767 _putws(nag);
768 WaitWindows();
769 break;
770 case Wait_Input:
771 wprintf(L"Press any key to continue... %s\n", nag);
772 _getch();
773 break;
775 g_EI.Wait();
776 break;
777 }
778}
int CDECL _getch(void)
Definition: console.c:218
int CDECL _putws(const wchar_t *s)
Definition: file.c:4942
WaitType g_Wait
Definition: shlextdbg.cpp:581
ExplorerInstance g_EI
void WaitWindows()
Definition: shlextdbg.cpp:696
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726

Referenced by wmain().

◆ WaitWindows()

void WaitWindows ( )

Definition at line 696 of file shlextdbg.cpp.

697{
698 /* Give the windows some time to spawn */
699 Sleep(2000);
701 while (true)
702 {
703 g_Windows.RemoveAll();
705 if (g_Windows.GetSize() == 0)
706 break;
707 Sleep(500);
708 }
709 wprintf(L"All windows closed (ignoring console window)\n");
710}
HWND WINAPI GetConsoleWindow(void)
Definition: console.c:1102
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
Definition: shlextdbg.cpp:682
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)

Referenced by Wait().

◆ wmain()

int wmain ( int  argc,
WCHAR **  argv 
)

Definition at line 821 of file shlextdbg.cpp.

822{
826 SHSetInstanceExplorer(static_cast<IUnknown*>(&g_EI));
827
828 bool failArgs = false;
829 for (int n = 1; n < argc; ++n)
830 {
831 WCHAR* cmd = argv[n];
832 if (cmd[0] == '-' || cmd[0] == '/')
833 {
834 PCWSTR arg;
835 if (isCmdWithArg(argc, argv, n, L"shgfi", arg))
836 {
837 failArgs = true;
838 if (*arg)
839 return SHGFI(arg);
840 }
841 else if (isCmd(argc, argv, n, L"assocq"))
842 {
843 failArgs = true;
844 if (argc - (n + 1) >= 6 && argc - (n + 1) <= 8)
845 return AssocQ(argc - (n + 1), &argv[(n + 1)]);
846 }
847 else if (isCmdWithArg(argc, argv, n, L"shellexec", arg))
848 {
849 PIDLIST_ABSOLUTE pidl = NULL;
850 HRESULT hr = SHParseDisplayName(arg, NULL, &pidl, 0, NULL);
851 if (FAILED(hr))
852 return ErrMsg(hr);
853 SHELLEXECUTEINFOW sei = { sizeof(sei), SEE_MASK_IDLIST | SEE_MASK_UNICODE };
854 sei.lpIDList = pidl;
855 sei.nShow = SW_SHOW;
856 while (++n < argc)
857 {
858 if (argv[n][0] != '-' && argv[n][0] != '/')
859 break;
860 else if (isCmd(argc, argv, n, L"MIN"))
862 else if (isCmd(argc, argv, n, L"MAX"))
864 else if (isCmd(argc, argv, n, L"INVOKE"))
866 else if (isCmd(argc, argv, n, L"NOUI"))
868 else if (isCmd(argc, argv, n, L"ASYNCOK"))
869 sei.fMask |= SEE_MASK_ASYNCOK ;
870 else if (isCmd(argc, argv, n, L"NOASYNC"))
871 sei.fMask |= SEE_MASK_NOASYNC;
872 else if (isCmd(argc, argv, n, L"NOCONSOLE"))
874 else if (isCmd(argc, argv, n, L"1000"))
875 sei.fMask |= 0x00001000; // Unknown flag
876 else if (isCmd(argc, argv, n, L"NOHOOKS"))
877 sei.fMask |= 0x00002000;
878 else if (isCmd(argc, argv, n, L"SITE"))
879 {
880 sei.fMask |= 0x08000000; // SEE_MASK_FLAG_HINST_IS_SITE
882 }
883 else if (isCmd(argc, argv, n, L"FILL"))
884 {
885 sei.hInstApp = (HINSTANCE)UlongToHandle(0xCAFE);
886 sei.hProcess = UlongToHandle(0xDEADF00D);
887 }
888 else
889 wprintf(L"WARN: Ignoring switch %s\n", argv[n]);
890 }
891 if (n < argc && *argv[n++])
892 {
893 sei.lpVerb = argv[n - 1];
894 }
895 if (n < argc && *argv[n++])
896 {
897 sei.lpClass = argv[n - 1];
899 }
900 UINT succ = ShellExecuteExW(&sei), gle = GetLastError();
901 SHFree(pidl);
902 if (!succ)
903 return ErrMsg(gle);
904 Wait();
905 return 0;
906 }
907 else if (isCmdWithArg(argc, argv, n, L"dumpmenu", arg))
908 {
909 HRESULT hr;
911 if (CLSIDPrefix(arg, g_CLSID))
912 {
915 }
916 else
917 {
920 if (SUCCEEDED(hr))
921 hr = si->BindToHandler(NULL, BHID_SFUIObject, IID_PPV_ARG(IContextMenu, &cm));
922 }
923 if (SUCCEEDED(hr))
924 {
925 UINT first = 10, last = 9000;
926 UINT cmf = 0, nosub = 0, fakeinit = 0;
927 while (++n < argc)
928 {
929 if (argv[n][0] != '-' && argv[n][0] != '/')
930 break;
931 else if (isCmd(argc, argv, n, L"DEFAULTONLY"))
932 cmf |= CMF_DEFAULTONLY;
933 else if (isCmd(argc, argv, n, L"NODEFAULT"))
934 cmf |= CMF_NODEFAULT;
935 else if (isCmd(argc, argv, n, L"DONOTPICKDEFAULT"))
936 cmf |= CMF_DONOTPICKDEFAULT;
937 else if (isCmd(argc, argv, n, L"EXTENDED") || isCmd(argc, argv, n, L"EXTENDEDVERBS"))
938 cmf |= CMF_EXTENDEDVERBS;
939 else if (isCmd(argc, argv, n, L"SYNCCASCADEMENU"))
940 cmf |= CMF_SYNCCASCADEMENU;
941 else if (isCmd(argc, argv, n, L"EXPLORE"))
942 cmf |= CMF_EXPLORE;
943 else if (isCmd(argc, argv, n, L"VERBSONLY"))
944 cmf |= CMF_VERBSONLY;
945 else if (isCmd(argc, argv, n, L"NOVERBS"))
946 cmf |= CMF_NOVERBS;
947 else if (isCmd(argc, argv, n, L"DISABLEDVERBS"))
948 cmf |= CMF_DISABLEDVERBS;
949 else if (isCmd(argc, argv, n, L"OPTIMIZEFORINVOKE"))
950 cmf |= CMF_OPTIMIZEFORINVOKE;
951 else if (isCmd(argc, argv, n, L"CANRENAME"))
952 cmf |= CMF_CANRENAME;
953 else if (isCmd(argc, argv, n, L"NOSUBMENU"))
954 nosub++;
955 else if (isCmd(argc, argv, n, L"INITMENUPOPUP"))
956 fakeinit++; // Tickle async submenus
957 else
958 wprintf(L"WARN: Ignoring switch %s\n", argv[n]);
959 }
960 HMENU hMenu = CreatePopupMenu();
961 hr = cm->QueryContextMenu(hMenu, 0, first, last, cmf);
962 if (SUCCEEDED(hr))
963 {
964 DumpMenu(hMenu, first, cm, fakeinit, nosub ? -1 : 0);
965 }
966 DestroyMenu(hMenu);
967 }
968 if (FAILED(hr))
969 return ErrMsg(hr);
970 return 0;
971 }
972 else if (isCmdWithArg(argc, argv, n, L"dumpfoldercolumns", arg))
973 {
974 return DumpFolderColumns(arg);
975 }
976 else if (isCmdWithArg(argc, argv, n, L"dumppidl", arg))
977 {
978 return DumpPidl(arg);
979 }
980 else if (isCmdWithArg(argc, argv, n, L"clsid", arg))
981 {
983 if (!SUCCEEDED(hr))
984 {
985 wprintf(L"Failed to convert %s to CLSID\n", arg);
986 failArgs = true;
987 }
988 }
989 else if (isCmdWithArg(argc, argv, n, L"dll", arg))
990 {
991 g_DLL = arg;
992 }
993 else if (isCmdWithArg(argc, argv, n, L"IShellExtInit", arg))
994 {
996 }
997 else if (isCmd(argc, argv, n, L"IShellPropSheetExt"))
998 {
1000 }
1001 else if (isCmdWithArg(argc, argv, n, L"IContextMenu", arg))
1002 {
1004 }
1005 else if (isCmd(argc, argv, n, L"infinite"))
1006 {
1008 }
1009 else if (isCmd(argc, argv, n, L"openwindows"))
1010 {
1012 }
1013 else if (isCmd(argc, argv, n, L"input"))
1014 {
1016 }
1017 else if (isCmd(argc, argv, n, L"explorerinstance"))
1018 {
1020 }
1021 else if (isCmd(argc, argv, n, L"nowait"))
1022 {
1023 g_Wait = Wait_None;
1024 }
1025 else
1026 {
1027 wprintf(L"Unknown argument: %s\n", cmd);
1028 failArgs = true;
1029 }
1030 }
1031 }
1032
1033 if (failArgs)
1034 {
1035 PrintHelp(NULL);
1036 return E_INVALIDARG;
1037 }
1038
1039 CLSID EmptyCLSID = { 0 };
1040 if (EmptyCLSID == g_CLSID)
1041 {
1042 PrintHelp(L"No CLSID specified");
1043 return E_INVALIDARG;
1044 }
1045
1046 if (g_ShellExtInit.IsEmpty())
1047 {
1048 PrintHelp(L"No filename specified");
1049 return E_INVALIDARG;
1050 }
1051
1052 HRESULT hr;
1054 {
1055 CComPtr<IShellPropSheetExt> spSheetExt;
1057 if (!SUCCEEDED(hr))
1058 return hr;
1059
1060 hr = spSheetExt->AddPages(cb_AddPage, (LPARAM)&g_Pages);
1061 if (!SUCCEEDED(hr))
1062 {
1063 wprintf(L"IShellPropSheetExt->AddPages failed: 0x%x\n", hr);
1064 return hr;
1065 }
1066
1067 USHORT ActivePage = HRESULT_CODE(hr);
1068 PROPSHEETHEADERW psh = { 0 };
1069
1070 psh.dwSize = sizeof(psh);
1071 psh.dwFlags = PSH_PROPTITLE;
1072 psh.pszCaption = L"shlextdbg";
1073 psh.phpage = g_Pages.GetData();
1074 psh.nPages = g_Pages.GetSize();
1075 psh.nStartPage = ActivePage ? (ActivePage-1) : 0;
1076 hr = PropertySheetW(&psh);
1077
1078 wprintf(L"PropertySheetW returned: 0x%x\n", hr);
1079 }
1080 if (!g_ContextMenu.IsEmpty())
1081 {
1082 CComPtr<IContextMenu> spContextMenu;
1083 hr = LoadAndInitialize(IID_PPV_ARG(IContextMenu, &spContextMenu));
1084 if (!SUCCEEDED(hr))
1085 return hr;
1086
1087 // FIXME: Must call QueryContextMenu before InvokeCommand?
1088
1089 CMINVOKECOMMANDINFO cm = { sizeof(cm), 0 };
1090 cm.lpVerb = g_ContextMenu.GetString();
1091 cm.nShow = SW_SHOW;
1092 hr = spContextMenu->InvokeCommand(&cm);
1093
1094 if (!SUCCEEDED(hr))
1095 {
1096 wprintf(L"IContextMenu->InvokeCommand failed: 0x%x\n", hr);
1097 return hr;
1098 }
1099 wprintf(L"IContextMenu->InvokeCommand returned: 0x%x\n", hr);
1100 }
1101
1102 Wait();
1103 return 0;
1104}
#define UlongToHandle(ul)
Definition: basetsd.h:91
BOOL WINAPI InitCommonControlsEx(const INITCOMMONCONTROLSEX *lpInitCtrls)
Definition: commctrl.c:904
INT_PTR WINAPI PropertySheetW(LPCPROPSHEETHEADERW lppsh)
Definition: propsheet.c:2950
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:531
const GLint * first
Definition: glext.h:5794
if(dx< 0)
Definition: linetemp.h:194
static const LARGE_INTEGER *static const HANDLE const LARGE_INTEGER *static PSLIST_ENTRY PSLIST_ENTRY last
Definition: sync.c:64
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
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:40
#define SEE_MASK_CLASSNAME
Definition: shellapi.h:25
#define SEE_MASK_ASYNCOK
Definition: shellapi.h:43
#define SEE_MASK_IDLIST
Definition: shellapi.h:27
#define SEE_MASK_NOASYNC
Definition: shellapi.h:35
#define SEE_MASK_INVOKEIDLIST
Definition: shellapi.h:28
#define SEE_MASK_FLAG_NO_UI
Definition: shellapi.h:38
#define SEE_MASK_NO_CONSOLE
Definition: shellapi.h:41
VOID WINAPI SHSetInstanceExplorer(LPUNKNOWN lpUnknown)
Definition: shellord.c:1714
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2732
CStringA g_ContextMenu
Definition: shlextdbg.cpp:580
static BOOL CALLBACK cb_AddPage(HPROPSHEETPAGE page, LPARAM lParam)
Definition: shlextdbg.cpp:781
static void Wait()
Definition: shlextdbg.cpp:754
static IServiceProvider * GetLoggingServiceProvider()
Definition: shlextdbg.cpp:137
static HRESULT DumpPidl(PCWSTR Path)
Definition: shlextdbg.cpp:342
static bool isCmdWithArg(int argc, WCHAR **argv, int &n, PCWSTR check, PCWSTR &arg)
Definition: shlextdbg.cpp:791
static bool isCmd(int argc, WCHAR **argv, int n, PCWSTR check)
Definition: shlextdbg.cpp:815
HRESULT LoadAndInitialize(REFIID riid, LPVOID *ppv)
Definition: shlextdbg.cpp:608
bool g_bIShellPropSheetExt
Definition: shlextdbg.cpp:579
static HRESULT DumpFolderColumns(PCWSTR Path)
Definition: shlextdbg.cpp:401
static int SHGFI(PCWSTR Path)
Definition: shlextdbg.cpp:297
static HRESULT AssocQ(int argc, WCHAR **argv)
Definition: shlextdbg.cpp:463
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
HINSTANCE hInstApp
Definition: shellapi.h:342
HANDLE HINSTANCE
Definition: typedefs.h:77
void * arg
Definition: msvc.h:10
#define SW_SHOWMAXIMIZED
Definition: winuser.h:784
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define SW_SHOW
Definition: winuser.h:786
#define SW_SHOWMINNOACTIVE
Definition: winuser.h:788

Variable Documentation

◆ g_bIShellPropSheetExt

bool g_bIShellPropSheetExt = false

Definition at line 579 of file shlextdbg.cpp.

Referenced by wmain().

◆ g_CLSID

CLSID g_CLSID = { 0 }

Definition at line 576 of file shlextdbg.cpp.

Referenced by LoadAndInitialize(), and wmain().

◆ g_ConsoleWindow

HWND g_ConsoleWindow

Definition at line 681 of file shlextdbg.cpp.

Referenced by EnumWindowsProc(), and WaitWindows().

◆ g_ContextMenu

CStringA g_ContextMenu

Definition at line 580 of file shlextdbg.cpp.

Referenced by wmain().

◆ g_DLL

CStringW g_DLL

Definition at line 577 of file shlextdbg.cpp.

Referenced by LoadAndInitialize(), and wmain().

◆ g_EI

Referenced by Wait(), and wmain().

◆ g_Pages

Definition at line 780 of file shlextdbg.cpp.

Referenced by cb_AddPage(), and wmain().

◆ g_ShellExtInit

CStringW g_ShellExtInit

Definition at line 578 of file shlextdbg.cpp.

Referenced by LoadAndInitialize(), and wmain().

◆ g_Wait

◆ g_Windows

CSimpleArray<HWND> g_Windows

Definition at line 680 of file shlextdbg.cpp.

Referenced by EnumWindowsProc(), and WaitWindows().