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.

552 lines
17 KiB

  1. //////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMIOLE DB Provider
  4. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // IDBProperties and IDBInfo interface implementations
  7. //
  8. //////////////////////////////////////////////////////////////////////////////////////////////////
  9. #include "headers.h"
  10. WCHAR g_szKeyWords[] = L"CLUSTERED,COMMITTED,COMPUTE,CONFIRM,CONTROLROW,DATABASE,DENY,DISK,DISTRIBUTED,DUMMY,DUMP,"
  11. L"ERRLVL,ERROREXIT,EXIT,FILLFACTOR,FLOPPY,HOLDLOCK,IDENTITY_INSERT,IDENTITYCOL,IF,INDEX,KILL,"
  12. L"LINENO,LOAD,LOG,NOCHECK,NONCLUSTERED,OFF,OFFSETS,ONCE,OVER,PERCENT,PERM,PERMANENT,PIPE,PLAN,"
  13. L"PRINT,PROC,PROCESSEXIT,QUALIFIER,RECONFIGURE,REPEATABLE,REPLICATION,RETURN,ROWCOUNT,RULE,SAVE,"
  14. L"SETUSER,SHUTDOWN,STATISTICS,TAPE,TEMP,TEXTSIZE,TOP,TRAN,TRUNCATE,TSEQUAL,UNCOMMITTED,"
  15. L"UPDATETEXT,WHILE";
  16. #define KEYWORD_MAXSIZE 1024
  17. #define NUMBER_OF_SUPPORTED_LITERALS 7
  18. DBLITERAL g_SupportedLiterals[] = { DBLITERAL_CATALOG_NAME,
  19. DBLITERAL_CHAR_LITERAL,
  20. DBLITERAL_COLUMN_NAME,
  21. DBLITERAL_SCHEMA_NAME,
  22. DBLITERAL_SCHEMA_SEPARATOR,
  23. DBLITERAL_TABLE_NAME,
  24. DBLITERAL_TEXT_COMMAND};
  25. DBLITERALINFO g_SupportedInfo[] = {
  26. { L"",
  27. L"!\"%&()*+-,/;:<=>?@[\\]^{|}~" ,
  28. L"0123456789!\"%%&()*+-,/;:<=>?@[\\]^{|}~_ ",
  29. DBLITERAL_CATALOG_NAME,
  30. TRUE,
  31. ~0
  32. } ,
  33. { L"",
  34. L"" ,
  35. L"",
  36. DBLITERAL_CHAR_LITERAL,
  37. TRUE,
  38. 0
  39. } ,
  40. { L"",
  41. L"!\"%&()*+-,/;:<=>?@[\\]^{|}~" ,
  42. L"0123456789!\"%%&()*+-,/;:<=>?@[\\]^{|}~_ ",
  43. DBLITERAL_COLUMN_NAME,
  44. TRUE,
  45. ~0
  46. } ,
  47. { L"",
  48. L"!\"%&()*+-,/;:<=>?@[\\]^{|}~" ,
  49. L"0123456789!\"%%&()*+-,/;:<=>?@[\\]^{|}~_ ",
  50. DBLITERAL_SCHEMA_NAME,
  51. TRUE,
  52. ~0
  53. } ,
  54. { L".",
  55. L"",
  56. L"",
  57. DBLITERAL_SCHEMA_SEPARATOR,
  58. TRUE,
  59. 1
  60. } ,
  61. { L"",
  62. L"!\"%&()*+-,/;:<=>?@[\\]^{|}~" ,
  63. L"0123456789!\"%%&()*+-,/;:<=>?@[\\]^{|}~_ ",
  64. DBLITERAL_TABLE_NAME,
  65. TRUE,
  66. ~0
  67. } ,
  68. { L"",
  69. L"",
  70. L"",
  71. DBLITERAL_TEXT_COMMAND,
  72. TRUE,
  73. 0
  74. }
  75. };
  76. //////////////////////////////////////////////////////////////////////////////////////////////////
  77. //
  78. // IDBInfo specific interface methods
  79. //
  80. // Returns information about keywords used in text commands
  81. //
  82. // HRESULT
  83. // S_OK Keywords successfully returned, NULL because no keywords
  84. // E_INVALIDARG ppwszKeywords was NULL
  85. // E_UNEXPECTED Can not be called unless initialized
  86. //
  87. //////////////////////////////////////////////////////////////////////////////////////////////////
  88. STDMETHODIMP CImpIDBInfo::GetKeywords( LPWSTR* ppwszKeywords )
  89. {
  90. HRESULT hr = S_OK;
  91. CSetStructuredExceptionHandler seh;
  92. WCHAR wcsKeyWords[KEYWORD_MAXSIZE];
  93. wcscpy(wcsKeyWords,L"");
  94. TRY_BLOCK;
  95. WMIOledb_LoadStringW(IDS_DBKEYWORDS,wcsKeyWords,KEYWORD_MAXSIZE * sizeof(WCHAR));
  96. //=========================
  97. // Serialize the object
  98. //=========================
  99. CAutoBlock cab(DATASOURCE->GetCriticalSection());
  100. g_pCError->ClearErrorInfo();
  101. //=================================================================
  102. // Initialize
  103. //=================================================================
  104. if (ppwszKeywords){
  105. *ppwszKeywords = NULL;
  106. }
  107. //=================================================================
  108. // check params
  109. //=================================================================
  110. if (NULL == ppwszKeywords){
  111. hr = E_INVALIDARG;
  112. }
  113. //=================================================================
  114. // check if we are initialized
  115. //=================================================================
  116. else if (!m_pObj->m_fDSOInitialized){
  117. hr = E_UNEXPECTED;
  118. }
  119. else
  120. {
  121. try
  122. {
  123. *ppwszKeywords = (LPWSTR)g_pIMalloc->Alloc((wcslen(wcsKeyWords) + 1) * sizeof(WCHAR));
  124. }
  125. catch(...)
  126. {
  127. if(*ppwszKeywords)
  128. {
  129. g_pIMalloc->Free(*ppwszKeywords);
  130. }
  131. throw;
  132. }
  133. if(*ppwszKeywords)
  134. {
  135. wcscpy(*ppwszKeywords, wcsKeyWords);
  136. }
  137. else
  138. {
  139. hr = E_OUTOFMEMORY;
  140. }
  141. }
  142. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IDBInfo);
  143. CATCH_BLOCK_HRESULT(hr,L"IDBInfo::GetKeywords");
  144. return hr;
  145. }
  146. //////////////////////////////////////////////////////////////////////////////////////////////////
  147. //
  148. // Returns information about literals used in text command
  149. //
  150. // HRESULT
  151. // S_OK cLiterals was 0
  152. // E_INVALIDARG cLiterals not equal to 0 and rgLiterals was NULL or pcLiteralInfo,
  153. // prgLiteralInfo, or ppCharBuffer was NULL
  154. // E_UNEXPECTED Can not be called unless initialized
  155. // DB_E_ERRORSOCCURRED None of the requested literals are supported
  156. //
  157. //////////////////////////////////////////////////////////////////////////////////////////////////
  158. STDMETHODIMP CImpIDBInfo::GetLiteralInfo (
  159. ULONG cLiterals, // IN Number of literals being asked about
  160. const DBLITERAL rgLiterals[], // IN Array of literals about which to return information
  161. ULONG* pcLiteralInfo, // OUT Number of literals for which info is returned
  162. DBLITERALINFO** prgLiteralInfo, // OUT Array of info structures
  163. WCHAR** ppCharBuffer // OUT Buffer for characters
  164. )
  165. {
  166. HRESULT hr = S_OK;
  167. CSetStructuredExceptionHandler seh;
  168. TRY_BLOCK;
  169. //==================================================================
  170. // Initialize
  171. //==================================================================
  172. if( pcLiteralInfo ){
  173. *pcLiteralInfo = 0;
  174. }
  175. if( prgLiteralInfo ){
  176. *prgLiteralInfo = NULL;
  177. }
  178. if( ppCharBuffer ){
  179. *ppCharBuffer = NULL;
  180. }
  181. // Serialize the object
  182. CAutoBlock cab(DATASOURCE->GetCriticalSection());
  183. g_pCError->ClearErrorInfo();
  184. //==================================================================
  185. // check params
  186. //==================================================================
  187. if ((cLiterals != 0) && (rgLiterals == NULL))
  188. {
  189. hr = E_INVALIDARG;
  190. }
  191. else if (!pcLiteralInfo || !prgLiteralInfo || !ppCharBuffer)
  192. {
  193. hr = E_INVALIDARG;
  194. }
  195. else if (!m_pObj->m_fDSOInitialized)
  196. {
  197. //==============================================================
  198. // check if we are initialized
  199. //==============================================================
  200. hr = E_UNEXPECTED;
  201. }
  202. else
  203. {
  204. ULONG cLiteralsToFetch = cLiterals == 0 ? NUMBER_OF_SUPPORTED_LITERALS : cLiterals;
  205. //==========================================================
  206. // Allocate memory for return information
  207. // - DBLITERALINFO array
  208. //==========================================================
  209. try
  210. {
  211. *prgLiteralInfo = (DBLITERALINFO*)g_pIMalloc->Alloc(cLiteralsToFetch * sizeof(DBLITERALINFO));
  212. *ppCharBuffer = (WCHAR *)g_pIMalloc->Alloc(GetStringBufferSize(cLiterals,rgLiterals));
  213. }
  214. catch(...)
  215. {
  216. if(*prgLiteralInfo)
  217. {
  218. g_pIMalloc->Free(*prgLiteralInfo);
  219. *prgLiteralInfo = NULL;
  220. }
  221. if(*ppCharBuffer)
  222. {
  223. g_pIMalloc->Free(*ppCharBuffer);
  224. *ppCharBuffer = NULL;
  225. }
  226. throw;
  227. }
  228. if (!(*prgLiteralInfo) || !(*ppCharBuffer))
  229. {
  230. if(*prgLiteralInfo)
  231. {
  232. g_pIMalloc->Free(*prgLiteralInfo);
  233. *prgLiteralInfo = NULL;
  234. }
  235. if(*ppCharBuffer)
  236. {
  237. g_pIMalloc->Free(*ppCharBuffer);
  238. *ppCharBuffer = NULL;
  239. }
  240. hr= E_OUTOFMEMORY;
  241. }
  242. else
  243. {
  244. LONG lLiteralIndex = 0;
  245. WCHAR *pTemp = *ppCharBuffer;
  246. memset(*prgLiteralInfo , 0 , sizeof(DBLITERALINFO) * cLiteralsToFetch);
  247. memset(*ppCharBuffer , 0 , GetStringBufferSize(cLiterals,rgLiterals));
  248. for(ULONG lIndex = 0; lIndex < cLiteralsToFetch ; lIndex++)
  249. {
  250. lLiteralIndex = -1;
  251. lLiteralIndex = cLiterals == 0 ? lIndex : GetLiteralIndex(rgLiterals[lIndex]);
  252. if(lLiteralIndex >= 0)
  253. {
  254. if(g_SupportedInfo[lLiteralIndex].pwszLiteralValue != NULL)
  255. {
  256. // copy the litervalue
  257. wcscpy(pTemp,g_SupportedInfo[lLiteralIndex].pwszLiteralValue);
  258. (*prgLiteralInfo)[lIndex].pwszLiteralValue = pTemp;
  259. (*prgLiteralInfo)[lIndex].cchMaxLen = wcslen(pTemp);
  260. pTemp += (wcslen(pTemp) + 1);
  261. }
  262. else
  263. {
  264. (*prgLiteralInfo)[lIndex].pwszLiteralValue = NULL;
  265. }
  266. if(g_SupportedInfo[lLiteralIndex].pwszInvalidChars != NULL)
  267. {
  268. // copy the litervalue
  269. wcscpy(pTemp,g_SupportedInfo[lLiteralIndex].pwszInvalidChars);
  270. (*prgLiteralInfo)[lIndex].pwszInvalidChars = pTemp;
  271. if(wcslen(pTemp) > (*prgLiteralInfo)[lIndex].cchMaxLen)
  272. {
  273. (*prgLiteralInfo)[lIndex].cchMaxLen = wcslen(pTemp);
  274. }
  275. pTemp += (wcslen(pTemp) + 1);
  276. }
  277. else
  278. {
  279. (*prgLiteralInfo)[lIndex].pwszInvalidChars = NULL;
  280. }
  281. if(g_SupportedInfo[lLiteralIndex].pwszInvalidStartingChars != NULL)
  282. {
  283. // copy the litervalue
  284. wcscpy(pTemp,g_SupportedInfo[lLiteralIndex].pwszInvalidStartingChars);
  285. (*prgLiteralInfo)[lIndex].pwszInvalidStartingChars = pTemp;
  286. if(wcslen(pTemp) > (*prgLiteralInfo)[lIndex].cchMaxLen)
  287. {
  288. (*prgLiteralInfo)[lIndex].cchMaxLen = wcslen(pTemp);
  289. }
  290. pTemp += (wcslen(pTemp) + 1);
  291. }
  292. else
  293. {
  294. (*prgLiteralInfo)[lIndex].pwszInvalidStartingChars = NULL;
  295. }
  296. (*prgLiteralInfo)[lIndex].lt = g_SupportedInfo[lLiteralIndex].lt;
  297. (*prgLiteralInfo)[lIndex].fSupported = TRUE;
  298. } // if valid literal index
  299. } // for loop
  300. } // after succesfull memory allocation
  301. if(SUCCEEDED(hr))
  302. {
  303. *pcLiteralInfo = cLiteralsToFetch;
  304. }
  305. } // initial parameter checking
  306. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IDBInfo);
  307. CATCH_BLOCK_HRESULT(hr,L"IDBInfo::GetLiteralInfo");
  308. return hr;
  309. }
  310. ///////////////////////////////////////////////////////////////////////////////////
  311. // Get index of the given literal in the global array
  312. ///////////////////////////////////////////////////////////////////////////////////
  313. LONG CImpIDBInfo::GetLiteralIndex(DBLITERAL rgLiterals)
  314. {
  315. LONG lRet = -1;
  316. for( int i = 0 ; i < NUMBER_OF_SUPPORTED_LITERALS ; i++)
  317. {
  318. if(g_SupportedLiterals[i] == rgLiterals)
  319. {
  320. lRet = i;
  321. break;
  322. }
  323. }
  324. return lRet;
  325. }
  326. ///////////////////////////////////////////////////////////////////////////////////
  327. // Get length of buffer to be allocated for strings
  328. ///////////////////////////////////////////////////////////////////////////////////
  329. LONG CImpIDBInfo::GetStringBufferSize(ULONG cLiterals, // IN Number of literals being asked about
  330. const DBLITERAL rgLiterals[])
  331. {
  332. LONG lBuffSize = 0;
  333. LONG lLiteralIndex = 0;
  334. LONG cLiteralsToFetch = cLiterals == 0 ? NUMBER_OF_SUPPORTED_LITERALS : cLiterals;
  335. for(LONG lIndex =0 ; lIndex < cLiteralsToFetch ; lIndex++)
  336. {
  337. lLiteralIndex = -1;
  338. lLiteralIndex = cLiterals == 0 ? lIndex : GetLiteralIndex(rgLiterals[lIndex]);
  339. if(lLiteralIndex >= 0)
  340. {
  341. lBuffSize += wcslen(g_SupportedInfo[lLiteralIndex].pwszLiteralValue) + 1;
  342. lBuffSize += wcslen(g_SupportedInfo[lLiteralIndex].pwszInvalidChars) + 1;
  343. lBuffSize += wcslen(g_SupportedInfo[lLiteralIndex].pwszInvalidStartingChars) + 1;
  344. }
  345. }
  346. lBuffSize *= sizeof(WCHAR);
  347. return lBuffSize;
  348. }
  349. //////////////////////////////////////////////////////////////////////////////////////////////////
  350. //
  351. // Returns information about rowset and data source properties supported by the provider
  352. //
  353. // HRESULT
  354. // S_OK The method succeeded
  355. // E_INVALIDARG pcPropertyInfo or prgPropertyInfo was NULL
  356. // E_OUTOFMEMORY Out of memory
  357. //
  358. //////////////////////////////////////////////////////////////////////////////////////////////////
  359. STDMETHODIMP CImpIDBProperties::GetPropertyInfo (
  360. ULONG cPropertySets, // IN Number of properties being asked about
  361. const DBPROPIDSET rgPropertySets[], // IN Array of cPropertySets properties about which to return information
  362. ULONG* pcPropertyInfoSets, // OUT Number of properties for which information is being returned
  363. DBPROPINFOSET** prgPropertyInfoSets,// OUT Buffer containing default values returned
  364. WCHAR** ppDescBuffer // OUT Buffer containing property descriptions
  365. )
  366. {
  367. assert( m_pObj );
  368. assert( m_pObj->m_pUtilProp );
  369. HRESULT hr = S_OK;
  370. CSetStructuredExceptionHandler seh;
  371. TRY_BLOCK;
  372. // Serialize the object
  373. CAutoBlock cab(DATASOURCE->GetCriticalSection());
  374. g_pCError->ClearErrorInfo();
  375. //=====================================================================================
  376. // just pass this call on to the utility object that manages our properties
  377. //=====================================================================================
  378. hr = m_pObj->m_pUtilProp->GetPropertyInfo(
  379. m_pObj->m_fDSOInitialized,
  380. cPropertySets,
  381. rgPropertySets,
  382. pcPropertyInfoSets,
  383. prgPropertyInfoSets,
  384. ppDescBuffer);
  385. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IDBProperties);
  386. CATCH_BLOCK_HRESULT(hr,L"IDBProperties::GetPropertyInfo");
  387. return hr;
  388. }
  389. //////////////////////////////////////////////////////////////////////////////////////////////////
  390. //
  391. // Returns current settings of all properties in the FLAGS_DATASRCINF property group
  392. //
  393. // HRESULT
  394. // S_OK The method succeeded
  395. // E_INVALIDARG pcProperties or prgPropertyInfo was NULL
  396. // E_OUTOFMEMORY Out of memory
  397. //
  398. //////////////////////////////////////////////////////////////////////////////////////////////////
  399. STDMETHODIMP CImpIDBProperties::GetProperties (
  400. ULONG cPropertySets, // IN count of restiction guids
  401. const DBPROPIDSET rgPropertySets[], // IN restriction guids
  402. ULONG* pcProperties, // OUT count of properties returned
  403. DBPROPSET** prgProperties // OUT property information returned
  404. )
  405. {
  406. DWORD dwBitMask = PROPSET_DSO;
  407. assert( m_pObj );
  408. assert( m_pObj->m_pUtilProp );
  409. HRESULT hr = S_OK;
  410. CSetStructuredExceptionHandler seh;
  411. TRY_BLOCK;
  412. // Serialize the object
  413. CAutoBlock cab(DATASOURCE->GetCriticalSection());
  414. g_pCError->ClearErrorInfo();
  415. //=================================================================================
  416. // set BitMask
  417. //=================================================================================
  418. if ( m_pObj->m_fDSOInitialized ){
  419. dwBitMask |= PROPSET_INIT;
  420. }
  421. //=================================================================================
  422. // Check Arguments
  423. //=================================================================================
  424. hr = m_pObj->m_pUtilProp->GetPropertiesArgChk(dwBitMask, cPropertySets, rgPropertySets, pcProperties, prgProperties,m_pObj->m_fDSOInitialized);
  425. if ( !FAILED(hr) ){
  426. //=============================================================================
  427. // Just pass this call on to the utility object that manages our properties
  428. //=============================================================================
  429. hr = m_pObj->m_pUtilProp->GetProperties(dwBitMask,cPropertySets, rgPropertySets,pcProperties, prgProperties );
  430. }
  431. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IDBProperties);
  432. CATCH_BLOCK_HRESULT(hr,L"IDBProperties::GetProperties");
  433. return hr;
  434. }
  435. //////////////////////////////////////////////////////////////////////////////////////////////////
  436. //
  437. // Set properties in the FLAGS_DATASRCINF property group
  438. //
  439. // HRESULT
  440. // S_OK | The method succeeded
  441. // E_INVALIDARG | cProperties was not equal to 0 and rgProperties was NULL
  442. //
  443. //////////////////////////////////////////////////////////////////////////////////////////////////
  444. STDMETHODIMP CImpIDBProperties::SetProperties ( ULONG cProperties,DBPROPSET rgProperties[] )
  445. {
  446. HRESULT hr = E_FAIL;
  447. DWORD dwBitMask = PROPSET_DSO;
  448. assert( m_pObj );
  449. assert( m_pObj->m_pUtilProp );
  450. CSetStructuredExceptionHandler seh;
  451. TRY_BLOCK;
  452. // Serialize the object
  453. CAutoBlock cab(DATASOURCE->GetCriticalSection());
  454. g_pCError->ClearErrorInfo();
  455. //===================================================================================
  456. // Quick return if the Count of Properties is 0
  457. //===================================================================================
  458. if( cProperties == 0 ){
  459. hr = S_OK ;
  460. }
  461. //===================================================================================
  462. // Check Arguments for use by properties
  463. //===================================================================================
  464. hr = m_pObj->m_pUtilProp->SetPropertiesArgChk(cProperties, rgProperties,m_pObj->m_fDSOInitialized);
  465. if( !FAILED(hr) ){
  466. //===================================================================================
  467. // set BitMask
  468. //===================================================================================
  469. if ( m_pObj->m_fDSOInitialized )
  470. dwBitMask |= PROPSET_INIT;
  471. //===================================================================================
  472. // just pass this call on to the utility object that manages our properties
  473. //===================================================================================
  474. hr = m_pObj->m_pUtilProp->SetProperties(dwBitMask,cProperties, rgProperties);
  475. }
  476. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IDBProperties);
  477. CATCH_BLOCK_HRESULT(hr,L"IDBProperties::SetProperties");
  478. return hr;
  479. }