Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

599 lines
17 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: shlexts.c
  3. *
  4. * Copyright (c) 1997, Microsoft Corporation
  5. *
  6. * This module contains user related debugging extensions.
  7. *
  8. * History:
  9. * 10/28/97 created by cdturner (butchered from the userexts.dll)
  10. \***************************************************************************/
  11. #include <precomp.h>
  12. #pragma hdrstop
  13. #include <winver.h>
  14. #include <shlwapi.h>
  15. char * pszExtName = "SHLEXTS";
  16. #include <stdexts.h>
  17. #include <stdexts.c>
  18. BOOL bShowFlagNames = TRUE;
  19. #define NO_FLAG INVALID_HANDLE_VALUE // use this for non-meaningful entries.
  20. LPSTR apszSFGAOFlags[] =
  21. {
  22. "SFGAO_CANCOPY", // 0x00000001L
  23. "SFGAO_CANMOVE", // 0x00000002L
  24. "SFGAO_CANLINK", // 0x00000004L
  25. NO_FLAG,
  26. "SFGAO_CANRENAME", // 0x00000010L // Objects can be renamed
  27. "SFGAO_CANDELETE", // 0x00000020L // Objects can be deleted
  28. "SFGAO_HASPROPSHEET", // 0x00000040L // Objects have property sheets
  29. NO_FLAG,
  30. "SFGAO_DROPTARGET", // 0x00000100L // Objects are drop target
  31. NO_FLAG,
  32. NO_FLAG,
  33. NO_FLAG,
  34. "SFGAO_LINK", // 0x00010000L // Shortcut (link)
  35. "SFGAO_SHARE", // 0x00020000L // shared
  36. "SFGAO_READONLY", // 0x00040000L // read-only
  37. "SFGAO_GHOSTED", // 0x00080000L // ghosted icon
  38. "SFGAO_NONENUMERATED", // 0x00100000L // is a non-enumerated object
  39. "SFGAO_NEWCONTENT", // 0x00200000L // should show bold in explorer tree
  40. NO_FLAG,
  41. NO_FLAG,
  42. "SFGAO_VALIDATE", // 0x01000000L // invalidate cached information
  43. "SFGAO_REMOVABLE", // 0x02000000L // is this removeable media?
  44. "SFGAO_COMPRESSED", // 0x04000000L // Object is compressed (use alt color)
  45. "SFGAO_BROWSABLE", // 0x08000000L // is in-place browsable
  46. "SFGAO_FILESYSANCESTOR",// 0x10000000L // It contains file system folder
  47. "SFGAO_FOLDER", // 0x20000000L // It's a folder.
  48. "SFGAO_FILESYSTEM", // 0x40000000L // is a file system thing (file/folder/root)
  49. "SFGAO_HASSUBFOLDER", // 0x80000000L // Expandable in the map pane
  50. NULL
  51. };
  52. LPSTR apszSLDFFlags[] =
  53. {
  54. "SLDF_HAS_ID_LIST", // = 0x0001, // Shell link saved with ID list
  55. "SLDF_HAS_LINK_INFO", // = 0x0002, // Shell link saved with LinkInfo
  56. "SLDF_HAS_NAME", // = 0x0004,
  57. "SLDF_HAS_RELPATH", // = 0x0008,
  58. "SLDF_HAS_WORKINGDIR", // = 0x0010,
  59. "SLDF_HAS_ARGS", // = 0x0020,
  60. "SLDF_HAS_ICONLOCATION", // = 0x0040,
  61. "SLDF_UNICODE", // = 0x0080, // the strings are unicode (NT is comming!)
  62. "SLDF_FORCE_NO_LINKINFO",// = 0x0100, // don't create a LINKINFO (make a dumb link)
  63. "SLDF_HAS_EXP_SZ" // = 0x0200, // the link contains expandable env strings
  64. "SLDF_RUN_IN_SEPARATE", // = 0x0400, // Run the 16-bit target exe in a separate VDM/WOW
  65. "SLDF_HAS_LOGO3ID", // = 0x0800, // this link is a special Logo3/MSICD link
  66. "SLDF_HAS_DARWINID", // = 0x1000 // this link is a special Darwin link
  67. NULL
  68. };
  69. LPSTR apszFWFFlags[] =
  70. {
  71. "FWF_AUTOARRANGE", // = 0x0001,
  72. "FWF_ABBREVIATEDNAMES", // = 0x0002,
  73. "FWF_SNAPTOGRID", // = 0x0004,
  74. "FWF_OWNERDATA", // = 0x0008,
  75. "FWF_BESTFITWINDOW", // = 0x0010,
  76. "FWF_DESKTOP", // = 0x0020,
  77. "FWF_SINGLESEL", // = 0x0040,
  78. "FWF_NOSUBFOLDERS", // = 0x0080,
  79. "FWF_TRANSPARENT", // = 0x0100,
  80. "FWF_NOCLIENTEDGE", // = 0x0200,
  81. "FWF_NOSCROLL", // = 0x0400,
  82. "FWF_ALIGNLEFT", // = 0x0800,
  83. "FWF_NOICONS", // = 0x1000,
  84. "FWF_SINGLECLICKACTIVATE", // = 0x8000 // TEMPORARY -- NO UI FOR THIS
  85. NULL
  86. };
  87. LPSTR apszICIFlags[] =
  88. {
  89. "ICIFLAG_LARGE", // 0x0001
  90. "ICIFLAG_SMALL", // 0x0002
  91. "ICIFLAG_BITMAP", // 0x0004
  92. "ICIFLAG_ICON", // 0x0008
  93. "ICIFLAG_INDEX", // 0x0010
  94. "ICIFLAG_NAME", // 0x0020
  95. "ICIFLAG_FLAGS", // 0x0040
  96. "ICIFLAG_NOUSAGE", // 0x0080
  97. NULL
  98. };
  99. LPSTR apszFDFlags[] =
  100. {
  101. "FD_CLSID", // = 0x0001,
  102. "FD_SIZEPOINT", // = 0x0002,
  103. "FD_ATTRIBUTES", // = 0x0004,
  104. "FD_CREATETIME", // = 0x0008,
  105. "FD_ACCESSTIME", // = 0x0010,
  106. "FD_WRITESTIME", // = 0x0020,
  107. "FD_FILESIZE", // = 0x0040,
  108. "FD_LINKUI", // = 0x8000, // 'link' UI is prefered
  109. NULL
  110. };
  111. LPSTR apszSHCNEFlags[] =
  112. {
  113. "SHCNE_RENAMEITEM", // 0x00000001L
  114. "SHCNE_CREATE", // 0x00000002L
  115. "SHCNE_DELETE", // 0x00000004L
  116. "SHCNE_MKDIR", // 0x00000008L
  117. "SHCNE_RMDIR", // 0x00000010L
  118. "SHCNE_MEDIAINSERTED", // 0x00000020L
  119. "SHCNE_MEDIAREMOVED", // 0x00000040L
  120. "SHCNE_DRIVEREMOVED", // 0x00000080L
  121. "SHCNE_DRIVEADD", // 0x00000100L
  122. "SHCNE_NETSHARE", // 0x00000200L
  123. "SHCNE_NETUNSHARE", // 0x00000400L
  124. "SHCNE_ATTRIBUTES", // 0x00000800L
  125. "SHCNE_UPDATEDIR", // 0x00001000L
  126. "SHCNE_UPDATEITEM", // 0x00002000L
  127. "SHCNE_SERVERDISCONNECT", // 0x00004000L
  128. "SHCNE_UPDATEIMAGE", // 0x00008000L
  129. "SHCNE_DRIVEADDGUI", // 0x00010000L
  130. "SHCNE_RENAMEFOLDER", // 0x00020000L
  131. "SHCNE_FREESPACE", // 0x00040000L
  132. NO_FLAG,
  133. NO_FLAG,
  134. NO_FLAG,
  135. "SHCNE_EXTENDED_EVENT", // 0x04000000L
  136. "SHCNE_ASSOCCHANGED", // 0x08000000L
  137. NULL
  138. };
  139. LPSTR apszSSFFlags[] =
  140. {
  141. "SSF_SHOWALLOBJECTS", // 0x0001
  142. "SSF_SHOWEXTENSIONS", // 0x0002
  143. "SSF_WIN95UNUSED", // 0x0004 // ;Internal - corresponding SHELLSTATE fields don't exist in SHELLFLAGSTATE
  144. "SSF_SHOWCOMPCOLOR", // 0x0008
  145. "SSF_SORTCOLUMNS", // 0x0010 // ;Internal - corresponding SHELLSTATE fields don't exist in SHELLFLAGSTATE
  146. "SSF_SHOWSYSFILES", // 0x0020
  147. "SSF_DOUBLECLICKINWEBVIEW", // 0x0080
  148. "SSF_SHOWATTRIBCOL", // 0x0100
  149. "SSF_DESKTOPHTML", // 0x0200
  150. "SSF_WIN95CLASSIC", // 0x0400
  151. "SSF_DONTPRETTYPATH", // 0x0800
  152. "SSF_MAPNETDRVBUTTON", // 0x1000
  153. "SSF_SHOWINFOTIP", // 0x2000
  154. "SSF_HIDEICONS", // 0x4000
  155. "SSF_NOCONFIRMRECYCLE", // 0x8000
  156. "SSF_FILTER", // 0x00010000 // ;Internal - corresponding SHELLSTATE fields don't exist in SHELLFLAGSTATE
  157. "SSF_WEBVIEW", // 0x00020000 // ;Internal
  158. "SSF_SHOWSUPERHIDDEN", // 0x00040000 // ;Internal
  159. "SSF_SEPPROCESS", // 0x00080000 // ;Internal
  160. "SSF_NONETCRAWLING", // 0x00100000 // ;Internal
  161. "SSF_STARTPANELON", // 0x00200000 // ;Internal
  162. NULL
  163. };
  164. enum GF_FLAGS {
  165. GL_SFGAO = 0,
  166. GL_SLDF,
  167. GL_FWF,
  168. GL_ICI,
  169. GL_FD,
  170. GL_SHCNE,
  171. GL_SSF,
  172. GF_MAX,
  173. };
  174. struct _tagFlags
  175. {
  176. LPSTR * apszFlags;
  177. LPSTR pszFlagsname;
  178. } argFlag[GF_MAX] =
  179. {
  180. {apszSFGAOFlags, "SFGAO"},
  181. {apszSLDFFlags, "SLD"},
  182. {apszFWFFlags, "FWF"},
  183. {apszICIFlags, "ICIFLAG"},
  184. {apszFDFlags, "FD"},
  185. {apszSHCNEFlags, "SHCNE"},
  186. {apszSSFFlags, "SSF"}
  187. };
  188. /************************************************************************\
  189. * Procedure: GetFlags
  190. *
  191. * Description:
  192. *
  193. * Converts a 32bit set of flags into an appropriate string.
  194. * pszBuf should be large enough to hold this string, no checks are done.
  195. * pszBuf can be NULL, allowing use of a local static buffer but note that
  196. * this is not reentrant.
  197. * Output string has the form: "FLAG1 | FLAG2 ..." or "0"
  198. *
  199. * Returns: pointer to given or static buffer with string in it.
  200. *
  201. * 6/9/1995 Created SanfordS
  202. * 11/5/1997 cdturner changed the aapszFlag type
  203. *
  204. \************************************************************************/
  205. LPSTR GetFlags(
  206. WORD wType,
  207. DWORD dwFlags,
  208. LPSTR pszBuf,
  209. BOOL fPrintZero)
  210. {
  211. static char szT[512];
  212. WORD i;
  213. BOOL fFirst = TRUE;
  214. BOOL fNoMoreNames = FALSE;
  215. LPSTR *apszFlags;
  216. if (pszBuf == NULL) {
  217. pszBuf = szT;
  218. }
  219. if (!bShowFlagNames) {
  220. sprintf(pszBuf, "%x", dwFlags);
  221. return pszBuf;
  222. }
  223. *pszBuf = '\0';
  224. if (wType >= GF_MAX) {
  225. strcpy(pszBuf, "Invalid flag type.");
  226. return pszBuf;
  227. }
  228. apszFlags = argFlag[wType].apszFlags;
  229. for (i = 0; dwFlags; dwFlags >>= 1, i++) {
  230. if (!fNoMoreNames && apszFlags[i] == NULL) {
  231. fNoMoreNames = TRUE;
  232. }
  233. if (dwFlags & 1) {
  234. if (!fFirst) {
  235. strcat(pszBuf, " | ");
  236. } else {
  237. fFirst = FALSE;
  238. }
  239. if (fNoMoreNames || apszFlags[i] == NO_FLAG) {
  240. char ach[16];
  241. sprintf(ach, "0x%lx", 1 << i);
  242. strcat(pszBuf, ach);
  243. } else {
  244. strcat(pszBuf, apszFlags[i]);
  245. }
  246. }
  247. }
  248. if (fFirst && fPrintZero) {
  249. sprintf(pszBuf, "0");
  250. }
  251. return pszBuf;
  252. }
  253. /************************************************************************\
  254. * Procedure: Iflags
  255. *
  256. * Description:
  257. *
  258. * outputs the list of flags for the given flags type
  259. *
  260. * 11/5/1997 Created cdturner
  261. *
  262. \************************************************************************/
  263. BOOL Iflags( DWORD dwOpts,
  264. LPSTR pszArgs )
  265. {
  266. CHAR szBuffer[100];
  267. int iOffset = 0;
  268. int iFlags;
  269. LPDWORD pAddr;
  270. BOOL bAddr = FALSE;
  271. DWORD dwValue;
  272. LPSTR pszOut;
  273. if ( dwOpts & OFLAG(l))
  274. {
  275. // list all the struct names
  276. Print("Flags types known:\n");
  277. for ( iFlags = 0; iFlags < GF_MAX; iFlags ++ )
  278. {
  279. sprintf( szBuffer, " %s\n", argFlag[iFlags].pszFlagsname);
  280. Print( szBuffer );
  281. }
  282. return TRUE;
  283. }
  284. // skip whitespace
  285. while ( *pszArgs == ' ' )
  286. pszArgs ++;
  287. // now grab the flagsname
  288. while ( pszArgs[iOffset] != ' ' && pszArgs[iOffset] != '\0' )
  289. {
  290. szBuffer[iOffset] = pszArgs[iOffset];
  291. iOffset ++;
  292. };
  293. // terminate the string
  294. szBuffer[iOffset] = 0;
  295. // find the flags value
  296. for ( iFlags = 0; iFlags < GF_MAX; iFlags ++ )
  297. {
  298. if ( lstrcmpA( szBuffer, argFlag[iFlags].pszFlagsname ) == 0 )
  299. break;
  300. }
  301. if ( iFlags >= GF_MAX )
  302. {
  303. Print( "unknown flagsname - ");
  304. Print( szBuffer );
  305. Print( "\n" );
  306. return TRUE;
  307. }
  308. // skip white space
  309. while ( pszArgs[iOffset] == ' ' )
  310. iOffset ++;
  311. if ( pszArgs[iOffset] == '*' )
  312. {
  313. bAddr = TRUE;
  314. iOffset ++;
  315. }
  316. pAddr = (LPDWORD) EvalExp( pszArgs + iOffset );
  317. if ( bAddr )
  318. {
  319. if ( !tryDword( &dwValue, pAddr ) )
  320. {
  321. Print( "unable to access memory at that location\n");
  322. return TRUE;
  323. }
  324. }
  325. else
  326. {
  327. dwValue = PtrToUlong(pAddr);
  328. }
  329. pszOut = GetFlags( (WORD) iFlags, dwValue, NULL, TRUE );
  330. if ( pszOut )
  331. {
  332. sprintf( szBuffer, "Value = %8X, pAddr = %8X\n", dwValue, (DWORD_PTR)pAddr );
  333. Print( szBuffer );
  334. Print( pszOut );
  335. Print( "\n" );
  336. }
  337. return TRUE;
  338. }
  339. /************************************************************************\
  340. * Procedure: Itest
  341. *
  342. * Description: Tests the basic stdexts macros and functions - a good check
  343. * on the debugger extensions in general before you waste time debuging
  344. * entensions.
  345. *
  346. * Returns: fSuccess
  347. *
  348. * 11/4/1997 Created cdturner
  349. *
  350. \************************************************************************/
  351. BOOL Itest()
  352. {
  353. Print("Print test!\n");
  354. SAFEWHILE(TRUE)
  355. {
  356. Print("SAFEWHILE test... Hit Ctrl-C NOW!\n");
  357. }
  358. return TRUE;
  359. }
  360. /************************************************************************\
  361. * Procedure: Iver
  362. *
  363. * Description: Dumps versions of extensions and winsrv/win32k
  364. *
  365. * Returns: fSuccess
  366. *
  367. * 11/4/1997 Created cdturner
  368. *
  369. \************************************************************************/
  370. BOOL Iver()
  371. {
  372. #if DEBUG
  373. Print("SHLEXTS version: Debug.\n");
  374. #else
  375. Print("SHLEXTS version: Retail.\n");
  376. #endif
  377. return TRUE;
  378. }
  379. /************************************************************************\
  380. *
  381. * DumpVerboseFileInfo
  382. *
  383. * Stolen from MSDN.
  384. *
  385. \************************************************************************/
  386. typedef struct LANGANDCODEPAGE {
  387. WORD wLang;
  388. WORD wCP;
  389. } LANGANDCODEPAGE;
  390. void DumpVersionString(LPVOID pBlock, LANGANDCODEPAGE *lpTranslate, LPCSTR pszKey)
  391. {
  392. char szBuf[128];
  393. LPSTR pszValue;
  394. DWORD cb;
  395. wsprintfA(szBuf, "\\StringFileInfo\\%04x%04x\\%s",
  396. lpTranslate->wLang, lpTranslate->wCP, pszKey);
  397. if (VerQueryValueA(pBlock, szBuf, (LPVOID*)&pszValue, &cb) &&
  398. lstrlenA(pszValue)) // lstrlen traps exceptions
  399. {
  400. Print(szBuf+16); // skip over "\\StringFileInfo\\"
  401. Print(" = ");
  402. Print(pszValue);
  403. Print("\n");
  404. }
  405. }
  406. LPCSTR c_rgszVersionKeys[] =
  407. {
  408. "CompanyName",
  409. "FileDescription",
  410. "InternalName",
  411. "OriginalFilename",
  412. "ProductName",
  413. "ProductVersion",
  414. "FileVersion",
  415. "LegalCopyright",
  416. "LegalTrademarks",
  417. "PrivateBuild",
  418. "SpecialBuild",
  419. "Comments",
  420. NULL,
  421. };
  422. void DumpVerboseFileInfo(LPVOID pBlock)
  423. {
  424. LANGANDCODEPAGE *lpTranslate;
  425. DWORD cbTranslate;
  426. // Read the list of languages and code pages
  427. if (VerQueryValueA(pBlock, "\\VarFileInfo\\Translation",
  428. (LPVOID*)&lpTranslate, &cbTranslate))
  429. {
  430. UINT i;
  431. for (i = 0; i < cbTranslate/sizeof(*lpTranslate) && !IsCtrlCHit(); i++)
  432. {
  433. LPCSTR *ppszVK;
  434. for (ppszVK = c_rgszVersionKeys; *ppszVK && !IsCtrlCHit(); ppszVK++)
  435. {
  436. DumpVersionString(pBlock, &lpTranslate[i], *ppszVK);
  437. }
  438. }
  439. }
  440. }
  441. /************************************************************************\
  442. * Procedure: Ifilever
  443. *
  444. * Description: Dumps versions of extensions and winsrv/win32k
  445. *
  446. * Returns: fSuccess
  447. *
  448. * 11/4/1997 Created cdturner
  449. *
  450. \************************************************************************/
  451. BOOL Ifilever( DWORD dwOpts,
  452. LPSTR pszArgs )
  453. {
  454. HINSTANCE hDll = NULL;
  455. DLLGETVERSIONPROC pGetVer = NULL;
  456. DWORD dwHandle;
  457. DWORD dwBlockLen;
  458. LPVOID pBlock = NULL;
  459. char szMessage[200];
  460. BOOL fSkipLoad = FALSE;
  461. if ( pszArgs == NULL || lstrlenA( pszArgs ) == 0 )
  462. {
  463. pszArgs = "Shell32.dll"; // default filename
  464. }
  465. if ( !dwOpts )
  466. {
  467. dwOpts = OFLAG(n); // default flags
  468. }
  469. Print("filever ");
  470. Print(pszArgs);
  471. Print("\n");
  472. if ( dwOpts & OFLAG(d) )
  473. {
  474. hDll = LoadLibraryA(pszArgs);
  475. if ( hDll == NULL )
  476. {
  477. Print("LoadLibrary failed\n");
  478. }
  479. else
  480. {
  481. pGetVer = (DLLGETVERSIONPROC) GetProcAddress( hDll, "DllGetVersion");
  482. if ( pGetVer )
  483. {
  484. DLLVERSIONINFO rgVerInfo;
  485. rgVerInfo.cbSize = sizeof( rgVerInfo );
  486. pGetVer( &rgVerInfo );
  487. wsprintfA( szMessage, "DllGetVersion\n Major = %d\n Minor = %d\n Build = %d\n",
  488. rgVerInfo.dwMajorVersion, rgVerInfo.dwMinorVersion, rgVerInfo.dwBuildNumber );
  489. Print(szMessage );
  490. }
  491. FreeLibrary( hDll );
  492. }
  493. }
  494. if ( dwOpts & (OFLAG(n) | OFLAG(v)) )
  495. {
  496. // now test the normal version details...
  497. dwBlockLen = GetFileVersionInfoSizeA( pszArgs, &dwHandle );
  498. if ( dwBlockLen == 0 )
  499. {
  500. Print("GetFileVersionSize failed\n");
  501. }
  502. else
  503. {
  504. pBlock = LocalAlloc( LPTR, dwBlockLen );
  505. if ( pBlock )
  506. {
  507. if (GetFileVersionInfoA( pszArgs, dwHandle, dwBlockLen, pBlock ))
  508. {
  509. VS_FIXEDFILEINFO * pFileInfo;
  510. UINT uLen;
  511. VerQueryValueA( pBlock, "\\", (LPVOID *) &pFileInfo, &uLen );
  512. Print("GetFileVersionInfo\n");
  513. wsprintfA( szMessage, "Version: %d.%d.%d.%d (0x%08x`%08x)\n",
  514. HIWORD(pFileInfo->dwFileVersionMS),
  515. LOWORD(pFileInfo->dwFileVersionMS),
  516. HIWORD(pFileInfo->dwFileVersionLS),
  517. LOWORD(pFileInfo->dwFileVersionLS),
  518. pFileInfo->dwFileVersionMS,
  519. pFileInfo->dwFileVersionLS);
  520. Print( szMessage );
  521. }
  522. if (dwOpts & OFLAG(v))
  523. {
  524. DumpVerboseFileInfo(pBlock);
  525. }
  526. LocalFree( pBlock );
  527. }
  528. }
  529. }
  530. return TRUE;
  531. }