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.

153 lines
4.0 KiB

  1. #include <windows.h>
  2. #include <shlwapi.h>
  3. #include <commctrl.h>
  4. #include "dataitem.h"
  5. #include "resource.h"
  6. #include "stdio.h"
  7. #include "util.h"
  8. #define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
  9. #define EXPLORER_EXE_STRING TEXT("explorer.exe")
  10. CDataItem::CDataItem()
  11. {
  12. m_pszTitle = m_pszCmdLine = m_pszArgs = NULL;
  13. m_dwFlags = 0;
  14. }
  15. CDataItem::~CDataItem()
  16. {
  17. if ( m_pszTitle )
  18. delete [] m_pszTitle;
  19. if ( m_pszCmdLine )
  20. delete [] m_pszCmdLine;
  21. if ( m_pszArgs )
  22. delete [] m_pszArgs;
  23. }
  24. BOOL CDataItem::SetData( LPTSTR szTitle, LPTSTR szCmd, LPTSTR szArgs, DWORD dwFlags, DWORD dwType)
  25. {
  26. TCHAR * psz;
  27. // This function should only be called once or else we will leak like a, like a, a thing that leaks a lot.
  28. ASSERT( NULL==m_pszTitle && NULL==m_pszMenuName && NULL==m_pszDescription && NULL==m_pszCmdLine && NULL==m_pszArgs );
  29. m_pszTitle = new TCHAR[lstrlen(szTitle)+1];
  30. if ( m_pszTitle )
  31. lstrcpy( m_pszTitle, szTitle );
  32. m_pszCmdLine = new TCHAR[lstrlen(szCmd)+1];
  33. if ( m_pszCmdLine )
  34. lstrcpy( m_pszCmdLine, szCmd );
  35. if ( szArgs )
  36. {
  37. // Some commands don't have any args so this can remain NULL. This is only used
  38. // if the executable requires arguments.
  39. m_pszArgs = new TCHAR[lstrlen(szArgs)+1];
  40. if ( m_pszArgs )
  41. lstrcpy( m_pszArgs, szArgs );
  42. }
  43. m_dwType = dwType;
  44. m_dwFlags = dwFlags;
  45. return TRUE;
  46. }
  47. BOOL CDataItem::Invoke(HWND hwnd)
  48. {
  49. TCHAR szBuffer1[1000];
  50. TCHAR szBuffer2[1000];
  51. LPTSTR pszExecutable = NULL;
  52. LPTSTR pszArgs = NULL;
  53. if ( NULL != m_pszCmdLine )
  54. {
  55. ExpandEnvironmentStrings(m_pszCmdLine, szBuffer1, ARRAYSIZE(szBuffer1));
  56. pszExecutable = szBuffer1;
  57. }
  58. if ( NULL != m_pszArgs )
  59. {
  60. ExpandEnvironmentStrings(m_pszArgs, szBuffer2, ARRAYSIZE(szBuffer2));
  61. pszArgs = szBuffer2;
  62. }
  63. BOOL fResult = FALSE;
  64. if (0 == strncmp(pszExecutable, EXPLORER_EXE_STRING, ARRAYSIZE(EXPLORER_EXE_STRING))) // explorer paths must be ShellExecuted
  65. {
  66. fResult = ((INT_PTR)ShellExecute(hwnd, TEXT("open"), pszArgs, NULL, NULL, SW_SHOWNORMAL) > 32);
  67. }
  68. else
  69. {
  70. TCHAR szDirectory[MAX_PATH];
  71. if (GetModuleFileName(NULL, szDirectory, ARRAYSIZE(szDirectory)) &&
  72. _PathRemoveFileSpec(szDirectory))
  73. {
  74. fResult = ((INT_PTR)ShellExecute(hwnd, NULL, pszExecutable, pszArgs, szDirectory, SW_SHOWNORMAL) > 32);
  75. }
  76. }
  77. return fResult;
  78. }
  79. #define CH_WHACK TEXT(FILENAME_SEPARATOR)
  80. // stolen from shlwapi
  81. BOOL CDataItem::_PathRemoveFileSpec(LPTSTR pFile)
  82. {
  83. RIPMSG(pFile && IS_VALID_STRING_PTR(pFile, -1), "PathRemoveFileSpec: caller passed bad pFile");
  84. if (pFile)
  85. {
  86. LPTSTR pT;
  87. LPTSTR pT2 = pFile;
  88. for (pT = pT2; *pT2; pT2 = CharNext(pT2))
  89. {
  90. if (*pT2 == CH_WHACK)
  91. {
  92. pT = pT2; // last "\" found, (we will strip here)
  93. }
  94. else if (*pT2 == TEXT(':')) // skip ":\" so we don't
  95. {
  96. if (pT2[1] ==TEXT('\\')) // strip the "\" from "C:\"
  97. {
  98. pT2++;
  99. }
  100. pT = pT2 + 1;
  101. }
  102. }
  103. if (*pT == 0)
  104. {
  105. // didn't strip anything
  106. return FALSE;
  107. }
  108. else if (((pT == pFile) && (*pT == CH_WHACK)) || // is it the "\foo" case?
  109. ((pT == pFile+1) && (*pT == CH_WHACK && *pFile == CH_WHACK))) // or the "\\bar" case?
  110. {
  111. // Is it just a '\'?
  112. if (*(pT+1) != TEXT('\0'))
  113. {
  114. // Nope.
  115. *(pT+1) = TEXT('\0');
  116. return TRUE; // stripped something
  117. }
  118. else
  119. {
  120. // Yep.
  121. return FALSE;
  122. }
  123. }
  124. else
  125. {
  126. *pT = 0;
  127. return TRUE; // stripped something
  128. }
  129. }
  130. return FALSE;
  131. }