ReactOS 0.4.17-dev-470-gf9e3448
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 564 of file shlextdbg.cpp.

565{
566 Wait_None,
571};
@ Wait_OpenWindows
Definition: shlextdbg.cpp:568
@ Wait_Input
Definition: shlextdbg.cpp:569
@ Wait_Infinite
Definition: shlextdbg.cpp:567
@ Wait_ExplorerInstance
Definition: shlextdbg.cpp:570
@ Wait_None
Definition: shlextdbg.cpp:566

Function Documentation

◆ AssocQ()

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

Definition at line 460 of file shlextdbg.cpp.

461{
462 UINT qtype = StrToNum(argv[2]);
463 ASSOCF iflags = StrToNum(argv[3]);
464 ASSOCF qflags = StrToNum(argv[4]);
465 PCWSTR extra = (argc > 6 && *argv[6]) ? argv[6] : NULL;
466 WCHAR buf[MAX_PATH * 2];
467 DWORD maxSize = (argc > 7 && *argv[7]) ? StrToNum(argv[7]) : sizeof(buf);
468
469 HRESULT hr;
471 PWSTR path = argv[0];
472 if (*path)
473 {
474 CLSID clsid, *pclsid = NULL;
475 if (CLSIDPrefix(path, clsid))
476 pclsid = &clsid;
479 {
480 hr = si->BindToHandler(NULL, pclsid ? *pclsid : BHID_AssociationArray, IID_PPV_ARG(IQueryAssociations, &qa));
481 if (FAILED(hr) && !pclsid)
482 hr = si->BindToHandler(NULL, BHID_SFUIObject, IID_PPV_ARG(IQueryAssociations, &qa));
483 }
484 }
485 else
486 {
487 hr = AssocCreate(CLSID_QueryAssociations, IID_PPV_ARG(IQueryAssociations, &qa));
488 }
489 if (FAILED(hr))
490 return ErrMsg(hr);
491 hr = qa->Init(iflags, argv[5], NULL, NULL);
492 if (FAILED(hr))
493 return ErrMsg(hr);
494
495 DWORD size = maxSize;
496 if (!_wcsicmp(argv[1], L"string"))
497 {
498 if (!_wcsicmp(argv[2], L"COMMAND"))
499 qtype = ASSOCSTR_COMMAND;
500 if (!_wcsicmp(argv[2], L"EXECUTABLE"))
501 qtype = ASSOCSTR_EXECUTABLE;
502 if (!_wcsicmp(argv[2], L"FRIENDLYDOCNAME") || !_wcsicmp(argv[2], L"FriendlyTypeName"))
504 if (!_wcsicmp(argv[2], L"DEFAULTICON"))
505 qtype = ASSOCSTR_DEFAULTICON;
506
507 buf[0] = UNICODE_NULL;
508 size /= sizeof(buf[0]); // Convert to number of characters
509 hr = qa->GetString(qflags, (ASSOCSTR)qtype, extra, buf, &size);
510 size *= sizeof(buf[0]); // Convert back to bytes
511 if (SUCCEEDED(hr) ||
513 {
514 wprintf(L"0x%.8X: %s\n", hr, buf);
515 }
516 else
517 {
518 wprintf(size != maxSize ? L"%u " : L"", size);
519 ErrMsg(hr);
520 }
521 }
522 else if (!_wcsicmp(argv[1], L"data"))
523 {
524 if (!_wcsicmp(argv[2], L"EDITFLAGS"))
525 qtype = ASSOCDATA_EDITFLAGS;
526 if (!_wcsicmp(argv[2], L"VALUE"))
527 qtype = ASSOCDATA_VALUE;
528
529 hr = qa->GetData(qflags, (ASSOCDATA)qtype, extra, buf, &size);
530 if (SUCCEEDED(hr))
531 {
532 wprintf(L"0x%.8X: %u byte(s) ", hr, size);
533 DumpBytes(buf, min(size, maxSize));
534 }
535 else
536 {
537 wprintf(size != maxSize ? L"%u " : L"", size);
538 ErrMsg(hr);
539 }
540 }
541 else if (!_wcsicmp(argv[1], L"key"))
542 {
543 HKEY hKey = NULL;
544 hr = qa->GetKey(qflags, (ASSOCKEY)qtype, extra, &hKey);
545 if (SUCCEEDED(hr))
546 {
547 wprintf(L"0x%.8X: hKey %p\n", hr, hKey);
548 RegQueryValueExW(hKey, L"shlextdbg", 0, NULL, NULL, NULL); // Filter by this in Process Monitor
550 }
551 else
552 {
553 ErrMsg(hr);
554 }
555 }
556 else
557 {
558 PrintHelp(L"Unknown query");
560 }
561 return hr;
562}
#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:104
#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
void PrintHelp()
Definition: appwiz.c:21
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
#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:150
static bool CLSIDPrefix(T &String, CLSID &Clsid)
Definition: shlextdbg.cpp:93
static LONG StrToNum(PCWSTR in)
Definition: shlextdbg.cpp:68
static void DumpBytes(const void *Data, SIZE_T cb)
Definition: shlextdbg.cpp:205
static int ErrMsg(int Error)
Definition: shlextdbg.cpp:75
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 778 of file shlextdbg.cpp.

779{
780 g_Pages.Add(page);
781 if (lParam != (LPARAM)&g_Pages)
782 {
783 wprintf(L"Propsheet failed to pass lParam, got: 0x%Ix\n", lParam);
784 }
785 return TRUE;
786}
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:777
Definition: module.h:576

Referenced by wmain().

◆ CLSIDPrefix()

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

Definition at line 93 of file shlextdbg.cpp.

94{
95 WCHAR buf[38 + 1];
96 if (String[0] == '{')
97 {
99 if (SUCCEEDED(CLSIDFromString(buf, &Clsid)))
100 {
101 String = String + 38;
102 return true;
103 }
104 }
105 return false;
106}
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 580 of file shlextdbg.cpp.

581{
583 if (!SUCCEEDED(hr))
584 {
585 wprintf(L"Failed to create pidl from '%s': 0x%x\n", FileName, hr);
586 return hr;
587 }
588
589 CComPtr<IShellFolder> shellFolder;
590 PCUITEMID_CHILD childs;
591 hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shellFolder), &childs);
592 if (!SUCCEEDED(hr))
593 {
594 wprintf(L"Failed to bind to parent: 0x%x\n", hr);
595 return hr;
596 }
597 hr = shellFolder->GetUIObjectOf(NULL, 1, &childs, IID_IDataObject, NULL, (PVOID*)&dataObject);
598 if (!SUCCEEDED(hr))
599 {
600 wprintf(L"Failed to query IDataObject: 0x%x\n", hr);
601 }
602 return hr;
603}
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 150 of file shlextdbg.cpp.

151{
152 PIDLIST_ABSOLUTE pidl = NULL;
153 HRESULT hr = SHParseDisplayName(Path, NULL, &pidl, 0, NULL);
154 if (SUCCEEDED(hr))
155 {
156 hr = SHCreateShellItem(NULL, NULL, pidl, ppSI);
157 if (ppidl)
158 *ppidl = pidl;
159 else
160 SHFree(pidl);
161 }
162 return hr;
163}
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:370

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

◆ DumpBytes()

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

Definition at line 205 of file shlextdbg.cpp.

206{
207 for (SIZE_T i = 0; i < cb; ++i)
208 {
209 wprintf(L"%s%.2X", i ? L" " : L"", ((LPCBYTE)Data)[i]);
210 }
211 wprintf(L"\n");
212}
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 398 of file shlextdbg.cpp.

399{
402 if (FAILED(hr))
403 {
404 wprintf(L"Can't parse %s\n", Path);
405 return hr;
406 }
408 if (FAILED(hr = si->BindToHandler(NULL, BHID_SFObject, IID_PPV_ARG(IShellFolder2, &sf))))
409 {
410 wprintf(L"Could not bind to IShellFolder2\n");
411 return hr;
412 }
413
414 ULONG columns, defSort, defDisp;
415 for (columns = 0; ; ++columns)
416 {
417 SHELLDETAILS sd = {};
418 if (FAILED(sf->GetDetailsOf(NULL, columns, &sd)))
419 break;
420 PWSTR str;
421 if (FAILED(StrRetToStrW(&sd.str, NULL, &str)))
422 str = NULL;
424 if (FAILED(sf->GetDefaultColumnState(columns, &flags)))
425 flags = 0;
426 wprintf(L"%lu: %s 0x%.4x %d 0x%.8x\n", columns, str ? str : L"", (UINT)sd.fmt, sd.cxChar, flags);
427 SHFree(str);
428 }
429
430 if (SUCCEEDED(sf->GetDefaultColumn(0, &defSort, &defDisp)))
431 wprintf(L"%lu is the default sort column and %lu is the default display column.\n", defSort, defDisp);
432
433 HRESULT (WINAPI* PSGNFPK)(SHCOLUMNID*, PWSTR*) = NULL;
434 if (HMODULE hPS = LoadLibraryW(L"propsys.dll"))
435 {
436 // HACKFIX: PSGetNameFromPropertyKey is a stub in ROS, we will crash if we call it
437 HRESULT (WINAPI* PSGPD)(SHCOLUMNID*, REFIID, void**);
438 (FARPROC&)PSGPD = GetProcAddress(hPS, "PSGetPropertyDescription");
440 SHCOLUMNID scid = {};
441 if (PSGPD && PSGPD(&scid, IID_PPV_ARG(IShellFolder2, &dummy)) != E_NOTIMPL)
442 (FARPROC&)PSGNFPK = GetProcAddress(hPS, "PSGetNameFromPropertyKey");
443 }
444 for (ULONG i = 0; i < max(columns, 999); ++i)
445 {
446 SHCOLUMNID scid = {};
447 if (FAILED(sf->MapColumnToSCID(i, &scid)))
448 continue;
449 WCHAR Buffer[100];
450 StringFromGUID2(scid.fmtid, Buffer, _countof(Buffer));
451 wprintf(L"%lu: %s,%-3lu", i, Buffer, scid.pid);
453 if (PSGNFPK && SUCCEEDED(PSGNFPK(&scid, &str)) && str)
454 wprintf(L" %s", (PWSTR)str);
455 wprintf(L"\n");
456 }
457 return columns ? S_OK : S_FALSE;
458}
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 219 of file shlextdbg.cpp.

220{
221 UINT cbPerLine = 16, cbLine;
222 for (SIZE_T i = 0, j; i < cb; i += cbLine)
223 {
224 cbLine = min(cbPerLine, cb - i);
225 for (j = 0; j < cbLine; ++j) wprintf(L" %.2X", ((BYTE*)Buffer)[i + j]);
226 for (j = 0; j < cbPerLine - cbLine; ++j) wprintf(L" ");
227 for (j = 0; j < cbLine; ++j) wprintf(L"%s%c", !j ? L" " : L"", SafeDumpChar(((BYTE*)Buffer)[i + j]));
228 for (j = 0; j < cbPerLine - cbLine; ++j) wprintf(L" ");
229 wprintf(L"\n");
230 }
231}
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:214
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 252 of file shlextdbg.cpp.

253{
254 bool recurse = Indent != UINT(-1);
256 MENUITEMINFOW mii;
257 mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem);
258
259 for (UINT i = 0, defid = GetMenuDefaultItem(hMenu, FALSE, 0); ; ++i)
260 {
261 mii.fMask = MIIM_STRING;
262 mii.dwTypeData = buf;
263 mii.cch = _countof(buf);
264 *buf = UNICODE_NULL;
265 if (!GetMenuItemInfo(hMenu, i, TRUE, &mii))
266 lstrcpynW(buf, L"?", _countof(buf)); // Tolerate string failure
268 mii.hSubMenu = NULL;
269 mii.dwTypeData = NULL;
270 mii.cch = 0;
271 if (!GetMenuItemInfo(hMenu, i, TRUE, &mii))
272 break;
273
274 BOOL sep = mii.fType & MFT_SEPARATOR;
275 wprintf(L"%-4d", (sep || mii.wID == UINT(-1)) ? mii.wID : (mii.wID - IdOffset));
276 for (UINT j = 0; j < Indent && recurse; ++j)
277 wprintf(L" ");
278 wprintf(L"%s%s", mii.hSubMenu ? L">" : L"|", sep ? L"----------" : buf);
279 if (!sep && pCM && SUCCEEDED(GetCommandString(*pCM, mii.wID - IdOffset,
280 GCS_VERB, buf, _countof(buf))))
281 {
282 wprintf(L" [%s]", buf);
283 }
284 wprintf(L"%s\n", (defid == mii.wID && defid != UINT(-1)) ? L" (Default)" : L"");
285 if (mii.hSubMenu && recurse)
286 {
287 if (FakeInit)
289 DumpMenu(mii.hSubMenu, IdOffset, pCM, FakeInit, Indent + 1);
290 }
291 }
292}
#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:233
static void DumpMenu(HMENU hMenu, UINT IdOffset, IContextMenu *pCM, BOOL FakeInit, UINT Indent)
Definition: shlextdbg.cpp:252
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 339 of file shlextdbg.cpp.

340{
341 PIDLIST_ABSOLUTE pidl;
344 if (FAILED(hr))
345 {
346 wprintf(L"Can't parse %s\n", Path);
347 return hr;
348 }
349
350 UINT lvl = 0;
351 for (PUITEMID_CHILD p = pidl; p; ++lvl)
352 {
353 if (!p->mkid.cb && p > pidl)
354 break;
355 PUITEMID_CHILD pNext = ILGetNext(p);
356 const WORD save = pNext ? pNext->mkid.cb : 0;
357 if (pNext)
358 pNext->mkid.cb = 0;
359 wprintf(L"#%u %ub", lvl, p->mkid.cb);
360
361 WCHAR buf[100];
362 VARIANT v;
363 V_VT(&v) = VT_EMPTY;
364 static const SHCOLUMNID pkey_descriptionid = { FMTID_ShellDetails, PID_DESCRIPTIONID };
365 CComPtr<IShellFolder2> pParentFolder;
366 PCUITEMID_CHILD pidlChildSelf;
367 hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder2, &pParentFolder), &pidlChildSelf);
368 if (SUCCEEDED(hr) && SUCCEEDED(hr = pParentFolder->GetDetailsEx(pidlChildSelf, &pkey_descriptionid, &v)))
369 {
370 if (V_VT(&v) == (VT_UI1 | VT_ARRAY))
371 {
372 const SHDESCRIPTIONID &shdid = *(SHDESCRIPTIONID*)V_ARRAY(&v)->pvData;
374 PCWSTR did = L"?";
375 switch (shdid.dwDescriptionId)
376 {
377 case SHDID_ROOT_REGITEM: did = L"ROOT_REGITEM"; break;
378 case SHDID_FS_FILE: did = L"FS_FILE"; break;
379 case SHDID_FS_DIRECTORY: did = L"FS_DIRECTORY"; break;
380 case SHDID_FS_OTHER: did = L"FS_OTHER"; break;
381 case SHDID_COMPUTER_FIXED: did = L"COMPUTER_FIXED"; break;
382 }
383 wprintf(L" %s %s(%#.2x)", buf, did, shdid.dwDescriptionId);
384 }
385 PropVariantClear((PROPVARIANT*)&v); // No need to drag in oleaut32, ole32 knows how to handle this
386 }
387 wprintf(L"\n");
388 DumpHexBytes(p->mkid.abID, p->mkid.cb > 2 ? p->mkid.cb - 2 : 0);
389
390 if (pNext)
391 pNext->mkid.cb = save;
392 p = pNext;
393 }
394 SHFree(pidl);
395 return S_OK;
396}
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:219
#define PID_DESCRIPTIONID
Definition: shlguid.h:171
#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 679 of file shlextdbg.cpp.

680{
681 if (hwnd != g_ConsoleWindow)
682 {
683 DWORD pid = 0;
685 if (pid == GetCurrentProcessId())
686 {
687 g_Windows.Add(hwnd);
688 }
689 }
690 return TRUE;
691}
CSimpleArray< HWND > g_Windows
Definition: shlextdbg.cpp:677
HWND g_ConsoleWindow
Definition: shlextdbg.cpp:678
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 75 of file shlextdbg.cpp.

76{
77 WCHAR buf[400];
78 for (UINT e = Error, cch; ;)
79 {
80 lstrcpynW(buf, L"?", _countof(buf));
82 while (cch && buf[cch - 1] <= ' ')
83 buf[--cch] = UNICODE_NULL; // Remove trailing newlines
84 if (cch || HIWORD(e) != HIWORD(HRESULT_FROM_WIN32(1)))
85 break;
86 e = HRESULT_CODE(e); // "WIN32_FROM_HRESULT"
87 }
88 wprintf(Error < 0 ? L"Error 0x%.8X %s\n" : L"Error %d %s\n", Error, buf);
89 return Error;
90}
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 165 of file shlextdbg.cpp.

166{
167 hKey = NULL;
168 IQueryAssociations* pQA;
169 if (SUCCEEDED(GetUIObjectOfAbsolute(pidl, IID_PPV_ARG(IQueryAssociations, &pQA))))
170 {
171 pQA->GetKey(0, ASSOCKEY_CLASS, NULL, &hKey); // Not implemented in ROS
172 pQA->Release();
173 }
174 if (!hKey)
175 {
176 DWORD cb;
180 info.dwAttributes = 0;
182 if (info.dwAttributes & SFGAO_FOLDER)
183 {
184 ext = const_cast<LPWSTR>(L"Directory");
185 }
186 else if (info.dwAttributes & SFGAO_BROWSABLE)
187 {
188 ext = const_cast<LPWSTR>(L"Folder"); // Best guess
189 }
190 else
191 {
192 cb = sizeof(buf);
194 {
196 }
197 }
198 if (!hKey)
199 {
201 }
202 }
203}
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:140
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 233 of file shlextdbg.cpp.

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

135{
136 static CLoggingServiceProvider g_SP;
137 return &g_SP;
138}

Referenced by wmain().

◆ GetUIObjectOfAbsolute()

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

Definition at line 140 of file shlextdbg.cpp.

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

813{
814 return !_wcsicmp(argv[n] + 1, check);
815}
#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 788 of file shlextdbg.cpp.

789{
790 arg = NULL;
791 size_t len = wcslen(check);
792 if (!_wcsnicmp(argv[n] + 1, check, len))
793 {
794 PCWSTR cmd = argv[n] + len + 1;
795 if (*cmd == ':' || *cmd == '=')
796 {
797 arg = cmd + 1;
798 return true;
799 }
800 if (n + 1 < argc)
801 {
802 arg = argv[n+1];
803 n++;
804 return true;
805 }
806 wprintf(L"Command %s has no required argument!\n", check);
807 return false;
808 }
809 return false;
810}
_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 605 of file shlextdbg.cpp.

606{
607 CComPtr<IShellExtInit> spShellExtInit;
608 HRESULT hr;
609 if (g_DLL.IsEmpty())
610 {
611 hr = CoCreateInstance(g_CLSID, NULL, CLSCTX_ALL, IID_PPV_ARG(IShellExtInit, &spShellExtInit));
612 if (!SUCCEEDED(hr))
613 {
614 WCHAR Buffer[100];
616 wprintf(L"Failed to Create %s:IShellExtInit: 0x%x\n", Buffer, hr);
617 return hr;
618 }
619 }
620 else
621 {
622 typedef HRESULT (STDAPICALLTYPE *tDllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
624 if (!mod)
625 {
626 wprintf(L"Failed to Load %s:(0x%x)\n", g_DLL.GetString(), GetLastError());
627 return E_FAIL;
628 }
629 tDllGetClassObject DllGet = (tDllGetClassObject)GetProcAddress(mod, "DllGetClassObject");
630 if (!DllGet)
631 {
632 wprintf(L"%s does not export DllGetClassObject\n", g_DLL.GetString());
633 return E_FAIL;
634 }
635 CComPtr<IClassFactory> spClassFactory;
636 hr = DllGet(g_CLSID, IID_PPV_ARG(IClassFactory, &spClassFactory));
637 if (!SUCCEEDED(hr))
638 {
639 wprintf(L"Failed to create IClassFactory: 0x%x\n", hr);
640 return hr;
641 }
642 hr = spClassFactory->CreateInstance(NULL, IID_PPV_ARG(IShellExtInit, &spShellExtInit));
643 if (!SUCCEEDED(hr))
644 {
645 wprintf(L"Failed to Request IShellExtInit from IClassFactory: 0x%x\n", hr);
646 return hr;
647 }
648 }
649
650 CComPtr<IDataObject> spDataObject;
652 hr = CreateIDataObject(pidl, spDataObject, g_ShellExtInit.GetString());
653 if (!SUCCEEDED(hr))
654 return hr;
655
656 HKEY hKey = NULL;
658 hr = spShellExtInit->Initialize(pidl, spDataObject, hKey);
659 if (hKey)
661 if (!SUCCEEDED(hr))
662 {
663 wprintf(L"IShellExtInit->Initialize failed: 0x%x\n", hr);
664 return hr;
665 }
666 hr = spShellExtInit->QueryInterface(riid, ppv);
667 if (!SUCCEEDED(hr))
668 {
669 WCHAR Buffer[100];
671 wprintf(L"Failed to query %s from IShellExtInit: 0x%x\n", Buffer, hr);
672 }
673 return hr;
674}
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:573
static void GetAssocClass(LPCWSTR Path, LPCITEMIDLIST pidl, HKEY &hKey)
Definition: shlextdbg.cpp:165
CStringW g_ShellExtInit
Definition: shlextdbg.cpp:575
HRESULT CreateIDataObject(CComHeapPtr< ITEMIDLIST > &pidl, CComPtr< IDataObject > &dataObject, PCWSTR FileName)
Definition: shlextdbg.cpp:580
CStringW g_DLL
Definition: shlextdbg.cpp:574
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 214 of file shlextdbg.cpp.

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

Referenced by DumpHexBytes().

◆ SHGFI()

static int SHGFI ( PCWSTR  Path)
static

Definition at line 294 of file shlextdbg.cpp.

295{
296 PIDLIST_ABSOLUTE pidl = NULL;
297 UINT flags = 0, ret = 0;
298
299 if (*Path == L'$')
300 {
301 HRESULT hr = SHParseDisplayName(++Path, NULL, &pidl, 0, NULL);
302 if (FAILED(hr))
303 return ErrMsg(hr);
304 flags |= SHGFI_PIDL;
305 Path = (LPCWSTR)pidl;
306 }
308 {
310 }
312 if (!SHGetFileInfoW(Path, 0, &info, sizeof(info), flags |
314 {
315 info.szDisplayName[0] = info.szTypeName[0] = UNICODE_NULL;
316 info.dwAttributes = 0;
318 }
319 wprintf(L"Display: %s\n", info.szDisplayName);
320 wprintf(L"Attributes: 0x%x\n", info.dwAttributes);
321 wprintf(L"Type: %s\n", info.szTypeName);
322
323 if (!SHGetFileInfoW(Path, 0, &info, sizeof(info), flags | SHGFI_ICONLOCATION))
324 {
325 info.szDisplayName[0] = UNICODE_NULL;
326 info.iIcon = -1;
327 }
328 wprintf(L"Icon: %s,%d\n", info.szDisplayName, info.iIcon);
329
330 if (!SHGetFileInfoW(Path, 0, &info, sizeof(info), flags | SHGFI_SYSICONINDEX))
331 {
332 info.iIcon = -1;
333 }
334 wprintf(L"Index: %d\n", info.iIcon);
335 SHFree(pidl);
336 return ret;
337}
return ret
Definition: mutex.c:146
#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 68 of file shlextdbg.cpp.

69{
70 PWCHAR end;
71 LONG v = wcstol(in, &end, 0);
72 return (end > in) ? v : 0;
73}
_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 751 of file shlextdbg.cpp.

752{
753 LPCWSTR nag = L"(Please use SHGetInstanceExplorer in your code instead)";
754 switch (g_Wait)
755 {
756 case Wait_None:
757 break;
758 case Wait_Infinite:
759 _putws(nag);
760 while (true)
761 Sleep(1000);
762 break;
763 case Wait_OpenWindows:
764 _putws(nag);
765 WaitWindows();
766 break;
767 case Wait_Input:
768 wprintf(L"Press any key to continue... %s\n", nag);
769 _getch();
770 break;
772 g_EI.Wait();
773 break;
774 }
775}
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:578
ExplorerInstance g_EI
void WaitWindows()
Definition: shlextdbg.cpp:693
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726

Referenced by wmain().

◆ WaitWindows()

void WaitWindows ( )

Definition at line 693 of file shlextdbg.cpp.

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

Referenced by Wait().

◆ wmain()

int wmain ( int  argc,
WCHAR **  argv 
)

Definition at line 818 of file shlextdbg.cpp.

819{
823 SHSetInstanceExplorer(static_cast<IUnknown*>(&g_EI));
824
825 bool failArgs = false;
826 for (int n = 1; n < argc; ++n)
827 {
828 WCHAR* cmd = argv[n];
829 if (cmd[0] == '-' || cmd[0] == '/')
830 {
831 PCWSTR arg;
832 if (isCmdWithArg(argc, argv, n, L"shgfi", arg))
833 {
834 failArgs = true;
835 if (*arg)
836 return SHGFI(arg);
837 }
838 else if (isCmd(argc, argv, n, L"assocq"))
839 {
840 failArgs = true;
841 if (argc - (n + 1) >= 6 && argc - (n + 1) <= 8)
842 return AssocQ(argc - (n + 1), &argv[(n + 1)]);
843 }
844 else if (isCmdWithArg(argc, argv, n, L"shellexec", arg))
845 {
846 PIDLIST_ABSOLUTE pidl = NULL;
847 HRESULT hr = SHParseDisplayName(arg, NULL, &pidl, 0, NULL);
848 if (FAILED(hr))
849 return ErrMsg(hr);
850 SHELLEXECUTEINFOW sei = { sizeof(sei), SEE_MASK_IDLIST | SEE_MASK_UNICODE };
851 sei.lpIDList = pidl;
852 sei.nShow = SW_SHOW;
853 while (++n < argc)
854 {
855 if (argv[n][0] != '-' && argv[n][0] != '/')
856 break;
857 else if (isCmd(argc, argv, n, L"MIN"))
859 else if (isCmd(argc, argv, n, L"MAX"))
861 else if (isCmd(argc, argv, n, L"INVOKE"))
863 else if (isCmd(argc, argv, n, L"NOUI"))
865 else if (isCmd(argc, argv, n, L"ASYNCOK"))
866 sei.fMask |= SEE_MASK_ASYNCOK ;
867 else if (isCmd(argc, argv, n, L"NOASYNC"))
868 sei.fMask |= SEE_MASK_NOASYNC;
869 else if (isCmd(argc, argv, n, L"NOCONSOLE"))
871 else if (isCmd(argc, argv, n, L"1000"))
872 sei.fMask |= 0x00001000; // Unknown flag
873 else if (isCmd(argc, argv, n, L"NOHOOKS"))
874 sei.fMask |= 0x00002000;
875 else if (isCmd(argc, argv, n, L"SITE"))
876 {
877 sei.fMask |= 0x08000000; // SEE_MASK_FLAG_HINST_IS_SITE
879 }
880 else if (isCmd(argc, argv, n, L"FILL"))
881 {
882 sei.hInstApp = (HINSTANCE)UlongToHandle(0xCAFE);
883 sei.hProcess = UlongToHandle(0xDEADF00D);
884 }
885 else
886 wprintf(L"WARN: Ignoring switch %s\n", argv[n]);
887 }
888 if (n < argc && *argv[n++])
889 {
890 sei.lpVerb = argv[n - 1];
891 }
892 if (n < argc && *argv[n++])
893 {
894 sei.lpClass = argv[n - 1];
896 }
897 UINT succ = ShellExecuteExW(&sei), gle = GetLastError();
898 SHFree(pidl);
899 if (!succ)
900 return ErrMsg(gle);
901 Wait();
902 return 0;
903 }
904 else if (isCmdWithArg(argc, argv, n, L"dumpmenu", arg))
905 {
906 HRESULT hr;
908 if (CLSIDPrefix(arg, g_CLSID))
909 {
912 }
913 else
914 {
917 if (SUCCEEDED(hr))
918 hr = si->BindToHandler(NULL, BHID_SFUIObject, IID_PPV_ARG(IContextMenu, &cm));
919 }
920 if (SUCCEEDED(hr))
921 {
922 UINT first = 10, last = 9000;
923 UINT cmf = 0, nosub = 0, fakeinit = 0;
924 while (++n < argc)
925 {
926 if (argv[n][0] != '-' && argv[n][0] != '/')
927 break;
928 else if (isCmd(argc, argv, n, L"DEFAULTONLY"))
929 cmf |= CMF_DEFAULTONLY;
930 else if (isCmd(argc, argv, n, L"NODEFAULT"))
931 cmf |= CMF_NODEFAULT;
932 else if (isCmd(argc, argv, n, L"DONOTPICKDEFAULT"))
933 cmf |= CMF_DONOTPICKDEFAULT;
934 else if (isCmd(argc, argv, n, L"EXTENDED") || isCmd(argc, argv, n, L"EXTENDEDVERBS"))
935 cmf |= CMF_EXTENDEDVERBS;
936 else if (isCmd(argc, argv, n, L"SYNCCASCADEMENU"))
937 cmf |= CMF_SYNCCASCADEMENU;
938 else if (isCmd(argc, argv, n, L"EXPLORE"))
939 cmf |= CMF_EXPLORE;
940 else if (isCmd(argc, argv, n, L"VERBSONLY"))
941 cmf |= CMF_VERBSONLY;
942 else if (isCmd(argc, argv, n, L"NOVERBS"))
943 cmf |= CMF_NOVERBS;
944 else if (isCmd(argc, argv, n, L"DISABLEDVERBS"))
945 cmf |= CMF_DISABLEDVERBS;
946 else if (isCmd(argc, argv, n, L"OPTIMIZEFORINVOKE"))
947 cmf |= CMF_OPTIMIZEFORINVOKE;
948 else if (isCmd(argc, argv, n, L"CANRENAME"))
949 cmf |= CMF_CANRENAME;
950 else if (isCmd(argc, argv, n, L"NOSUBMENU"))
951 nosub++;
952 else if (isCmd(argc, argv, n, L"INITMENUPOPUP"))
953 fakeinit++; // Tickle async submenus
954 else
955 wprintf(L"WARN: Ignoring switch %s\n", argv[n]);
956 }
957 HMENU hMenu = CreatePopupMenu();
958 hr = cm->QueryContextMenu(hMenu, 0, first, last, cmf);
959 if (SUCCEEDED(hr))
960 {
961 DumpMenu(hMenu, first, cm, fakeinit, nosub ? -1 : 0);
962 }
963 DestroyMenu(hMenu);
964 }
965 if (FAILED(hr))
966 return ErrMsg(hr);
967 return 0;
968 }
969 else if (isCmdWithArg(argc, argv, n, L"dumpfoldercolumns", arg))
970 {
971 return DumpFolderColumns(arg);
972 }
973 else if (isCmdWithArg(argc, argv, n, L"dumppidl", arg))
974 {
975 return DumpPidl(arg);
976 }
977 else if (isCmdWithArg(argc, argv, n, L"clsid", arg))
978 {
980 if (!SUCCEEDED(hr))
981 {
982 wprintf(L"Failed to convert %s to CLSID\n", arg);
983 failArgs = true;
984 }
985 }
986 else if (isCmdWithArg(argc, argv, n, L"dll", arg))
987 {
988 g_DLL = arg;
989 }
990 else if (isCmdWithArg(argc, argv, n, L"IShellExtInit", arg))
991 {
993 }
994 else if (isCmd(argc, argv, n, L"IShellPropSheetExt"))
995 {
997 }
998 else if (isCmdWithArg(argc, argv, n, L"IContextMenu", arg))
999 {
1001 }
1002 else if (isCmd(argc, argv, n, L"infinite"))
1003 {
1005 }
1006 else if (isCmd(argc, argv, n, L"openwindows"))
1007 {
1009 }
1010 else if (isCmd(argc, argv, n, L"input"))
1011 {
1013 }
1014 else if (isCmd(argc, argv, n, L"explorerinstance"))
1015 {
1017 }
1018 else if (isCmd(argc, argv, n, L"nowait"))
1019 {
1020 g_Wait = Wait_None;
1021 }
1022 else
1023 {
1024 wprintf(L"Unknown argument: %s\n", cmd);
1025 failArgs = true;
1026 }
1027 }
1028 }
1029
1030 if (failArgs)
1031 {
1032 PrintHelp(NULL);
1033 return E_INVALIDARG;
1034 }
1035
1036 CLSID EmptyCLSID = { 0 };
1037 if (EmptyCLSID == g_CLSID)
1038 {
1039 PrintHelp(L"No CLSID specified");
1040 return E_INVALIDARG;
1041 }
1042
1043 if (g_ShellExtInit.IsEmpty())
1044 {
1045 PrintHelp(L"No filename specified");
1046 return E_INVALIDARG;
1047 }
1048
1049 HRESULT hr;
1051 {
1052 CComPtr<IShellPropSheetExt> spSheetExt;
1054 if (!SUCCEEDED(hr))
1055 return hr;
1056
1057 hr = spSheetExt->AddPages(cb_AddPage, (LPARAM)&g_Pages);
1058 if (!SUCCEEDED(hr))
1059 {
1060 wprintf(L"IShellPropSheetExt->AddPages failed: 0x%x\n", hr);
1061 return hr;
1062 }
1063
1064 USHORT ActivePage = HRESULT_CODE(hr);
1065 PROPSHEETHEADERW psh = { 0 };
1066
1067 psh.dwSize = sizeof(psh);
1068 psh.dwFlags = PSH_PROPTITLE;
1069 psh.pszCaption = L"shlextdbg";
1070 psh.phpage = g_Pages.GetData();
1071 psh.nPages = g_Pages.GetSize();
1072 psh.nStartPage = ActivePage ? (ActivePage-1) : 0;
1073 hr = PropertySheetW(&psh);
1074
1075 wprintf(L"PropertySheetW returned: 0x%x\n", hr);
1076 }
1077 if (!g_ContextMenu.IsEmpty())
1078 {
1079 CComPtr<IContextMenu> spContextMenu;
1080 hr = LoadAndInitialize(IID_PPV_ARG(IContextMenu, &spContextMenu));
1081 if (!SUCCEEDED(hr))
1082 return hr;
1083
1084 // FIXME: Must call QueryContextMenu before InvokeCommand?
1085
1086 CMINVOKECOMMANDINFO cm = { sizeof(cm), 0 };
1087 cm.lpVerb = g_ContextMenu.GetString();
1088 cm.nShow = SW_SHOW;
1089 hr = spContextMenu->InvokeCommand(&cm);
1090
1091 if (!SUCCEEDED(hr))
1092 {
1093 wprintf(L"IContextMenu->InvokeCommand failed: 0x%x\n", hr);
1094 return hr;
1095 }
1096 wprintf(L"IContextMenu->InvokeCommand returned: 0x%x\n", hr);
1097 }
1098
1099 Wait();
1100 return 0;
1101}
#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:2916
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:1711
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2723
CStringA g_ContextMenu
Definition: shlextdbg.cpp:577
static BOOL CALLBACK cb_AddPage(HPROPSHEETPAGE page, LPARAM lParam)
Definition: shlextdbg.cpp:778
static void Wait()
Definition: shlextdbg.cpp:751
static IServiceProvider * GetLoggingServiceProvider()
Definition: shlextdbg.cpp:134
static HRESULT DumpPidl(PCWSTR Path)
Definition: shlextdbg.cpp:339
static bool isCmdWithArg(int argc, WCHAR **argv, int &n, PCWSTR check, PCWSTR &arg)
Definition: shlextdbg.cpp:788
static bool isCmd(int argc, WCHAR **argv, int n, PCWSTR check)
Definition: shlextdbg.cpp:812
HRESULT LoadAndInitialize(REFIID riid, LPVOID *ppv)
Definition: shlextdbg.cpp:605
bool g_bIShellPropSheetExt
Definition: shlextdbg.cpp:576
static HRESULT DumpFolderColumns(PCWSTR Path)
Definition: shlextdbg.cpp:398
static int SHGFI(PCWSTR Path)
Definition: shlextdbg.cpp:294
static HRESULT AssocQ(int argc, WCHAR **argv)
Definition: shlextdbg.cpp:460
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 576 of file shlextdbg.cpp.

Referenced by wmain().

◆ g_CLSID

CLSID g_CLSID = { 0 }

Definition at line 573 of file shlextdbg.cpp.

Referenced by LoadAndInitialize(), and wmain().

◆ g_ConsoleWindow

HWND g_ConsoleWindow

Definition at line 678 of file shlextdbg.cpp.

Referenced by EnumWindowsProc(), and WaitWindows().

◆ g_ContextMenu

CStringA g_ContextMenu

Definition at line 577 of file shlextdbg.cpp.

Referenced by wmain().

◆ g_DLL

CStringW g_DLL

Definition at line 574 of file shlextdbg.cpp.

Referenced by LoadAndInitialize(), and wmain().

◆ g_EI

Referenced by Wait(), and wmain().

◆ g_Pages

Definition at line 777 of file shlextdbg.cpp.

Referenced by cb_AddPage(), and wmain().

◆ g_ShellExtInit

CStringW g_ShellExtInit

Definition at line 575 of file shlextdbg.cpp.

Referenced by LoadAndInitialize(), and wmain().

◆ g_Wait

◆ g_Windows

CSimpleArray<HWND> g_Windows

Definition at line 677 of file shlextdbg.cpp.

Referenced by EnumWindowsProc(), and WaitWindows().