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.

629 lines
15 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMIOLE DB Provider
  4. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // UTIL.CPP - implementation of some utility functions
  7. //
  8. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. #define _WIN32_DCOM
  10. #include "headers.h"
  11. #define wbem_towlower(C) \
  12. (((C) >= 0 && (C) <= 127)? \
  13. (((C) >= 'A' && (C) <= 'Z')? \
  14. ((C) + ('a' - 'A')): \
  15. (C) \
  16. ): \
  17. towlower(C) \
  18. )
  19. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  20. void AllocateAndConvertAnsiToUnicode(char * pstr, WCHAR *& pszW)
  21. {
  22. pszW = NULL;
  23. int nSize = strlen(pstr);
  24. if (nSize != 0 ){
  25. // Determine number of wide characters to be allocated for the
  26. // Unicode string.
  27. nSize++;
  28. try{
  29. pszW = new WCHAR[nSize * 2];
  30. if (NULL != pszW){
  31. // Covert to Unicode.
  32. MultiByteToWideChar(CP_ACP, 0, pstr, nSize,pszW,nSize);
  33. }
  34. }
  35. catch(...)
  36. {
  37. SAFE_DELETE_ARRAY(pszW);
  38. throw;
  39. }
  40. }
  41. }
  42. ////////////////////////////////////////////////////////////////////
  43. BOOL UnicodeToAnsi(WCHAR * pszW, char *& pAnsi)
  44. {
  45. ULONG cbAnsi, cCharacters;
  46. BOOL fRc = FALSE;
  47. pAnsi = NULL;
  48. if (pszW != NULL){
  49. cCharacters = wcslen(pszW)+1;
  50. // Determine number of bytes to be allocated for ANSI string. An
  51. // ANSI string can have at most 2 bytes per character (for Double
  52. // Byte Character Strings.)
  53. cbAnsi = cCharacters*2;
  54. try{
  55. pAnsi = new char[cbAnsi];
  56. if (NULL != pAnsi){
  57. // Convert to ANSI.
  58. if (0 != WideCharToMultiByte(CP_ACP, 0, pszW, cCharacters, pAnsi, cbAnsi, NULL, NULL)){
  59. fRc = TRUE;
  60. }
  61. }
  62. }
  63. catch(...)
  64. {
  65. SAFE_DELETE_ARRAY(pAnsi);
  66. throw;
  67. }
  68. }
  69. return fRc;
  70. }
  71. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  72. void TranslateAndLog( WCHAR * wcsMsg )
  73. {
  74. char * pStr = NULL;
  75. UnicodeToAnsi(wcsMsg,pStr);
  76. if( pStr ){
  77. ERRORTRACE((THISPROVIDER,"**************************************************************************\n"));
  78. ERRORTRACE((THISPROVIDER,pStr));
  79. ERRORTRACE((THISPROVIDER,"\n"));
  80. SAFE_DELETE_ARRAY(pStr);
  81. }
  82. }
  83. void FormatAndLogMessage( LPCWSTR pszFormatString,... )
  84. {
  85. char * pStr = NULL;
  86. va_list argList;
  87. va_start(argList,pszFormatString);
  88. CHString sMsg;
  89. sMsg.FormatV(pszFormatString,argList);
  90. va_end(argList);
  91. UnicodeToAnsi(sMsg.GetBuffer(sMsg.GetLength()),pStr);
  92. if( pStr ){
  93. ERRORTRACE((THISPROVIDER,"**************************************************************************\n"));
  94. ERRORTRACE((THISPROVIDER,pStr));
  95. ERRORTRACE((THISPROVIDER,"\n"));
  96. SAFE_DELETE_ARRAY(pStr);
  97. }
  98. }
  99. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  100. void LogMessage( char * szMsg )
  101. {
  102. if( szMsg ){
  103. ERRORTRACE((THISPROVIDER,"**************************************************************************\n"));
  104. ERRORTRACE((THISPROVIDER,szMsg));
  105. ERRORTRACE((THISPROVIDER,"\n"));
  106. }
  107. }
  108. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  109. void LogMessage( char * szMsg , HRESULT hr)
  110. {
  111. if( szMsg ){
  112. ERRORTRACE((THISPROVIDER,"**************************************************************************\n"));
  113. ERRORTRACE((THISPROVIDER,szMsg));
  114. ERRORTRACE((THISPROVIDER,"\n"));
  115. }
  116. }
  117. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  118. void LogMessage( WCHAR * szMsg )
  119. {
  120. char *pstrMsg = NULL;
  121. UnicodeToAnsi(szMsg,pstrMsg);
  122. if( szMsg ){
  123. ERRORTRACE((THISPROVIDER,"**************************************************************************\n"));
  124. ERRORTRACE((THISPROVIDER,pstrMsg));
  125. ERRORTRACE((THISPROVIDER,"\n"));
  126. }
  127. SAFE_DELETE_ARRAY(pstrMsg);
  128. }
  129. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  130. void LogMessage( WCHAR * szMsg , HRESULT hr)
  131. {
  132. char *pstrMsg = NULL;
  133. UnicodeToAnsi(szMsg,pstrMsg);
  134. if( szMsg ){
  135. ERRORTRACE((THISPROVIDER,"**************************************************************************\n"));
  136. ERRORTRACE((THISPROVIDER,pstrMsg));
  137. ERRORTRACE((THISPROVIDER,"\n"));
  138. }
  139. SAFE_DELETE_ARRAY(pstrMsg);
  140. }
  141. //-----------------------------------------------------------------------------
  142. // OnUnicodeSystem
  143. //
  144. // @func Determine if the OS that we are on, actually supports the unicode verion
  145. // of the win32 API. If YES, then g_bIsAnsiOS == FALSE.
  146. //
  147. // @rdesc True of False
  148. //-----------------------------------------------------------------------------------
  149. BOOL OnUnicodeSystem()
  150. {
  151. BOOL fUnicode = TRUE;
  152. HKEY hkJunk = HKEY_CURRENT_USER;
  153. // Check to see if we have win95's broken registry, thus
  154. // do not have Unicode support in the OS
  155. if ((RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  156. L"SOFTWARE",
  157. 0,
  158. KEY_READ,
  159. &hkJunk) == ERROR_SUCCESS)
  160. && hkJunk == HKEY_CURRENT_USER)
  161. {
  162. // Try the ANSI version
  163. if ((RegOpenKeyExA(HKEY_LOCAL_MACHINE,
  164. "SOFTWARE",
  165. 0,
  166. KEY_READ,
  167. &hkJunk) == ERROR_SUCCESS)
  168. && (hkJunk != HKEY_CURRENT_USER))
  169. {
  170. fUnicode = FALSE;
  171. }
  172. }
  173. if (hkJunk != HKEY_CURRENT_USER)
  174. RegCloseKey(hkJunk);
  175. return fUnicode;
  176. }
  177. inline int wbem_towupper(wint_t c)
  178. {
  179. if(c >= 0 && c <= 127)
  180. {
  181. if(c >= 'a' && c <= 'z')
  182. return c + ('A' - 'a');
  183. else
  184. return c;
  185. }
  186. else return towupper(c);
  187. }
  188. inline int wbem_tolower(int c)
  189. {
  190. if(c >= 0 && c <= 127)
  191. {
  192. if(c >= 'A' && c <= 'Z')
  193. return c + ('a' - 'A');
  194. else
  195. return c;
  196. }
  197. else return tolower(c);
  198. }
  199. inline int wbem_toupper(int c)
  200. {
  201. if(c >= 0 && c <= 127)
  202. {
  203. if(c >= 'a' && c <= 'z')
  204. return c + ('A' - 'a');
  205. else
  206. return c;
  207. }
  208. else return toupper(c);
  209. }
  210. int wbem_wcsicmp(const wchar_t* wsz1, const wchar_t* wsz2)
  211. {
  212. int nRet = 0;
  213. if(wsz1 == NULL || wsz2 == NULL)
  214. {
  215. nRet = 1;
  216. }
  217. else
  218. if(!(wsz1 == NULL && wsz2 == NULL))
  219. {
  220. while(*wsz1 || *wsz2)
  221. {
  222. int diff = wbem_towlower(*wsz1) - wbem_towlower(*wsz2);
  223. if(diff) return diff;
  224. wsz1++; wsz2++;
  225. }
  226. }
  227. return nRet;
  228. }
  229. int wbem_wcsincmp(const wchar_t* wsz1, const wchar_t* wsz2,int nChars)
  230. {
  231. int nIndex = 0;
  232. int nDiff = 0;
  233. if(wsz1 == NULL || wsz2 == NULL)
  234. {
  235. nDiff = 1;
  236. }
  237. else
  238. if(!(wsz1 == NULL && wsz2 == NULL))
  239. {
  240. while((*wsz1 || *wsz2) && nIndex < nChars )
  241. {
  242. nDiff = wbem_towlower(*wsz1) - wbem_towlower(*wsz2);
  243. if(nDiff)
  244. {
  245. break;
  246. }
  247. wsz1++; wsz2++;
  248. nIndex++;
  249. }
  250. }
  251. return nDiff;
  252. }
  253. BSTR Wmioledb_SysAllocString(const OLECHAR * sz)
  254. {
  255. BSTR strRet = SysAllocString(sz);
  256. if(strRet == NULL && sz != NULL)
  257. {
  258. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  259. }
  260. return strRet;
  261. }
  262. ///////////////////////////////////////////////////////////////////////////////////////////////////
  263. // Get Binding flags and put it in a variable as INIT_MODE flags
  264. ///////////////////////////////////////////////////////////////////////////////////////////////////
  265. void GetInitAndBindFlagsFromBindFlags(DBBINDURLFLAG dwBindURLFlags,LONG & lInitMode ,LONG & lInitBindFlags)
  266. {
  267. lInitMode = 0;
  268. lInitBindFlags = 0;
  269. // DBPROP_INIT_MODE
  270. if(DBBINDURLFLAG_READ & dwBindURLFlags)
  271. {
  272. lInitMode = lInitMode | DB_MODE_READ;
  273. }
  274. if(DBBINDURLFLAG_WRITE & dwBindURLFlags)
  275. {
  276. lInitMode = lInitMode | DB_MODE_WRITE;
  277. }
  278. if(DBBINDURLFLAG_SHARE_DENY_READ & dwBindURLFlags)
  279. {
  280. lInitMode = lInitMode | DB_MODE_SHARE_DENY_READ;
  281. }
  282. if(DBBINDURLFLAG_SHARE_DENY_WRITE & dwBindURLFlags)
  283. {
  284. lInitMode = lInitMode | DB_MODE_SHARE_DENY_WRITE;
  285. }
  286. if(DBBINDURLFLAG_SHARE_EXCLUSIVE & dwBindURLFlags)
  287. {
  288. lInitMode = lInitMode | DB_MODE_SHARE_EXCLUSIVE;
  289. }
  290. if(DBBINDURLFLAG_SHARE_DENY_NONE & dwBindURLFlags)
  291. {
  292. lInitMode = lInitMode | DB_MODE_SHARE_DENY_NONE;
  293. }
  294. // DBPROP_INIT_BINDFLAGS
  295. if(DBBINDURLFLAG_RECURSIVE & dwBindURLFlags)
  296. {
  297. lInitBindFlags = lInitBindFlags | DB_BINDFLAGS_RECURSIVE;
  298. }
  299. if(DBBINDURLFLAG_OUTPUT & dwBindURLFlags)
  300. {
  301. lInitBindFlags = lInitBindFlags | DB_BINDFLAGS_OUTPUT;
  302. }
  303. if(DBBINDURLFLAG_DELAYFETCHCOLUMNS & dwBindURLFlags)
  304. {
  305. lInitBindFlags = lInitBindFlags | DB_BINDFLAGS_DELAYFETCHCOLUMNS;
  306. }
  307. if(DBBINDURLFLAG_DELAYFETCHSTREAM & dwBindURLFlags)
  308. {
  309. lInitBindFlags = lInitBindFlags | DB_BINDFLAGS_DELAYFETCHSTREAM;
  310. }
  311. }
  312. int WMIOledb_LoadStringW(UINT nID, LPWSTR lpszBuf, UINT nMaxBuf)
  313. {
  314. int nLen;
  315. if (!g_bIsAnsiOS )
  316. {
  317. nLen = ::LoadStringW(g_hInstance, nID, lpszBuf, nMaxBuf);
  318. if (nLen == 0)
  319. {
  320. lpszBuf[0] = '\0';
  321. }
  322. }
  323. else
  324. {
  325. char *pszBuf = new char[nMaxBuf];
  326. if ( pszBuf )
  327. {
  328. nLen = ::LoadStringA(g_hInstance, nID, pszBuf, nMaxBuf);
  329. if (nLen == 0)
  330. {
  331. lpszBuf[0] = '\0';
  332. }
  333. else
  334. {
  335. nLen = ::MultiByteToWideChar(CP_ACP, 0, pszBuf, nLen + 1,
  336. lpszBuf, nMaxBuf);
  337. // Truncate to requested size
  338. if (nLen > 0)
  339. {
  340. // nLen doesn't include the '\0'.
  341. nLen = min(nMaxBuf - 1, (UINT) nLen - 1);
  342. }
  343. lpszBuf[nLen] = '\0';
  344. }
  345. delete [] pszBuf;
  346. }
  347. else
  348. {
  349. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  350. }
  351. }
  352. return nLen; // excluding terminator
  353. }
  354. CTString::CTString()
  355. {
  356. m_pStr = NULL;
  357. }
  358. CTString::~CTString()
  359. {
  360. SAFE_DELETE_ARRAY(m_pStr);
  361. }
  362. // NTRaid: 136432 , 136436
  363. // 07/05/00
  364. HRESULT CTString::LoadStr(UINT lStrID)
  365. {
  366. HRESULT hr = S_OK;
  367. // try fixed buffer first (to avoid wasting space in the heap)
  368. SAFE_DELETE_ARRAY(m_pStr);
  369. int nTcharLen = 256;
  370. m_pStr = new TCHAR[256];
  371. if(m_pStr)
  372. {
  373. memset(m_pStr,0,nTcharLen * sizeof(TCHAR));
  374. int nLen = LoadString(g_hInstance,lStrID, m_pStr,nTcharLen );
  375. if (nTcharLen - nLen > sizeof(TCHAR))
  376. {
  377. return S_OK;
  378. }
  379. // try buffer size of 512, then larger size until entire string is retrieved
  380. int nSize = 256;
  381. do
  382. {
  383. nTcharLen += nSize;
  384. SAFE_DELETE_PTR(m_pStr);
  385. m_pStr = new TCHAR[nTcharLen];
  386. if(m_pStr)
  387. {
  388. memset(m_pStr,0,nTcharLen * sizeof(TCHAR));
  389. nLen = LoadString(g_hInstance,lStrID, m_pStr,nTcharLen);
  390. }
  391. else
  392. {
  393. hr = E_OUTOFMEMORY;
  394. break;
  395. }
  396. } while (nTcharLen - nLen <= sizeof(TCHAR));
  397. }
  398. else
  399. {
  400. hr = E_OUTOFMEMORY;
  401. }
  402. return hr;
  403. }
  404. // Function which tries to get class name from urlparser and if not possible
  405. // get it from connection to the object
  406. // NTRaid : 134967
  407. // 07/12/00
  408. HRESULT GetClassName(CURLParser *pUrlParser,DBPROPSET* prgPropertySets,BSTR &strClassName,CWbemConnectionWrapper *pConWrapper)
  409. {
  410. HRESULT hr = S_OK;
  411. hr = pUrlParser->GetClassName(strClassName);
  412. if(FAILED(hr) && hr != E_OUTOFMEMORY)
  413. {
  414. BSTR strPath= NULL;
  415. if(SUCCEEDED(hr = pUrlParser->GetPath(strPath)) &&
  416. (FAILED(hr = pConWrapper->GetClassName(strPath,strClassName)) && hr != E_OUTOFMEMORY))
  417. {
  418. BSTR strTemp = NULL;
  419. if (SUCCEEDED(hr = pUrlParser->GetPath(strTemp)))
  420. {
  421. CWbemConnectionWrapper *pConnection = new CWbemConnectionWrapper;
  422. if(pConnection)
  423. {
  424. if(SUCCEEDED(hr = InitializeConnectionProperties(pConnection,prgPropertySets,strTemp)))
  425. {
  426. hr = pConnection->GetParameters(strTemp,strClassName);
  427. }
  428. SAFE_DELETE_PTR(pConnection);
  429. }
  430. else
  431. {
  432. hr = E_OUTOFMEMORY;
  433. }
  434. SAFE_FREE_SYSSTRING(strTemp);
  435. }
  436. }
  437. SAFE_FREE_SYSSTRING(strPath);
  438. }
  439. return hr;
  440. }
  441. HRESULT InitializeConnectionProperties(CWbemConnectionWrapper *pConWrap,DBPROPSET* prgPropertySets,BSTR strPath)
  442. {
  443. HRESULT hr = S_OK;
  444. DWORD dwAuthnLevel = 0;
  445. DWORD dwImpLevel = 0;
  446. CVARIANT var;
  447. var.SetStr(strPath);
  448. //==========================================================================
  449. // now, set the namespace, if this isn't a valid namespace, then it reverts
  450. // to the default
  451. //==========================================================================
  452. pConWrap->SetValidNamespace(&var);
  453. pConWrap->SetUserInfo(prgPropertySets->rgProperties[IDX_DBPROP_AUTH_USERID].vValue.bstrVal,
  454. prgPropertySets->rgProperties[IDX_DBPROP_AUTH_PASSWORD].vValue.bstrVal,
  455. prgPropertySets->rgProperties[IDX_DBPROP_WMIOLEDB_AUTHORITY].vValue.bstrVal);
  456. // convert the OLEDB prop value to the actual value
  457. dwAuthnLevel = GetAuthnLevel(prgPropertySets->rgProperties[IDX_DBPROP_INIT_PROTECTION_LEVEL].vValue.lVal);
  458. dwImpLevel = GetImpLevel(prgPropertySets->rgProperties[IDX_DBPROP_INIT_PROTECTION_LEVEL].vValue.lVal);
  459. pConWrap->SetLocale(prgPropertySets->rgProperties[IDX_DBPROP_INIT_LCID].vValue.lVal);
  460. pConWrap->SetConnAttributes(dwAuthnLevel,dwImpLevel);
  461. return hr;
  462. }
  463. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  464. // Get the authentication level for the corresponding OLEDB property
  465. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  466. DWORD GetAuthnLevel(DWORD dwAuthnPropVal)
  467. {
  468. DWORD dwAuthnLevel = RPC_C_AUTHN_LEVEL_DEFAULT;
  469. switch(dwAuthnPropVal)
  470. {
  471. case DB_PROT_LEVEL_NONE :
  472. dwAuthnLevel = RPC_C_AUTHN_LEVEL_NONE;
  473. break;
  474. case DB_PROT_LEVEL_CONNECT :
  475. dwAuthnLevel = RPC_C_AUTHN_LEVEL_CONNECT;
  476. break;
  477. case DB_PROT_LEVEL_CALL :
  478. dwAuthnLevel = RPC_C_AUTHN_LEVEL_CALL;
  479. break;
  480. case DB_PROT_LEVEL_PKT :
  481. dwAuthnLevel = RPC_C_AUTHN_LEVEL_PKT;
  482. break;
  483. case DB_PROT_LEVEL_PKT_INTEGRITY :
  484. dwAuthnLevel = RPC_C_AUTHN_LEVEL_PKT_INTEGRITY;
  485. break;
  486. case DB_PROT_LEVEL_PKT_PRIVACY :
  487. dwAuthnLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY;
  488. break;
  489. }
  490. return dwAuthnLevel;
  491. }
  492. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  493. // Get the impersonation level for the corresponding OLEDB property
  494. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  495. DWORD GetImpLevel(DWORD dwImpPropVal)
  496. {
  497. DWORD dwImpLevel = RPC_C_IMP_LEVEL_ANONYMOUS;
  498. switch(dwImpPropVal)
  499. {
  500. case DB_IMP_LEVEL_ANONYMOUS :
  501. dwImpLevel = RPC_C_IMP_LEVEL_ANONYMOUS;
  502. break;
  503. case DB_IMP_LEVEL_IDENTIFY :
  504. dwImpLevel = RPC_C_IMP_LEVEL_IDENTIFY;
  505. break;
  506. case DB_IMP_LEVEL_IMPERSONATE :
  507. dwImpLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  508. break;
  509. case DB_IMP_LEVEL_DELEGATE :
  510. dwImpLevel = RPC_C_IMP_LEVEL_DELEGATE;
  511. break;
  512. }
  513. return dwImpLevel;
  514. }
  515. // NTRaid:138957
  516. DBTYPE GetVBCompatibleAutomationType(DBTYPE dbInType)
  517. {
  518. DBTYPE dbTypeOut = dbInType;
  519. switch(dbInType)
  520. {
  521. case DBTYPE_UI4:
  522. dbTypeOut = DBTYPE_I4;
  523. break;
  524. }
  525. return dbTypeOut;
  526. }