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.

424 lines
11 KiB

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