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.

437 lines
12 KiB

  1. //--------------------------------------------------------------------------------
  2. //
  3. // File: propsext.cpp
  4. //
  5. // General handling of OLE Entry points, CClassFactory and CPropSheetExt
  6. //
  7. // Common Code for all display property sheet extension
  8. //
  9. // Copyright (c) Microsoft Corp. 1992-1998 All Rights Reserved
  10. //
  11. //--------------------------------------------------------------------------------
  12. #include "shfusion.h"
  13. //---------------------------------------------------------------------------
  14. // Globals
  15. //---------------------------------------------------------------------------
  16. //
  17. // Count number of objects and number of locks.
  18. //
  19. HINSTANCE g_hInst = NULL;
  20. BOOL g_RunningOnNT = FALSE;
  21. LPDATAOBJECT g_lpdoTarget = NULL;
  22. ULONG g_cObj = 0;
  23. ULONG g_cLock = 0;
  24. //---------------------------------------------------------------------------
  25. // DllMain()
  26. //---------------------------------------------------------------------------
  27. int APIENTRY DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID )
  28. {
  29. if (dwReason == DLL_PROCESS_ATTACH) // Initializing
  30. {
  31. if ((int)GetVersion() >= 0)
  32. {
  33. g_RunningOnNT = TRUE;
  34. }
  35. g_hInst = hInstance;
  36. DisableThreadLibraryCalls(hInstance);
  37. SHFusionInitializeFromModuleID(hInstance, 124);
  38. }
  39. else if (dwReason == DLL_PROCESS_DETACH)
  40. {
  41. SHFusionUninitialize();
  42. }
  43. return 1;
  44. }
  45. //---------------------------------------------------------------------------
  46. // DllGetClassObject()
  47. //
  48. // If someone calls with our CLSID, create an IClassFactory and pass it to
  49. // them, so they can create and use one of our CPropSheetExt objects.
  50. //
  51. //---------------------------------------------------------------------------
  52. STDAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, LPVOID* ppvOut )
  53. {
  54. *ppvOut = NULL; // Assume Failure
  55. if( IsEqualCLSID( rclsid, g_CLSID_CplExt ) )
  56. {
  57. //
  58. //Check that we can provide the interface
  59. //
  60. if( IsEqualIID( riid, IID_IUnknown) ||
  61. IsEqualIID( riid, IID_IClassFactory )
  62. )
  63. {
  64. //Return our IClassFactory for CPropSheetExt objects
  65. *ppvOut = (LPVOID* )new CClassFactory();
  66. if( NULL != *ppvOut )
  67. {
  68. //AddRef the object through any interface we return
  69. ((CClassFactory*)*ppvOut)->AddRef();
  70. return NOERROR;
  71. }
  72. return E_OUTOFMEMORY;
  73. }
  74. return E_NOINTERFACE;
  75. }
  76. else
  77. {
  78. return CLASS_E_CLASSNOTAVAILABLE;
  79. }
  80. }
  81. //---------------------------------------------------------------------------
  82. // DllCanUnloadNow()
  83. //
  84. // If we are not locked, and no objects are active, then we can exit.
  85. //
  86. //---------------------------------------------------------------------------
  87. STDAPI DllCanUnloadNow()
  88. {
  89. SCODE sc;
  90. //
  91. //Our answer is whether there are any object or locks
  92. //
  93. sc = (0L == g_cObj && 0 == g_cLock) ? S_OK : S_FALSE;
  94. return ResultFromScode(sc);
  95. }
  96. //---------------------------------------------------------------------------
  97. // ObjectDestroyed()
  98. //
  99. // Function for the CPropSheetExt object to call when it is destroyed.
  100. // Because we're in a DLL, we only track the number of objects here,
  101. // letting DllCanUnloadNow take care of the rest.
  102. //---------------------------------------------------------------------------
  103. void FAR PASCAL ObjectDestroyed( void )
  104. {
  105. g_cObj--;
  106. return;
  107. }
  108. UINT CALLBACK PropertySheetCallback(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
  109. {
  110. switch (uMsg) {
  111. case PSPCB_CREATE:
  112. return TRUE; // return TRUE to continue with creation of page
  113. case PSPCB_RELEASE:
  114. if (g_lpdoTarget) {
  115. g_lpdoTarget->Release();
  116. g_lpdoTarget = NULL;
  117. }
  118. return 0; // return value ignored
  119. default:
  120. break;
  121. }
  122. return TRUE;
  123. }
  124. //***************************************************************************
  125. //
  126. // CClassFactory Class
  127. //
  128. //***************************************************************************
  129. //---------------------------------------------------------------------------
  130. // Constructor
  131. //---------------------------------------------------------------------------
  132. CClassFactory::CClassFactory()
  133. {
  134. m_cRef = 0L;
  135. return;
  136. }
  137. //---------------------------------------------------------------------------
  138. // Destructor
  139. //---------------------------------------------------------------------------
  140. CClassFactory::~CClassFactory( void )
  141. {
  142. return;
  143. }
  144. //---------------------------------------------------------------------------
  145. // QueryInterface()
  146. //---------------------------------------------------------------------------
  147. STDMETHODIMP CClassFactory::QueryInterface( REFIID riid, LPVOID* ppv )
  148. {
  149. *ppv = NULL;
  150. //Any interface on this object is the object pointer.
  151. if( IsEqualIID( riid, IID_IUnknown ) ||
  152. IsEqualIID( riid, IID_IClassFactory )
  153. )
  154. {
  155. *ppv = (LPVOID)this;
  156. ++m_cRef;
  157. return NOERROR;
  158. }
  159. return E_NOINTERFACE;
  160. }
  161. //---------------------------------------------------------------------------
  162. // AddRef()
  163. //---------------------------------------------------------------------------
  164. STDMETHODIMP_(ULONG) CClassFactory::AddRef()
  165. {
  166. return ++m_cRef;
  167. }
  168. //---------------------------------------------------------------------------
  169. // Release()
  170. //---------------------------------------------------------------------------
  171. STDMETHODIMP_(ULONG) CClassFactory::Release()
  172. {
  173. ULONG cRefT;
  174. cRefT = --m_cRef;
  175. if( 0L == m_cRef )
  176. delete this;
  177. return cRefT;
  178. }
  179. // Allow the caller to specify another class to use. The only requirement
  180. // is that there be a contructore with (punk, void FAR PASCAL pfnObjDes(void) )
  181. #ifndef PROPSHEET_CLASS
  182. #define PROPSHEET_CLASS CPropSheetExt
  183. #endif // PROPSHEET_CLASS
  184. //---------------------------------------------------------------------------
  185. // CreateInstance()
  186. //---------------------------------------------------------------------------
  187. STDMETHODIMP
  188. CClassFactory::CreateInstance( LPUNKNOWN pUnkOuter,
  189. REFIID riid,
  190. LPVOID FAR *ppvObj
  191. )
  192. {
  193. CPropSheetExt* pObj;
  194. HRESULT hr = E_OUTOFMEMORY;
  195. *ppvObj = NULL;
  196. // We don't support aggregation at all.
  197. if( pUnkOuter )
  198. {
  199. return CLASS_E_NOAGGREGATION;
  200. }
  201. //Verify that a controlling unknown asks for IShellPropSheetExt
  202. if( IsEqualIID( riid, IID_IShellPropSheetExt ) )
  203. {
  204. //Create the object, passing function to notify on destruction
  205. pObj = new PROPSHEET_CLASS(pUnkOuter, ObjectDestroyed);
  206. if( NULL == pObj )
  207. {
  208. return hr;
  209. }
  210. hr = pObj->QueryInterface( riid, ppvObj );
  211. //Kill the object if initial creation or FInit failed.
  212. if( FAILED(hr) )
  213. {
  214. delete pObj;
  215. }
  216. else
  217. {
  218. g_cObj++;
  219. }
  220. return hr;
  221. }
  222. return E_NOINTERFACE;
  223. }
  224. //---------------------------------------------------------------------------
  225. // LockServer()
  226. //---------------------------------------------------------------------------
  227. STDMETHODIMP CClassFactory::LockServer( BOOL fLock )
  228. {
  229. if( fLock )
  230. {
  231. g_cLock++;
  232. }
  233. else
  234. {
  235. g_cLock--;
  236. }
  237. return NOERROR;
  238. }
  239. //***************************************************************************
  240. //
  241. // CPropSheetExt Class
  242. //
  243. //***************************************************************************
  244. //---------------------------------------------------------------------------
  245. // Constructor
  246. //---------------------------------------------------------------------------
  247. CPropSheetExt::CPropSheetExt( LPUNKNOWN pUnkOuter, LPFNDESTROYED pfnDestroy )
  248. {
  249. m_cRef = 0;
  250. m_pUnkOuter = pUnkOuter;
  251. m_pfnDestroy = pfnDestroy;
  252. return;
  253. }
  254. //---------------------------------------------------------------------------
  255. // Destructor
  256. //---------------------------------------------------------------------------
  257. CPropSheetExt::~CPropSheetExt( void )
  258. {
  259. return;
  260. }
  261. //---------------------------------------------------------------------------
  262. // QueryInterface()
  263. //---------------------------------------------------------------------------
  264. STDMETHODIMP CPropSheetExt::QueryInterface( REFIID riid, LPVOID* ppv )
  265. {
  266. *ppv = NULL;
  267. if (IsEqualIID(riid, IID_IShellExtInit))
  268. {
  269. *ppv = (IShellExtInit *) this;
  270. }
  271. if (IsEqualIID(riid, IID_IShellPropSheetExt))
  272. {
  273. *ppv = (LPVOID)this;
  274. }
  275. if (*ppv)
  276. {
  277. ++m_cRef;
  278. return NOERROR;
  279. }
  280. return ResultFromScode(E_NOINTERFACE);
  281. }
  282. //---------------------------------------------------------------------------
  283. // AddRef()
  284. //---------------------------------------------------------------------------
  285. STDMETHODIMP_(ULONG) CPropSheetExt::AddRef( void )
  286. {
  287. return ++m_cRef;
  288. }
  289. //---------------------------------------------------------------------------
  290. // Release()
  291. //---------------------------------------------------------------------------
  292. STDMETHODIMP_(ULONG) CPropSheetExt::Release( void )
  293. {
  294. ULONG cRefT;
  295. cRefT = --m_cRef;
  296. if( m_cRef == 0 )
  297. {
  298. // Tell the housing that an object is going away so that it
  299. // can shut down if appropriate.
  300. if( NULL != m_pfnDestroy )
  301. {
  302. (*m_pfnDestroy)();
  303. }
  304. delete this;
  305. }
  306. return cRefT;
  307. }
  308. //---------------------------------------------------------------------------
  309. // AddPages()
  310. //---------------------------------------------------------------------------
  311. STDMETHODIMP CPropSheetExt::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam )
  312. {
  313. PROPSHEETPAGE psp;
  314. HPROPSHEETPAGE hpage;
  315. TCHAR szTitle[ 30 ];
  316. LoadString( g_hInst, IDS_PAGE_TITLE, szTitle, ARRAYSIZE(szTitle) );
  317. psp.dwSize = sizeof(PROPSHEETPAGE);
  318. psp.dwFlags = PSP_USETITLE | PSP_USECALLBACK;
  319. psp.hIcon = NULL;
  320. psp.hInstance = g_hInst;
  321. psp.pszTemplate =MAKEINTRESOURCE( PROP_SHEET_DLG );
  322. psp.pfnDlgProc = PropertySheetDlgProc;
  323. psp.pfnCallback = PropertySheetCallback;
  324. psp.pszTitle = szTitle;
  325. psp.lParam = 0;
  326. #ifdef USESLINKCONTROL
  327. LinkWindow_RegisterClass();
  328. #endif
  329. if( ( hpage = CreatePropertySheetPage( &psp ) ) == NULL )
  330. {
  331. return ( E_OUTOFMEMORY );
  332. }
  333. if( !lpfnAddPage(hpage, lParam ) )
  334. {
  335. DestroyPropertySheetPage(hpage );
  336. return ( E_FAIL );
  337. }
  338. return NOERROR;
  339. }
  340. //---------------------------------------------------------------------------
  341. // ReplacePage()
  342. //---------------------------------------------------------------------------
  343. STDMETHODIMP CPropSheetExt::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam )
  344. {
  345. return NOERROR;
  346. }
  347. //---------------------------------------------------------------------------
  348. // IShellExtInit member function- this interface needs only one
  349. //---------------------------------------------------------------------------
  350. STDMETHODIMP CPropSheetExt::Initialize(LPCITEMIDLIST pcidlFolder,
  351. LPDATAOBJECT pdoTarget,
  352. HKEY hKeyID)
  353. {
  354. // The target data object is an HDROP, or list of files from the shell.
  355. if (g_lpdoTarget)
  356. {
  357. g_lpdoTarget->Release();
  358. g_lpdoTarget = NULL;
  359. }
  360. if (pdoTarget)
  361. {
  362. g_lpdoTarget = pdoTarget;
  363. g_lpdoTarget->AddRef();
  364. }
  365. return NOERROR;
  366. }