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.

324 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: SvcQuery.cxx
  7. //
  8. // Contents: IInternalQuery interface for cisvc
  9. //
  10. // History: 13-Sep-96 dlee Created
  11. //
  12. //--------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #pragma hdrstop
  15. #include <restrict.hxx>
  16. #include <rowset.hxx>
  17. #include <query.hxx>
  18. #include <pidmap.hxx>
  19. #include <coldesc.hxx>
  20. #include <lang.hxx>
  21. #include <rstprop.hxx>
  22. #include <proprst.hxx>
  23. #include "svcquery.hxx"
  24. //+-------------------------------------------------------------------------
  25. //
  26. // Member: CSvcQuery::QueryInterface, public
  27. //
  28. // Arguments: [ifid] -- Interface id
  29. // [ppiuk] -- Interface return pointer
  30. //
  31. // Returns: Error. No rebind from this class is supported.
  32. //
  33. // History: 13-Sep-96 dlee Created
  34. //
  35. //--------------------------------------------------------------------------
  36. STDMETHODIMP CSvcQuery::QueryInterface(
  37. REFIID ifid,
  38. void ** ppiuk )
  39. {
  40. if ( IID_IUnknown == ifid )
  41. {
  42. AddRef();
  43. *ppiuk = (void *)((IUnknown *)this);
  44. return S_OK;
  45. }
  46. else
  47. {
  48. *ppiuk = 0;
  49. return E_NOINTERFACE;
  50. }
  51. } //QueryInterface
  52. //+-------------------------------------------------------------------------
  53. //
  54. // Member: CSvcQuery::AddRef, public
  55. //
  56. // Synopsis: Reference the virtual table.
  57. //
  58. // History: 13-Sep-96 dlee Created
  59. //
  60. //--------------------------------------------------------------------------
  61. STDMETHODIMP_(ULONG) CSvcQuery::AddRef()
  62. {
  63. return InterlockedIncrement( (long *) &_ref );
  64. } //AddRef
  65. //+-------------------------------------------------------------------------
  66. //
  67. // Member: CSvcQuery::Release, public
  68. //
  69. // Synopsis: De-Reference the virtual table.
  70. //
  71. // Effects: If the ref count goes to 0 then the table is deleted.
  72. //
  73. // History: 13-Sep-96 dlee Created
  74. //
  75. //--------------------------------------------------------------------------
  76. STDMETHODIMP_(ULONG) CSvcQuery::Release()
  77. {
  78. long l = InterlockedDecrement( (long *) &_ref );
  79. if ( l <= 0 )
  80. {
  81. // delete self
  82. vqDebugOut(( DEB_ITRACE,
  83. "Svc IInternalQuery unreferenced. Deleting.\n" ));
  84. delete this;
  85. return 0;
  86. }
  87. return l;
  88. } //Release
  89. //+-------------------------------------------------------------------------
  90. //
  91. // Class: CCursorArray
  92. //
  93. // Synopsis: Smart container of query cursors
  94. //
  95. // History: 16-Feb-97 dlee Created
  96. //
  97. //--------------------------------------------------------------------------
  98. class CCursorArray
  99. {
  100. public:
  101. CCursorArray( ULONG * pCursors,
  102. ULONG cCursors,
  103. CSvcQueryProxy & Query ) :
  104. _pCursors( pCursors ),
  105. _cCursors( cCursors ),
  106. _Query( Query )
  107. {
  108. }
  109. void Acquire( ULONG iElement )
  110. {
  111. _pCursors[ iElement ] = 0;
  112. }
  113. ~CCursorArray()
  114. {
  115. // FreeCursor can fail if the pipe is stale, in which
  116. // case don't bother with freeing the rest of the cursors.
  117. TRY
  118. {
  119. for ( ULONG x = 0; x < _cCursors; x++ )
  120. {
  121. if ( 0 != _pCursors[ x ] )
  122. _Query.FreeCursor( _pCursors[ x ] );
  123. }
  124. }
  125. CATCH( CException, e )
  126. {
  127. }
  128. END_CATCH
  129. }
  130. private:
  131. ULONG * _pCursors;
  132. ULONG _cCursors;
  133. CSvcQueryProxy & _Query;
  134. };
  135. //+-------------------------------------------------------------------------
  136. //
  137. // Member: CSvcQuery::Execute, public
  138. //
  139. // Synopsis: Executes a query. Helper for ICommand::Execute.
  140. //
  141. // Arguments: [pUnkOuter] -- Outer unknown
  142. // [pRestriction] -- Query restriction
  143. // [pidmap] -- pid mapper for output, sort, category columns
  144. // [rColumns] -- Output columns in IRowset
  145. // [rSort] -- Initial sort
  146. // [xProps] -- Rowset properties (query flags)
  147. // [rCateg] -- Categorization specification
  148. // [cRowsets] -- # of rowsets
  149. // [ppUnknowns] -- IUnknowns returned here
  150. // [aAccessors] -- Bag of accessors which rowsets need to inherit
  151. //
  152. // Returns: Throws on error
  153. //
  154. // History: 26 Nov 1995 AlanW Created
  155. // 13-Sep-96 dlee Make it support cisvc
  156. //
  157. //--------------------------------------------------------------------------
  158. void CSvcQuery::Execute( IUnknown * pUnkOuter,
  159. RESTRICTION * pRestriction,
  160. CPidMapperWithNames & pidmap,
  161. CColumnSet & rColumns,
  162. CSortSet & rSort,
  163. XPtr<CMRowsetProps> & xProps,
  164. CCategorizationSet & rCateg,
  165. ULONG cRowsets,
  166. IUnknown ** ppUnknowns,
  167. CAccessorBag & aAccessors,
  168. IUnknown * pUnkCreator )
  169. {
  170. if (0 == ppUnknowns)
  171. THROW(CException( E_INVALIDARG));
  172. if ( cRowsets != 1 + (rCateg.Count() ? rCateg.Count() : 0) )
  173. THROW( CException( E_INVALIDARG ));
  174. if (_QueryUnknown.IsQueryActive())
  175. {
  176. vqDebugOut(( DEB_ERROR,
  177. "CSvcQuery: Query already active.\n" ));
  178. // NTRAID#DB-NTBUG9-84330-2000/07/31-dlee OLE-DB spec variance in Indexing Service when reexecuting queries
  179. // spec variance: only if query changed
  180. THROW( CException( DB_E_OBJECTOPEN ));
  181. }
  182. // Construct table
  183. *ppUnknowns = 0; // in case of error or exception
  184. XArray<ULONG> aCursors( cRowsets );
  185. // Construct a CRowsetProperties
  186. CRowsetProperties Prop;
  187. Prop.SetDefaults( xProps->GetPropertyFlags(),
  188. xProps->GetMaxOpenRows(),
  189. xProps->GetMemoryUsage(),
  190. xProps->GetMaxResults(),
  191. xProps->GetCommandTimeout(),
  192. xProps->GetFirstRows() );
  193. XInterface<CSvcQueryProxy> xQuery(new
  194. CSvcQueryProxy( _client,
  195. rColumns,
  196. (CRestriction&) (*pRestriction),
  197. rSort.Count() ? &rSort : 0,
  198. rCateg.Count() ? &rCateg : 0,
  199. Prop,
  200. pidmap,
  201. cRowsets,
  202. aCursors.GetPointer()
  203. ));
  204. // Make rowsets for each level in the hierarchy (usually 1).
  205. // Rowset 0 is the top of the hierarchy.
  206. CCursorArray cursorArray( aCursors.GetPointer(),
  207. cRowsets,
  208. xQuery.GetReference() );
  209. _QueryUnknown.ReInit();
  210. CRowsetArray apRowsets( cRowsets );
  211. XArray<IUnknown *> xapUnknown( cRowsets );
  212. CMRowsetProps & OrigProps = xProps.GetReference();
  213. for ( unsigned r = 0; r < cRowsets; r++ )
  214. {
  215. // First rowset is not chaptered, even if others are.
  216. XPtr<CMRowsetProps> xTmp;
  217. if ( 0 != r )
  218. {
  219. xTmp.Set( new CMRowsetProps( OrigProps ) );
  220. xTmp->SetChaptered( TRUE );
  221. }
  222. if ( 1 != cRowsets && 0 == r )
  223. xProps->SetChaptered( FALSE );
  224. apRowsets[r] = new CRowset( pUnkOuter,
  225. &xapUnknown[r],
  226. (r == (cRowsets - 1)) ?
  227. rColumns :
  228. rCateg.Get(r)->GetColumnSet(),
  229. pidmap,
  230. xQuery.GetReference(),
  231. (IUnknown &) _QueryUnknown,
  232. 0 != r,
  233. ( 0 == r ) ? xProps : xTmp,
  234. aCursors[r],
  235. aAccessors,
  236. pUnkCreator );
  237. // the cursor is acquired
  238. cursorArray.Acquire( r );
  239. }
  240. for (r = 0; r < cRowsets; r++)
  241. {
  242. if (r < cRowsets-1)
  243. apRowsets[r]->SetRelatedRowset( apRowsets[r+1] );
  244. ppUnknowns[r] = xapUnknown[r];
  245. }
  246. // xQuery goes out of scope, which does a Release() on it.
  247. // Each rowset above has done an AddRef() on it and they own it.
  248. // ReInit can't fail
  249. _QueryUnknown.ReInit( cRowsets, apRowsets.Acquire() );
  250. } //Execute
  251. //+-------------------------------------------------------------------------
  252. //
  253. // Member: CSvcQuery::CSvcQuery, public
  254. //
  255. // Synopsis: saves the query scope, machine, and catalog
  256. //
  257. // Arguments: [cScopes] - # of entries in the scope arrays
  258. // [aDepths] - array of scope depths
  259. // [aScopes] - array of paths to roots of scopes
  260. // [pwcCatalog] - catalog override name or path
  261. // [pwcMachine] - Machine name for catalog
  262. //
  263. // History: 13-Sep-96 dlee Updated from FAT for svc
  264. //
  265. //--------------------------------------------------------------------------
  266. CSvcQuery::CSvcQuery(
  267. WCHAR const * pwcMachine,
  268. IDBProperties * pDbProperties ) :
  269. #pragma warning(disable : 4355) // 'this' in a constructor
  270. _QueryUnknown( * ((IUnknown *) this) ),
  271. #pragma warning(default : 4355) // 'this' in a constructor
  272. PIInternalQuery( 0 ),
  273. _client( pwcMachine, pDbProperties )
  274. {
  275. AddRef();
  276. } //CSvcQuery