Leaked source code of windows server 2003
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.

212 lines
5.8 KiB

  1. // ShlExt.cpp : Implementation of CVSSShellExt
  2. #include "stdafx.h"
  3. #include "Vssui.h"
  4. #include "ShlExt.h"
  5. #include "vssprop.h"
  6. #include <shellapi.h>
  7. /////////////////////////////////////////////////////////////////////////////
  8. // CVSSShellExt
  9. CVSSShellExt::CVSSShellExt()
  10. {
  11. #ifdef DEBUG
  12. OutputDebugString(_T("CVSSShellExt::CVSSShellExt\n"));
  13. #endif
  14. m_lpszFile = NULL;
  15. }
  16. CVSSShellExt::~CVSSShellExt()
  17. {
  18. #ifdef DEBUG
  19. OutputDebugString(_T("CVSSShellExt::~CVSSShellExt\n"));
  20. #endif
  21. if (m_lpszFile)
  22. {
  23. delete [] m_lpszFile;
  24. m_lpszFile = NULL;
  25. }
  26. }
  27. STDMETHODIMP CVSSShellExt::Initialize(
  28. IN LPCITEMIDLIST pidlFolder, // For property sheet extensions, this parameter is NULL
  29. IN LPDATAOBJECT lpdobj,
  30. IN HKEY hkeyProgID // not used in property sheet extensions
  31. )
  32. {
  33. HRESULT hr = S_OK;
  34. if ((IDataObject *)m_spiDataObject)
  35. m_spiDataObject.Release();
  36. if (lpdobj)
  37. {
  38. m_spiDataObject = lpdobj;
  39. STGMEDIUM medium;
  40. FORMATETC fe = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  41. UINT uCount = 0;
  42. hr = m_spiDataObject->GetData(&fe, &medium);
  43. if (FAILED(hr))
  44. {
  45. fe.cfFormat = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_MOUNTEDVOLUME);
  46. hr = m_spiDataObject->GetData(&fe, &medium);
  47. }
  48. if (SUCCEEDED(hr))
  49. {
  50. if (m_lpszFile)
  51. {
  52. delete [] m_lpszFile;
  53. m_lpszFile = NULL;
  54. }
  55. uCount = DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, NULL, 0);
  56. if (uCount > 0)
  57. {
  58. UINT uiChars = DragQueryFile ((HDROP) medium.hGlobal, 0, NULL, 0);
  59. m_lpszFile = new TCHAR [uiChars + 1];
  60. if (!m_lpszFile)
  61. {
  62. hr = E_OUTOFMEMORY;
  63. } else
  64. {
  65. ZeroMemory(m_lpszFile, sizeof(TCHAR) * (uiChars + 1));
  66. DragQueryFile ((HDROP) medium.hGlobal, 0, m_lpszFile, uiChars + 1);
  67. }
  68. } else
  69. {
  70. hr = E_FAIL;
  71. }
  72. ReleaseStgMedium(&medium);
  73. }
  74. }
  75. return hr;
  76. }
  77. LPFNPSPCALLBACK _OldPropertyPageCallback;
  78. UINT CALLBACK _NewPropertyPageCallback(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
  79. {
  80. ASSERT(_OldPropertyPageCallback);
  81. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  82. //
  83. // First, let the old callback function handles the msg.
  84. //
  85. UINT i = _OldPropertyPageCallback(hwnd, uMsg, ppsp);
  86. //
  87. // Then, we release our page here
  88. //
  89. if (uMsg == PSPCB_RELEASE)
  90. {
  91. ASSERT(ppsp);
  92. CVSSProp* pPage = (CVSSProp*)(ppsp->lParam);
  93. ASSERT(pPage);
  94. delete pPage;
  95. }
  96. return i;
  97. }
  98. void ReplacePropertyPageCallback(void* vpsp)
  99. {
  100. ASSERT(vpsp);
  101. LPPROPSHEETPAGE ppsp = (LPPROPSHEETPAGE)vpsp;
  102. _OldPropertyPageCallback = ppsp->pfnCallback; // save the old callback function
  103. ppsp->pfnCallback = _NewPropertyPageCallback; // replace with our own callback
  104. }
  105. //
  106. // From RaymondC:
  107. // If you didn't add a page, you still return S_OK -- you successfully added zero pages.
  108. // If you add some pages and then you want one of those added pages to be the default,
  109. // you return ResultFromShort(pagenumber+1). S_FALSE = ResultFromShort(1).
  110. //
  111. STDMETHODIMP CVSSShellExt::AddPages(
  112. IN LPFNADDPROPSHEETPAGE lpfnAddPage,
  113. IN LPARAM lParam
  114. )
  115. {
  116. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  117. //
  118. // we only add our page if local machine is postW2K server
  119. //
  120. if (!IsPostW2KServer(NULL))
  121. return S_OK;
  122. //
  123. // we only add our page for local fixed non-FAT drive
  124. //
  125. if (DRIVE_FIXED != GetDriveType(m_lpszFile))
  126. return S_OK;
  127. TCHAR szFileSystemName[MAX_PATH] = _T("");
  128. DWORD dwMaxCompLength = 0, dwFileSystemFlags = 0;
  129. GetVolumeInformation(m_lpszFile, NULL, 0, NULL, &dwMaxCompLength,
  130. &dwFileSystemFlags, szFileSystemName, MAX_PATH);
  131. if (CSTR_EQUAL != CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, _T("NTFS"), -1, szFileSystemName, -1))
  132. return S_OK;
  133. CVSSProp *pPage = new CVSSProp(_T(""), m_lpszFile);
  134. if (!pPage)
  135. return E_OUTOFMEMORY;
  136. if (pPage->m_psp.dwFlags & PSP_USECALLBACK)
  137. {
  138. //
  139. // Replace with our own callback function such that we can delete pPage
  140. // when the property sheet is closed.
  141. //
  142. // Note: don't change m_psp.lParam, which has to point to CVSSProp object;
  143. // otherwise, MFC won't hook up message handler correctly.
  144. //
  145. ReplacePropertyPageCallback(&(pPage->m_psp));
  146. //
  147. // Fusion MFC-based property page
  148. //
  149. PROPSHEETPAGE_V3 sp_v3 = {0};
  150. CopyMemory (&sp_v3, &(pPage->m_psp), (pPage->m_psp).dwSize);
  151. sp_v3.dwSize = sizeof(sp_v3);
  152. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&sp_v3);
  153. if (hPage)
  154. {
  155. if (lpfnAddPage(hPage, lParam))
  156. {
  157. // Store this pointer in pPage in order to keep our dll loaded,
  158. // it will be released when pPage gets deleted.
  159. pPage->StoreShellExtPointer((IShellPropSheetExt *)this);
  160. return S_OK;
  161. }
  162. DestroyPropertySheetPage(hPage);
  163. hPage = NULL;
  164. }
  165. }
  166. delete pPage;
  167. return S_OK;
  168. }
  169. //
  170. // The shell doesn't call ReplacePage
  171. //
  172. STDMETHODIMP CVSSShellExt::ReplacePage(
  173. IN UINT uPageID,
  174. IN LPFNADDPROPSHEETPAGE lpfnReplaceWith,
  175. IN LPARAM lParam
  176. )
  177. {
  178. return E_NOTIMPL;
  179. }