windows-nt/Source/XPSP1/NT/shell/tools/shlexts/shlexts.c
2020-09-26 16:20:57 +08:00

600 lines
17 KiB
C

/****************************** Module Header ******************************\
* Module Name: shlexts.c
*
* Copyright (c) 1997, Microsoft Corporation
*
* This module contains user related debugging extensions.
*
* History:
* 10/28/97 created by cdturner (butchered from the userexts.dll)
\***************************************************************************/
#include <precomp.h>
#pragma hdrstop
#include <winver.h>
#include <shlwapi.h>
char * pszExtName = "SHLEXTS";
#include <stdexts.h>
#include <stdexts.c>
BOOL bShowFlagNames = TRUE;
#define NO_FLAG INVALID_HANDLE_VALUE // use this for non-meaningful entries.
LPSTR apszSFGAOFlags[] =
{
"SFGAO_CANCOPY", // 0x00000001L
"SFGAO_CANMOVE", // 0x00000002L
"SFGAO_CANLINK", // 0x00000004L
NO_FLAG,
"SFGAO_CANRENAME", // 0x00000010L // Objects can be renamed
"SFGAO_CANDELETE", // 0x00000020L // Objects can be deleted
"SFGAO_HASPROPSHEET", // 0x00000040L // Objects have property sheets
NO_FLAG,
"SFGAO_DROPTARGET", // 0x00000100L // Objects are drop target
NO_FLAG,
NO_FLAG,
NO_FLAG,
"SFGAO_LINK", // 0x00010000L // Shortcut (link)
"SFGAO_SHARE", // 0x00020000L // shared
"SFGAO_READONLY", // 0x00040000L // read-only
"SFGAO_GHOSTED", // 0x00080000L // ghosted icon
"SFGAO_NONENUMERATED", // 0x00100000L // is a non-enumerated object
"SFGAO_NEWCONTENT", // 0x00200000L // should show bold in explorer tree
NO_FLAG,
NO_FLAG,
"SFGAO_VALIDATE", // 0x01000000L // invalidate cached information
"SFGAO_REMOVABLE", // 0x02000000L // is this removeable media?
"SFGAO_COMPRESSED", // 0x04000000L // Object is compressed (use alt color)
"SFGAO_BROWSABLE", // 0x08000000L // is in-place browsable
"SFGAO_FILESYSANCESTOR",// 0x10000000L // It contains file system folder
"SFGAO_FOLDER", // 0x20000000L // It's a folder.
"SFGAO_FILESYSTEM", // 0x40000000L // is a file system thing (file/folder/root)
"SFGAO_HASSUBFOLDER", // 0x80000000L // Expandable in the map pane
NULL
};
LPSTR apszSLDFFlags[] =
{
"SLDF_HAS_ID_LIST", // = 0x0001, // Shell link saved with ID list
"SLDF_HAS_LINK_INFO", // = 0x0002, // Shell link saved with LinkInfo
"SLDF_HAS_NAME", // = 0x0004,
"SLDF_HAS_RELPATH", // = 0x0008,
"SLDF_HAS_WORKINGDIR", // = 0x0010,
"SLDF_HAS_ARGS", // = 0x0020,
"SLDF_HAS_ICONLOCATION", // = 0x0040,
"SLDF_UNICODE", // = 0x0080, // the strings are unicode (NT is comming!)
"SLDF_FORCE_NO_LINKINFO",// = 0x0100, // don't create a LINKINFO (make a dumb link)
"SLDF_HAS_EXP_SZ" // = 0x0200, // the link contains expandable env strings
"SLDF_RUN_IN_SEPARATE", // = 0x0400, // Run the 16-bit target exe in a separate VDM/WOW
"SLDF_HAS_LOGO3ID", // = 0x0800, // this link is a special Logo3/MSICD link
"SLDF_HAS_DARWINID", // = 0x1000 // this link is a special Darwin link
NULL
};
LPSTR apszFWFFlags[] =
{
"FWF_AUTOARRANGE", // = 0x0001,
"FWF_ABBREVIATEDNAMES", // = 0x0002,
"FWF_SNAPTOGRID", // = 0x0004,
"FWF_OWNERDATA", // = 0x0008,
"FWF_BESTFITWINDOW", // = 0x0010,
"FWF_DESKTOP", // = 0x0020,
"FWF_SINGLESEL", // = 0x0040,
"FWF_NOSUBFOLDERS", // = 0x0080,
"FWF_TRANSPARENT", // = 0x0100,
"FWF_NOCLIENTEDGE", // = 0x0200,
"FWF_NOSCROLL", // = 0x0400,
"FWF_ALIGNLEFT", // = 0x0800,
"FWF_NOICONS", // = 0x1000,
"FWF_SINGLECLICKACTIVATE", // = 0x8000 // TEMPORARY -- NO UI FOR THIS
NULL
};
LPSTR apszICIFlags[] =
{
"ICIFLAG_LARGE", // 0x0001
"ICIFLAG_SMALL", // 0x0002
"ICIFLAG_BITMAP", // 0x0004
"ICIFLAG_ICON", // 0x0008
"ICIFLAG_INDEX", // 0x0010
"ICIFLAG_NAME", // 0x0020
"ICIFLAG_FLAGS", // 0x0040
"ICIFLAG_NOUSAGE", // 0x0080
NULL
};
LPSTR apszFDFlags[] =
{
"FD_CLSID", // = 0x0001,
"FD_SIZEPOINT", // = 0x0002,
"FD_ATTRIBUTES", // = 0x0004,
"FD_CREATETIME", // = 0x0008,
"FD_ACCESSTIME", // = 0x0010,
"FD_WRITESTIME", // = 0x0020,
"FD_FILESIZE", // = 0x0040,
"FD_LINKUI", // = 0x8000, // 'link' UI is prefered
NULL
};
LPSTR apszSHCNEFlags[] =
{
"SHCNE_RENAMEITEM", // 0x00000001L
"SHCNE_CREATE", // 0x00000002L
"SHCNE_DELETE", // 0x00000004L
"SHCNE_MKDIR", // 0x00000008L
"SHCNE_RMDIR", // 0x00000010L
"SHCNE_MEDIAINSERTED", // 0x00000020L
"SHCNE_MEDIAREMOVED", // 0x00000040L
"SHCNE_DRIVEREMOVED", // 0x00000080L
"SHCNE_DRIVEADD", // 0x00000100L
"SHCNE_NETSHARE", // 0x00000200L
"SHCNE_NETUNSHARE", // 0x00000400L
"SHCNE_ATTRIBUTES", // 0x00000800L
"SHCNE_UPDATEDIR", // 0x00001000L
"SHCNE_UPDATEITEM", // 0x00002000L
"SHCNE_SERVERDISCONNECT", // 0x00004000L
"SHCNE_UPDATEIMAGE", // 0x00008000L
"SHCNE_DRIVEADDGUI", // 0x00010000L
"SHCNE_RENAMEFOLDER", // 0x00020000L
"SHCNE_FREESPACE", // 0x00040000L
NO_FLAG,
NO_FLAG,
NO_FLAG,
"SHCNE_EXTENDED_EVENT", // 0x04000000L
"SHCNE_ASSOCCHANGED", // 0x08000000L
NULL
};
LPSTR apszSSFFlags[] =
{
"SSF_SHOWALLOBJECTS", // 0x0001
"SSF_SHOWEXTENSIONS", // 0x0002
"SSF_WIN95UNUSED", // 0x0004 // ;Internal - corresponding SHELLSTATE fields don't exist in SHELLFLAGSTATE
"SSF_SHOWCOMPCOLOR", // 0x0008
"SSF_SORTCOLUMNS", // 0x0010 // ;Internal - corresponding SHELLSTATE fields don't exist in SHELLFLAGSTATE
"SSF_SHOWSYSFILES", // 0x0020
"SSF_DOUBLECLICKINWEBVIEW", // 0x0080
"SSF_SHOWATTRIBCOL", // 0x0100
"SSF_DESKTOPHTML", // 0x0200
"SSF_WIN95CLASSIC", // 0x0400
"SSF_DONTPRETTYPATH", // 0x0800
"SSF_MAPNETDRVBUTTON", // 0x1000
"SSF_SHOWINFOTIP", // 0x2000
"SSF_HIDEICONS", // 0x4000
"SSF_NOCONFIRMRECYCLE", // 0x8000
"SSF_FILTER", // 0x00010000 // ;Internal - corresponding SHELLSTATE fields don't exist in SHELLFLAGSTATE
"SSF_WEBVIEW", // 0x00020000 // ;Internal
"SSF_SHOWSUPERHIDDEN", // 0x00040000 // ;Internal
"SSF_SEPPROCESS", // 0x00080000 // ;Internal
"SSF_NONETCRAWLING", // 0x00100000 // ;Internal
"SSF_STARTPANELON", // 0x00200000 // ;Internal
NULL
};
enum GF_FLAGS {
GL_SFGAO = 0,
GL_SLDF,
GL_FWF,
GL_ICI,
GL_FD,
GL_SHCNE,
GL_SSF,
GF_MAX,
};
struct _tagFlags
{
LPSTR * apszFlags;
LPSTR pszFlagsname;
} argFlag[GF_MAX] =
{
{apszSFGAOFlags, "SFGAO"},
{apszSLDFFlags, "SLD"},
{apszFWFFlags, "FWF"},
{apszICIFlags, "ICIFLAG"},
{apszFDFlags, "FD"},
{apszSHCNEFlags, "SHCNE"},
{apszSSFFlags, "SSF"}
};
/************************************************************************\
* Procedure: GetFlags
*
* Description:
*
* Converts a 32bit set of flags into an appropriate string.
* pszBuf should be large enough to hold this string, no checks are done.
* pszBuf can be NULL, allowing use of a local static buffer but note that
* this is not reentrant.
* Output string has the form: "FLAG1 | FLAG2 ..." or "0"
*
* Returns: pointer to given or static buffer with string in it.
*
* 6/9/1995 Created SanfordS
* 11/5/1997 cdturner changed the aapszFlag type
*
\************************************************************************/
LPSTR GetFlags(
WORD wType,
DWORD dwFlags,
LPSTR pszBuf,
BOOL fPrintZero)
{
static char szT[512];
WORD i;
BOOL fFirst = TRUE;
BOOL fNoMoreNames = FALSE;
LPSTR *apszFlags;
if (pszBuf == NULL) {
pszBuf = szT;
}
if (!bShowFlagNames) {
sprintf(pszBuf, "%x", dwFlags);
return pszBuf;
}
*pszBuf = '\0';
if (wType >= GF_MAX) {
strcpy(pszBuf, "Invalid flag type.");
return pszBuf;
}
apszFlags = argFlag[wType].apszFlags;
for (i = 0; dwFlags; dwFlags >>= 1, i++) {
if (!fNoMoreNames && apszFlags[i] == NULL) {
fNoMoreNames = TRUE;
}
if (dwFlags & 1) {
if (!fFirst) {
strcat(pszBuf, " | ");
} else {
fFirst = FALSE;
}
if (fNoMoreNames || apszFlags[i] == NO_FLAG) {
char ach[16];
sprintf(ach, "0x%lx", 1 << i);
strcat(pszBuf, ach);
} else {
strcat(pszBuf, apszFlags[i]);
}
}
}
if (fFirst && fPrintZero) {
sprintf(pszBuf, "0");
}
return pszBuf;
}
/************************************************************************\
* Procedure: Iflags
*
* Description:
*
* outputs the list of flags for the given flags type
*
* 11/5/1997 Created cdturner
*
\************************************************************************/
BOOL Iflags( DWORD dwOpts,
LPSTR pszArgs )
{
CHAR szBuffer[100];
int iOffset = 0;
int iFlags;
LPDWORD pAddr;
BOOL bAddr = FALSE;
DWORD dwValue;
LPSTR pszOut;
if ( dwOpts & OFLAG(l))
{
// list all the struct names
Print("Flags types known:\n");
for ( iFlags = 0; iFlags < GF_MAX; iFlags ++ )
{
sprintf( szBuffer, " %s\n", argFlag[iFlags].pszFlagsname);
Print( szBuffer );
}
return TRUE;
}
// skip whitespace
while ( *pszArgs == ' ' )
pszArgs ++;
// now grab the flagsname
while ( pszArgs[iOffset] != ' ' && pszArgs[iOffset] != '\0' )
{
szBuffer[iOffset] = pszArgs[iOffset];
iOffset ++;
};
// terminate the string
szBuffer[iOffset] = 0;
// find the flags value
for ( iFlags = 0; iFlags < GF_MAX; iFlags ++ )
{
if ( lstrcmpA( szBuffer, argFlag[iFlags].pszFlagsname ) == 0 )
break;
}
if ( iFlags >= GF_MAX )
{
Print( "unknown flagsname - ");
Print( szBuffer );
Print( "\n" );
return TRUE;
}
// skip white space
while ( pszArgs[iOffset] == ' ' )
iOffset ++;
if ( pszArgs[iOffset] == '*' )
{
bAddr = TRUE;
iOffset ++;
}
pAddr = (LPDWORD) EvalExp( pszArgs + iOffset );
if ( bAddr )
{
if ( !tryDword( &dwValue, pAddr ) )
{
Print( "unable to access memory at that location\n");
return TRUE;
}
}
else
{
dwValue = PtrToUlong(pAddr);
}
pszOut = GetFlags( (WORD) iFlags, dwValue, NULL, TRUE );
if ( pszOut )
{
sprintf( szBuffer, "Value = %8X, pAddr = %8X\n", dwValue, (DWORD_PTR)pAddr );
Print( szBuffer );
Print( pszOut );
Print( "\n" );
}
return TRUE;
}
/************************************************************************\
* Procedure: Itest
*
* Description: Tests the basic stdexts macros and functions - a good check
* on the debugger extensions in general before you waste time debuging
* entensions.
*
* Returns: fSuccess
*
* 11/4/1997 Created cdturner
*
\************************************************************************/
BOOL Itest()
{
Print("Print test!\n");
SAFEWHILE(TRUE)
{
Print("SAFEWHILE test... Hit Ctrl-C NOW!\n");
}
return TRUE;
}
/************************************************************************\
* Procedure: Iver
*
* Description: Dumps versions of extensions and winsrv/win32k
*
* Returns: fSuccess
*
* 11/4/1997 Created cdturner
*
\************************************************************************/
BOOL Iver()
{
#if DEBUG
Print("SHLEXTS version: Debug.\n");
#else
Print("SHLEXTS version: Retail.\n");
#endif
return TRUE;
}
/************************************************************************\
*
* DumpVerboseFileInfo
*
* Stolen from MSDN.
*
\************************************************************************/
typedef struct LANGANDCODEPAGE {
WORD wLang;
WORD wCP;
} LANGANDCODEPAGE;
void DumpVersionString(LPVOID pBlock, LANGANDCODEPAGE *lpTranslate, LPCSTR pszKey)
{
char szBuf[128];
LPSTR pszValue;
DWORD cb;
wsprintfA(szBuf, "\\StringFileInfo\\%04x%04x\\%s",
lpTranslate->wLang, lpTranslate->wCP, pszKey);
if (VerQueryValueA(pBlock, szBuf, (LPVOID*)&pszValue, &cb) &&
lstrlenA(pszValue)) // lstrlen traps exceptions
{
Print(szBuf+16); // skip over "\\StringFileInfo\\"
Print(" = ");
Print(pszValue);
Print("\n");
}
}
LPCSTR c_rgszVersionKeys[] =
{
"CompanyName",
"FileDescription",
"InternalName",
"OriginalFilename",
"ProductName",
"ProductVersion",
"FileVersion",
"LegalCopyright",
"LegalTrademarks",
"PrivateBuild",
"SpecialBuild",
"Comments",
NULL,
};
void DumpVerboseFileInfo(LPVOID pBlock)
{
LANGANDCODEPAGE *lpTranslate;
DWORD cbTranslate;
// Read the list of languages and code pages
if (VerQueryValueA(pBlock, "\\VarFileInfo\\Translation",
(LPVOID*)&lpTranslate, &cbTranslate))
{
UINT i;
for (i = 0; i < cbTranslate/sizeof(*lpTranslate) && !IsCtrlCHit(); i++)
{
LPCSTR *ppszVK;
for (ppszVK = c_rgszVersionKeys; *ppszVK && !IsCtrlCHit(); ppszVK++)
{
DumpVersionString(pBlock, &lpTranslate[i], *ppszVK);
}
}
}
}
/************************************************************************\
* Procedure: Ifilever
*
* Description: Dumps versions of extensions and winsrv/win32k
*
* Returns: fSuccess
*
* 11/4/1997 Created cdturner
*
\************************************************************************/
BOOL Ifilever( DWORD dwOpts,
LPSTR pszArgs )
{
HINSTANCE hDll = NULL;
DLLGETVERSIONPROC pGetVer = NULL;
DWORD dwHandle;
DWORD dwBlockLen;
LPVOID pBlock = NULL;
char szMessage[200];
BOOL fSkipLoad = FALSE;
if ( pszArgs == NULL || lstrlenA( pszArgs ) == 0 )
{
pszArgs = "Shell32.dll"; // default filename
}
if ( !dwOpts )
{
dwOpts = OFLAG(n); // default flags
}
Print("filever ");
Print(pszArgs);
Print("\n");
if ( dwOpts & OFLAG(d) )
{
hDll = LoadLibraryA(pszArgs);
if ( hDll == NULL )
{
Print("LoadLibrary failed\n");
}
else
{
pGetVer = (DLLGETVERSIONPROC) GetProcAddress( hDll, "DllGetVersion");
if ( pGetVer )
{
DLLVERSIONINFO rgVerInfo;
rgVerInfo.cbSize = sizeof( rgVerInfo );
pGetVer( &rgVerInfo );
wsprintfA( szMessage, "DllGetVersion\n Major = %d\n Minor = %d\n Build = %d\n",
rgVerInfo.dwMajorVersion, rgVerInfo.dwMinorVersion, rgVerInfo.dwBuildNumber );
Print(szMessage );
}
FreeLibrary( hDll );
}
}
if ( dwOpts & (OFLAG(n) | OFLAG(v)) )
{
// now test the normal version details...
dwBlockLen = GetFileVersionInfoSizeA( pszArgs, &dwHandle );
if ( dwBlockLen == 0 )
{
Print("GetFileVersionSize failed\n");
}
else
{
pBlock = LocalAlloc( LPTR, dwBlockLen );
if ( pBlock )
{
if (GetFileVersionInfoA( pszArgs, dwHandle, dwBlockLen, pBlock ))
{
VS_FIXEDFILEINFO * pFileInfo;
UINT uLen;
VerQueryValueA( pBlock, "\\", (LPVOID *) &pFileInfo, &uLen );
Print("GetFileVersionInfo\n");
wsprintfA( szMessage, "Version: %d.%d.%d.%d (0x%08x`%08x)\n",
HIWORD(pFileInfo->dwFileVersionMS),
LOWORD(pFileInfo->dwFileVersionMS),
HIWORD(pFileInfo->dwFileVersionLS),
LOWORD(pFileInfo->dwFileVersionLS),
pFileInfo->dwFileVersionMS,
pFileInfo->dwFileVersionLS);
Print( szMessage );
}
if (dwOpts & OFLAG(v))
{
DumpVerboseFileInfo(pBlock);
}
LocalFree( pBlock );
}
}
}
return TRUE;
}