/****************************** 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 #pragma hdrstop #include #include char * pszExtName = "SHLEXTS"; #include #include 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, UINT cchBuf, BOOL fPrintZero) { static char szT[512]; WORD i; BOOL fFirst = TRUE; BOOL fNoMoreNames = FALSE; LPSTR *apszFlags; if (pszBuf == NULL) { pszBuf = szT; cchBuf = ARRAYSIZE(szT); } if (!bShowFlagNames) { StringCchPrintfA(pszBuf, cchBuf, "%x", dwFlags); return pszBuf; } *pszBuf = '\0'; if (wType >= GF_MAX) { StringCchCopyA(pszBuf, cchBuf, "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) { StringCchCatA(pszBuf, cchBuf, " | "); } else { fFirst = FALSE; } if (fNoMoreNames || apszFlags[i] == NO_FLAG) { char ach[16]; StringCchPrintfA(ach, ARRAYSIZE(ach), "0x%lx", 1 << i); StringCchCatA(pszBuf, cchBuf, ach); } else { StringCchCatA(pszBuf, cchBuf, apszFlags[i]); } } } if (fFirst && fPrintZero) { StringCchPrintfA(pszBuf, cchBuf, "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 ++ ) { StringCchPrintfA( szBuffer, ARRAYSIZE(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, 0, TRUE ); if ( pszOut ) { StringCchPrintfA( szBuffer, ARRAYSIZE(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; StringCchPrintfA(szBuf, ARRAYSIZE(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 ); StringCchPrintfA( szMessage, ARRAYSIZE(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"); StringCchPrintfA( szMessage, ARRAYSIZE(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; }