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.

389 lines
10 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #define INITGUID
  4. #include <initguid.h>
  5. #include "iids.h"
  6. #define DECL_CRTFREE
  7. #include <crtfree.h>
  8. HINSTANCE g_hInstance = 0;
  9. DWORD g_tls = 0;
  10. LONG g_cRef = 0;
  11. HRESULT _OpenSavedDsQuery(LPTSTR pSavedQuery);
  12. STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID pReserved)
  13. {
  14. switch (dwReason)
  15. {
  16. case DLL_PROCESS_ATTACH:
  17. SHFusionInitializeFromModule(hInstance);
  18. TraceSetMaskFromCLSID(CLSID_DsQuery);
  19. GLOBAL_HINSTANCE = hInstance;
  20. DisableThreadLibraryCalls(GLOBAL_HINSTANCE);
  21. break;
  22. case DLL_PROCESS_DETACH:
  23. SHFusionUninitialize();
  24. break;
  25. }
  26. return TRUE;
  27. }
  28. // Lifetime management of the DLL
  29. STDAPI_(void) DllAddRef()
  30. {
  31. InterlockedIncrement(&g_cRef);
  32. }
  33. STDAPI_(void) DllRelease()
  34. {
  35. InterlockedDecrement(&g_cRef);
  36. }
  37. STDAPI DllCanUnloadNow(VOID)
  38. {
  39. return (g_cRef > 0) ? S_FALSE : S_OK;
  40. }
  41. // expose objects
  42. CF_TABLE_BEGIN(g_ObjectInfo)
  43. // core query handler stuff
  44. CF_TABLE_ENTRY( &CLSID_CommonQuery, CCommonQuery_CreateInstance, COCREATEONLY),
  45. CF_TABLE_ENTRY( &CLSID_DsQuery, CDsQuery_CreateInstance, COCREATEONLY),
  46. CF_TABLE_ENTRY( &CLSID_DsFolderProperties, CDsFolderProperties_CreateInstance, COCREATEONLY),
  47. // start/find and context menu entries
  48. CF_TABLE_ENTRY( &CLSID_DsFind, CDsFind_CreateInstance, COCREATEONLY),
  49. CF_TABLE_ENTRY( &CLSID_DsStartFind, CDsFind_CreateInstance, COCREATEONLY),
  50. // column handler for object class and adspath
  51. CF_TABLE_ENTRY( &CLSID_PublishedAtCH, CQueryThreadCH_CreateInstance, COCREATEONLY),
  52. CF_TABLE_ENTRY( &CLSID_ObjectClassCH, CQueryThreadCH_CreateInstance, COCREATEONLY),
  53. CF_TABLE_ENTRY( &CLSID_MachineRoleCH, CQueryThreadCH_CreateInstance, COCREATEONLY),
  54. CF_TABLE_ENTRY( &CLSID_MachineOwnerCH, CQueryThreadCH_CreateInstance, COCREATEONLY),
  55. // domain query form specific column handlers
  56. CF_TABLE_ENTRY( &CLSID_PathElement1CH, CDomainCH_CreateInstance, COCREATEONLY),
  57. CF_TABLE_ENTRY( &CLSID_PathElement3CH, CDomainCH_CreateInstance, COCREATEONLY),
  58. CF_TABLE_ENTRY( &CLSID_PathElementDomainCH, CDomainCH_CreateInstance, COCREATEONLY),
  59. CF_TABLE_END(g_ObjectInfo)
  60. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
  61. {
  62. if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
  63. {
  64. for (LPCOBJECTINFO pcls = g_ObjectInfo; pcls->pclsid; pcls++)
  65. {
  66. if (IsEqualGUID(rclsid, *(pcls->pclsid)))
  67. {
  68. *ppv = (void*)pcls;
  69. DllAddRef();
  70. return NOERROR;
  71. }
  72. }
  73. }
  74. *ppv = NULL;
  75. return CLASS_E_CLASSNOTAVAILABLE;
  76. }
  77. // registration
  78. STDAPI DllRegisterServer(VOID)
  79. {
  80. return CallRegInstall(GLOBAL_HINSTANCE, "RegDll");
  81. }
  82. STDAPI DllUnregisterServer(VOID)
  83. {
  84. return CallRegInstall(GLOBAL_HINSTANCE, "UnRegDll");
  85. }
  86. STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)
  87. {
  88. return S_OK;
  89. }
  90. /*-----------------------------------------------------------------------------
  91. / OpenQueryWindow (runndll)
  92. / ----------------
  93. / Opens the query window, parsing the specified CLSID for the form to
  94. / select, in the same way invoking Start/Search/<bla>.
  95. /
  96. / In:
  97. / hInstanec, hPrevInstance = instance information
  98. / pCmdLine = .dsq File to be opened
  99. / nCmdShow = display flags for our window
  100. /
  101. / Out:
  102. / INT
  103. /----------------------------------------------------------------------------*/
  104. STDAPI_(int) OpenQueryWindow(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, INT nCmdShow)
  105. {
  106. HRESULT hr, hrCoInit;
  107. CLSID clsidForm;
  108. OPENQUERYWINDOW oqw = { 0 };
  109. DSQUERYINITPARAMS dqip = { 0 };
  110. ICommonQuery* pCommonQuery = NULL;
  111. USES_CONVERSION;
  112. TraceEnter(TRACE_CORE, "OpenQueryWindow");
  113. //
  114. // get the ICommonQuery object we are going to use
  115. //
  116. hr = hrCoInit = CoInitialize(NULL);
  117. FailGracefully(hr, "Failed to CoInitialize");
  118. hr = CoCreateInstance(CLSID_CommonQuery, NULL, CLSCTX_INPROC_SERVER, IID_ICommonQuery, (LPVOID*)&pCommonQuery);
  119. FailGracefully(hr, "Failed in CoCreateInstance of CLSID_CommonQuery");
  120. dqip.cbStruct = SIZEOF(dqip);
  121. dqip.dwFlags = 0;
  122. dqip.pDefaultScope = NULL;
  123. oqw.cbStruct = SIZEOF(oqw);
  124. oqw.dwFlags = 0;
  125. oqw.clsidHandler = CLSID_DsQuery;
  126. oqw.pHandlerParameters = &dqip;
  127. //
  128. // can we parse the form CLSID from the command line?
  129. //
  130. if ( GetGUIDFromString(A2T(pCmdLine), &oqw.clsidDefaultForm) )
  131. {
  132. TraceMsg("Parsed out the form CLSID, so specifying the def form/remove forms");
  133. oqw.dwFlags |= OQWF_DEFAULTFORM|OQWF_REMOVEFORMS;
  134. }
  135. hr = pCommonQuery->OpenQueryWindow(NULL, &oqw, NULL);
  136. FailGracefully(hr, "OpenQueryWindow failed");
  137. exit_gracefully:
  138. DoRelease(pCommonQuery);
  139. if ( SUCCEEDED(hrCoInit) )
  140. CoUninitialize();
  141. TraceLeaveValue(0);
  142. }
  143. /*-----------------------------------------------------------------------------
  144. / OpenSavedDsQuery
  145. / ----------------
  146. / Open a saved DS query and display the query UI with that query.
  147. /
  148. / In:
  149. / hInstanec, hPrevInstance = instance information
  150. / pCmdLine = .dsq File to be opened
  151. / nCmdShow = display flags for our window
  152. /
  153. / Out:
  154. / INT
  155. /----------------------------------------------------------------------------*/
  156. // UNICODE platforms export the W export as the prefered way of invoking the DLL
  157. // on a .QDS, we provide the ANSI version as a thunk to ensure compatibility.
  158. #ifdef UNICODE
  159. INT WINAPI OpenSavedDsQueryW(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR pCmdLineW, INT nCmdShow)
  160. {
  161. HRESULT hr;
  162. TraceEnter(TRACE_CORE, "OpenSavedDsQueryW");
  163. Trace(TEXT("pCmdLine: %s, nCmdShow %d"), pCmdLineW, nCmdShow);
  164. hr = _OpenSavedDsQuery(pCmdLineW);
  165. FailGracefully(hr, "Failed when calling _OpenSavedDsQuery");
  166. // hr = S_OK; // success
  167. exit_gracefully:
  168. TraceLeaveResult(hr);
  169. }
  170. #endif
  171. INT WINAPI OpenSavedDsQuery(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, INT nCmdShow)
  172. {
  173. HRESULT hr;
  174. USES_CONVERSION;
  175. TraceEnter(TRACE_CORE, "OpenSavedDsQuery");
  176. Trace(TEXT("pCmdLine: %s, nCmdShow %d"), A2T(pCmdLine), nCmdShow);
  177. hr = _OpenSavedDsQuery(A2T(pCmdLine));
  178. FailGracefully(hr, "Failed when calling _OpenSavedDsQuery");
  179. // hr = S_OK; // success
  180. exit_gracefully:
  181. TraceLeaveResult(hr);
  182. }
  183. HRESULT _OpenSavedDsQuery(LPTSTR pSavedQuery)
  184. {
  185. HRESULT hr, hrCoInit;
  186. ICommonQuery* pCommonQuery = NULL;
  187. IPersistQuery *ppq = NULL;
  188. OPENQUERYWINDOW oqw;
  189. DSQUERYINITPARAMS dqip;
  190. USES_CONVERSION;
  191. TraceEnter(TRACE_CORE, "OpenSavedQueryW");
  192. Trace(TEXT("Filename is: "), pSavedQuery);
  193. hr = hrCoInit = CoInitialize(NULL);
  194. FailGracefully(hr, "Failed to CoInitialize");
  195. // Construct the persistance object so that we can load objects from the given file
  196. // assuming that pSavedQuery is a valid filename.
  197. hr = CPersistQuery_CreateInstance(pSavedQuery, &ppq);
  198. FailGracefully(hr, "Failed to create persistance object");
  199. // Now lets get the ICommonQuery and get it to open itself based on the
  200. // IPersistQuery stream that are giving it.
  201. hr =CoCreateInstance(CLSID_CommonQuery, NULL, CLSCTX_INPROC_SERVER, IID_ICommonQuery, (LPVOID*)&pCommonQuery);
  202. FailGracefully(hr, "Failed in CoCreateInstance of CLSID_CommonQuery");
  203. dqip.cbStruct = SIZEOF(dqip);
  204. dqip.dwFlags = 0;
  205. dqip.pDefaultScope = NULL;
  206. oqw.cbStruct = SIZEOF(oqw);
  207. oqw.dwFlags = OQWF_LOADQUERY|OQWF_ISSUEONOPEN|OQWF_REMOVEFORMS;
  208. oqw.clsidHandler = CLSID_DsQuery;
  209. oqw.pHandlerParameters = &dqip;
  210. oqw.pPersistQuery = ppq;
  211. hr = pCommonQuery->OpenQueryWindow(NULL, &oqw, NULL);
  212. FailGracefully(hr, "OpenQueryWindow failed");
  213. exit_gracefully:
  214. // Failed so report that this was a bogus query file, however the user may have
  215. // already been prompted with nothing.
  216. if ( FAILED(hr) )
  217. {
  218. WIN32_FIND_DATA fd;
  219. HANDLE handle;
  220. Trace(TEXT("FindFirstFile on: %s"), pSavedQuery);
  221. handle = FindFirstFile(pSavedQuery, &fd);
  222. if ( INVALID_HANDLE_VALUE != handle )
  223. {
  224. Trace(TEXT("Resulting 'long' name is: "), fd.cFileName);
  225. pSavedQuery = fd.cFileName;
  226. FindClose(handle);
  227. }
  228. FormatMsgBox(NULL,
  229. GLOBAL_HINSTANCE, IDS_WINDOWTITLE, IDS_ERR_BADDSQ,
  230. MB_OK|MB_ICONERROR,
  231. pSavedQuery);
  232. }
  233. DoRelease(ppq);
  234. if ( SUCCEEDED(hrCoInit) )
  235. CoUninitialize();
  236. TraceLeaveValue(0);
  237. }
  238. // static class factory
  239. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void **ppvObj)
  240. {
  241. if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
  242. {
  243. *ppvObj = (void *)GET_ICLASSFACTORY(this);
  244. InterlockedIncrement(&g_cRef);
  245. return NOERROR;
  246. }
  247. *ppvObj = NULL;
  248. return E_NOINTERFACE;
  249. }
  250. STDMETHODIMP_(ULONG) CClassFactory::AddRef()
  251. {
  252. InterlockedIncrement(&g_cRef);
  253. return 2;
  254. }
  255. STDMETHODIMP_(ULONG) CClassFactory::Release()
  256. {
  257. InterlockedDecrement(&g_cRef);
  258. return 1;
  259. }
  260. STDMETHODIMP CClassFactory::CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv)
  261. {
  262. *ppv = NULL;
  263. if (punkOuter && !IsEqualIID(riid, IID_IUnknown))
  264. {
  265. // It is technically illegal to aggregate an object and request
  266. // any interface other than IUnknown. Enforce this.
  267. //
  268. return CLASS_E_NOAGGREGATION;
  269. }
  270. else
  271. {
  272. LPOBJECTINFO pthisobj = (LPOBJECTINFO)this;
  273. if ( punkOuter )
  274. return CLASS_E_NOAGGREGATION;
  275. IUnknown *punk;
  276. HRESULT hres = pthisobj->pfnCreateInstance(punkOuter, &punk, pthisobj);
  277. if (SUCCEEDED(hres))
  278. {
  279. hres = punk->QueryInterface(riid, ppv);
  280. punk->Release();
  281. }
  282. return hres;
  283. }
  284. }
  285. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  286. {
  287. if (fLock)
  288. InterlockedIncrement(&g_cRef);
  289. else
  290. InterlockedDecrement(&g_cRef);
  291. return S_OK;
  292. }