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.

10794 lines
266 KiB

  1. /***************************************************************************/
  2. /* ISAM.C */
  3. /* Copyright (C) 1995-96 SYWARE Inc., All rights reserved */
  4. /***************************************************************************/
  5. // Commenting #define out - causing compiler error - not sure if needed, compiles
  6. // okay without it.
  7. //#define WINVER 0x0400
  8. #include "precomp.h"
  9. #include "wbemidl.h"
  10. #include <comdef.h>
  11. //smart pointer
  12. _COM_SMARTPTR_TYPEDEF(IWbemServices, IID_IWbemServices);
  13. _COM_SMARTPTR_TYPEDEF(IEnumWbemClassObject, IID_IEnumWbemClassObject);
  14. //_COM_SMARTPTR_TYPEDEF(IWbemContext, IID_IWbemContext );
  15. _COM_SMARTPTR_TYPEDEF(IWbemLocator, IID_IWbemLocator);
  16. _COM_SMARTPTR_TYPEDEF(IWbemClassObject, IID_IWbemClassObject);
  17. _COM_SMARTPTR_TYPEDEF(IWbemQualifierSet, IID_IWbemQualifierSet);
  18. #include "drdbdr.h"
  19. #include "float.h"
  20. #include "resource.h"
  21. #include <comdef.h> //for _bstr_t
  22. #include <vector>
  23. #include "cominit.h" //for Dcom blanket
  24. #include <process.h> //for _beginthreadex
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. //Some standard SYNTAX/CIMTYPE qualifier string constants
  31. //#define WBEM_WSYNTAX_CHAR L"CHAR"
  32. //#define WBEM_WSYNTAX_INT8 L"INT8"
  33. #define WBEM_WSYNTAX_UINT8 L"UINT8"
  34. #define WBEM_WSYNTAX_SINT8 L"SINT8"
  35. //#define WBEM_WSYNTAX_UCHAR L"UCHAR"
  36. //#define WBEM_WSYNTAX_BYTE L"BYTE"
  37. //#define WBEM_WSYNTAX_INT64 L"INT64"
  38. #define WBEM_WSYNTAX_SINT64 L"SINT64"
  39. #define WBEM_WSYNTAX_UINT64 L"UINT64"
  40. //#define WBEM_WSYNTAX_INTERVAL L"INTERVAL"
  41. #define WBEM_WSYNTAX_DATETIME L"DATETIME"
  42. //#define WBEM_WSYNTAX_DATE L"DATE"
  43. //#define WBEM_WSYNTAX_TIME L"TIME"
  44. #define WBEM_WSYNTAX_STRING L"STRING"
  45. //#define WBEM_WSYNTAX_DWORD L"DWORD"
  46. //#define WBEM_WSYNTAX_ULONG L"ULONG"
  47. //#define WBEM_WSYNTAX_UINT L"UINT"
  48. #define WBEM_WSYNTAX_SINT32 L"SINT32"
  49. #define WBEM_WSYNTAX_UINT32 L"UINT32"
  50. //#define WBEM_WSYNTAX_LONG L"LONG"
  51. //#define WBEM_WSYNTAX_INT L"INT"
  52. //#define WBEM_WSYNTAX_INTEGER L"INTEGER"
  53. //#define WBEM_WSYNTAX_INT32 L"INT32"
  54. //#define WBEM_WSYNTAX_WCHAR L"WCHAR"
  55. //#define WBEM_WSYNTAX_WCHAR_T L"WCHAR_T"
  56. //#define WBEM_WSYNTAX_INT16 L"INT16"
  57. //#define WBEM_WSYNTAX_SHORT L"SHORT"
  58. #define WBEM_WSYNTAX_SINT16 L"SINT16"
  59. #define WBEM_WSYNTAX_UINT16 L"UINT16"
  60. //#define WBEM_WSYNTAX_USHORT L"USHORT"
  61. //#define WBEM_WSYNTAX_WORD L"WORD"
  62. //#define WBEM_WSYNTAX_CHAR L"CHAR"
  63. #define WBEM_WSYNTAX_STRING_LEN 6
  64. #define WBEM_SYNTAX_STRING "STRING"
  65. #define WBEM_VARIANT_VT_I1 1
  66. #define WBEM_VARIANT_VT_UI1 2
  67. #define WBEM_VARIANT_VT_BSTR 3
  68. #define WBEM_VARIANT_VT_I4 4
  69. #define WBEM_VARIANT_VT_UI4 5
  70. #define WBEM_VARIANT_VT_I2 6
  71. #define WBEM_VARIANT_VT_UI2 7
  72. #define WBEM_VARIANT_VT_R4 8
  73. #define WBEM_VARIANT_VT_R8 9
  74. #define WBEM_VARIANT_VT_I8 10
  75. #define WBEM_VARIANT_VT_UI8 11
  76. #define WBEM_VARIANT_VT_BOOL 12
  77. #define WBEM_VARIANT_VT_ARRAY_I1 13
  78. #define WBEM_VARIANT_VT_ARRAY_UI1 14
  79. #define WBEM_VARIANT_VT_ARRAY_BSTR 15
  80. #define WBEM_VARIANT_VT_ARRAY_I4 16
  81. #define WBEM_VARIANT_VT_ARRAY_UI4 17
  82. #define WBEM_VARIANT_VT_ARRAY_I2 18
  83. #define WBEM_VARIANT_VT_ARRAY_UI2 19
  84. #define WBEM_VARIANT_VT_ARRAY_R4 20
  85. #define WBEM_VARIANT_VT_ARRAY_R8 21
  86. #define WBEM_VARIANT_VT_ARRAY_I8 22
  87. #define WBEM_VARIANT_VT_ARRAY_UI8 23
  88. #define WBEM_VARIANT_VT_ARRAY_BOOL 24
  89. #define WBEM_DSDT_UNKNOWN 0
  90. #define WBEM_DSDT_SINT8 1
  91. #define WBEM_DSDT_UINT8 2
  92. #define WBEM_DSDT_SINT64 3
  93. #define WBEM_DSDT_UINT64 4
  94. //#define WBEM_DSDT_INTERVAL 5
  95. #define WBEM_DSDT_TIMESTAMP 6
  96. //#define WBEM_DSDT_DATE 7
  97. //#define WBEM_DSDT_TIME 8
  98. #define WBEM_DSDT_SMALL_STRING 9
  99. #define WBEM_DSDT_STRING 10
  100. #define WBEM_DSDT_UINT32 11
  101. #define WBEM_DSDT_SINT32 12
  102. #define WBEM_DSDT_SINT16 13
  103. #define WBEM_DSDT_UINT16 14
  104. #define WBEM_DSDT_REAL 15
  105. #define WBEM_DSDT_DOUBLE 16
  106. #define WBEM_DSDT_BIT 17
  107. #define WBEM_DSDT_SINT8_ARRAY 18
  108. #define WBEM_DSDT_UINT8_ARRAY 19
  109. #define WBEM_DSDT_UINT32_ARRAY 20
  110. #define WBEM_DSDT_SINT32_ARRAY 21
  111. #define WBEM_DSDT_BOOL_ARRAY 22
  112. #define WBEM_DSDT_SINT16_ARRAY 23
  113. #define WBEM_DSDT_UINT16_ARRAY 24
  114. #define WBEM_DSDT_REAL_ARRAY 25
  115. #define WBEM_DSDT_DOUBLE_ARRAY 26
  116. #define WBEM_DSDT_SINT64_ARRAY 27
  117. #define WBEM_DSDT_UINT64_ARRAY 28
  118. #define WBEM_DSDT_STRING_ARRAY 29
  119. //#define WBEM_DSDT_INTERVAL_ARRAY 30
  120. #define WBEM_DSDT_TIMESTAMP_ARRAY 31
  121. //#define WBEM_DSDT_DATE_ARRAY 32
  122. //#define WBEM_DSDT_TIME_ARRAY 33
  123. #define WBEM_DSDT_SMALL_STRING_ARRAY 34
  124. BSTR gpPrincipal = NULL;
  125. BOOL g_DebugTracingSwitchedOn = FALSE; //global variable
  126. void __DuhDoSomething(LPCTSTR myStr,...)
  127. {
  128. if (g_DebugTracingSwitchedOn)
  129. {
  130. OutputDebugString(myStr);
  131. //Write data to file
  132. /*
  133. FILE* hfile = fopen("wbemdr32.log", "a");
  134. if (hfile)
  135. {
  136. fwrite(myStr, _mbstrlen(myStr) + 1, _mbstrlen(myStr) + 1, hfile);
  137. fclose(hfile);
  138. }
  139. */
  140. }
  141. }
  142. //used to create and manage worker thread
  143. CWorkerThreadManager glob_myWorkerThread;
  144. BOOL IsW2KOrMore(void)
  145. {
  146. OSVERSIONINFO os;
  147. os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  148. if(!GetVersionEx(&os))
  149. return FALSE; // should never happen
  150. return ( os.dwPlatformId == VER_PLATFORM_WIN32_NT ) && ( os.dwMajorVersion >= 5 ) ;
  151. }
  152. HRESULT WbemSetDynamicCloaking(IUnknown* pProxy,
  153. DWORD dwAuthnLevel, DWORD dwImpLevel)
  154. {
  155. ODBCTRACE("\nWBEM ODBC Driver : WbemSetDynamicCloaking\n");
  156. HRESULT hres;
  157. if(!IsW2KOrMore())
  158. {
  159. // Not NT5 --- don't bother
  160. // ========================
  161. ODBCTRACE("\nWBEM ODBC Driver : WbemSetDynamicCloaking : Not NT5 --- don't bother\n");
  162. return WBEM_S_FALSE;
  163. }
  164. // Try to get IClientSecurity from it
  165. // ==================================
  166. IClientSecurity* pSec;
  167. hres = pProxy->QueryInterface(IID_IClientSecurity, (void**)&pSec);
  168. if(FAILED(hres))
  169. {
  170. // Not a proxy --- not a problem
  171. // =============================
  172. ODBCTRACE("\nWBEM ODBC Driver : WbemSetDynamicCloaking : Not a proxy --- not a problem\n");
  173. return WBEM_S_FALSE;
  174. }
  175. DWORD dwSize = 1000;
  176. char buffer[1001];
  177. buffer[0] = 0;
  178. if ( GetUserName(buffer, &dwSize) )
  179. {
  180. CString lpMessage;
  181. lpMessage.Format("\nUser Account just before SetBlanket is %ld characters long : %s\n", dwSize, buffer);
  182. ODBCTRACE(lpMessage);
  183. }
  184. else
  185. {
  186. ODBCTRACE("\nGetUserName call failed just before SetBlanket\n");
  187. }
  188. hres = pSec->SetBlanket(pProxy,
  189. RPC_C_AUTHN_DEFAULT,//0xa,//RPC_C_AUTHN_WINNT,
  190. RPC_C_AUTHZ_DEFAULT,//0,//RPC_C_AUTHZ_NONE,
  191. NULL,
  192. RPC_C_AUTHN_LEVEL_CONNECT,//2,//dwAuthnLevel,
  193. RPC_C_IMP_LEVEL_IMPERSONATE,//3,//dwImpLevel,
  194. NULL,
  195. EOAC_DYNAMIC_CLOAKING//0x20
  196. );
  197. pSec->Release();
  198. if (SUCCEEDED(hres))
  199. {
  200. ODBCTRACE("\nWBEM ODBC Driver : WbemSetDynamicCloaking : SUCCEEDED\n");
  201. }
  202. else
  203. {
  204. ODBCTRACE("\nWBEM ODBC Driver : WbemSetDynamicCloaking : FAILED\n");
  205. }
  206. return hres;
  207. }
  208. HRESULT ISAMSetCloaking1(IUnknown* pProxy, BOOL fIsLocalConnection, BOOL fW2KOrMore, DWORD dwAuthLevel, DWORD dwImpLevel,
  209. BSTR authorityBSTR, BSTR userBSTR, BSTR passwdBSTR, COAUTHIDENTITY ** gpAuthIdentity)
  210. {
  211. HRESULT sc = WBEM_S_FALSE;
  212. if ( fIsLocalConnection && fW2KOrMore )
  213. {
  214. sc = WbemSetDynamicCloaking(pProxy, dwAuthLevel, dwImpLevel);
  215. }
  216. else
  217. {
  218. sc = SetInterfaceSecurityEx(pProxy, authorityBSTR, userBSTR, passwdBSTR,
  219. dwAuthLevel, dwImpLevel, EOAC_NONE, gpAuthIdentity, &gpPrincipal );
  220. }
  221. return sc;
  222. }
  223. HRESULT ISAMSetCloaking2(IUnknown* pProxy, BOOL fIsLocalConnection, BOOL fW2KOrMore, DWORD dwAuthLevel, DWORD dwImpLevel,
  224. COAUTHIDENTITY * gpAuthIdentity)
  225. {
  226. HRESULT sc = WBEM_S_FALSE;
  227. if ( fIsLocalConnection && fW2KOrMore )
  228. {
  229. sc = WbemSetDynamicCloaking(pProxy, dwAuthLevel, dwImpLevel);
  230. }
  231. else
  232. {
  233. SetInterfaceSecurityEx(pProxy, gpAuthIdentity, gpPrincipal, dwAuthLevel, dwImpLevel);
  234. }
  235. return sc;
  236. }
  237. void ISAMCheckWorkingThread_AllocEnv()
  238. {
  239. ODBCTRACE("\nISAMCheckWorkingThread_AllocEnv\n");
  240. //Create working thread if necessary
  241. if (! glob_myWorkerThread.GetThreadHandle() && ! glob_myWorkerThread.IsValid() )
  242. {
  243. ODBCTRACE("\nCreateWorkerThread\n");
  244. glob_myWorkerThread.CreateWorkerThread();
  245. }
  246. else
  247. {
  248. //increament ref count on working thread
  249. MyWorkingThreadParams* m_params = new MyWorkingThreadParams(NULL, NULL, 0, NULL);
  250. //post message to create this object on working thread
  251. CString sMessage;
  252. sMessage.Format( "\nCreateWorkerThread : post message to thread %ld\n", glob_myWorkerThread.GetThreadId() );
  253. ODBCTRACE(sMessage);
  254. EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
  255. ResetEvent(m_params->m_EventHnd);
  256. LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
  257. BOOL status = PostThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REFCOUNT_INCR, 0, (LPARAM)m_params);
  258. WaitForSingleObject(m_params->m_EventHnd, INFINITE);
  259. ODBCTRACE("\nISAMCheckWorkingThread_AllocEnv : exit\n");
  260. delete m_params;
  261. }
  262. }
  263. void ISAMCheckWorkingThread_FreeEnv()
  264. {
  265. //decrement ref count
  266. MyWorkingThreadParams* m_params = new MyWorkingThreadParams(NULL, NULL, 0, NULL);
  267. //post message to create this object on working thread
  268. EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
  269. HANDLE EventHnd = m_params->m_EventHnd;
  270. ResetEvent(EventHnd);
  271. LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
  272. BOOL status = PostThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REFCOUNT_DECR, 0, (LPARAM)m_params);
  273. WaitForSingleObject(EventHnd, INFINITE);
  274. delete m_params;
  275. //if zero shut down thread
  276. if ( ! glob_myWorkerThread.GetRefCount() )
  277. {
  278. ISAMCloseWorkerThread1();
  279. //invalidate it
  280. glob_myWorkerThread.Invalidate();
  281. }
  282. }
  283. void ISAMCheckTracingOption()
  284. {
  285. //Read the registry setting to determine if you
  286. //want to enable tracing and set the global variable accordingly
  287. //by default logging is switched off
  288. g_DebugTracingSwitchedOn = FALSE;
  289. HKEY keyHandle = (HKEY)1;
  290. long fStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  291. "Software\\Microsoft\\WBEM", 0, KEY_READ, &keyHandle);
  292. if (fStatus == ERROR_SUCCESS)
  293. {
  294. DWORD dwLogging;
  295. DWORD sizebuff = sizeof(DWORD);
  296. DWORD typeValue;
  297. fStatus = RegQueryValueEx(keyHandle, "ODBC Logging", NULL,
  298. &typeValue, (LPBYTE)&dwLogging, &sizebuff);
  299. if ( (fStatus == ERROR_SUCCESS) && dwLogging )
  300. {
  301. //switch on logging if 'ODBC Logging' is set to a non-zero number
  302. g_DebugTracingSwitchedOn = TRUE;
  303. }
  304. RegCloseKey(keyHandle);
  305. }
  306. }
  307. void INTFUNC ISAMGetSelectStarList(char** lpWQLSelectStarList, //OUT
  308. TableColumnInfo* pSelectInfo, //IN
  309. LPISAM lpISAM);
  310. void Utility_GetLocaleIDFromString(IN char* lpValue, OUT DWORD& _dwLocale)
  311. {
  312. _bstr_t sFullLocaleStr = lpValue;
  313. if(!_wcsnicmp(sFullLocaleStr, L"MS\\", 3))
  314. {
  315. DWORD dwLocale = 0;
  316. _bstr_t sHexLocaleID = &((wchar_t*)sFullLocaleStr)[3];
  317. swscanf( sHexLocaleID, L"%x", &dwLocale);
  318. // Only set if we have a result
  319. if(dwLocale)
  320. _dwLocale = dwLocale;
  321. }
  322. }
  323. UINT Utility_GetCodePageFromLCID(LCID lcid)
  324. {
  325. char szLocale[12];
  326. UINT cp;
  327. int iNumChars = 0;
  328. iNumChars = GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, szLocale, sizeof(szLocale));
  329. if (iNumChars)
  330. {
  331. szLocale[iNumChars] = '\0';
  332. cp = strtoul(szLocale, NULL, 10);
  333. if (cp)
  334. return cp;
  335. }
  336. return GetACP();
  337. }
  338. void Utility_SetThreadLocale(IN char* lpValue, ULPSETTHREADLOCALE pProcSetThreadLocale)
  339. {
  340. // Default to local system Locale
  341. DWORD dwLocaleID = GetSystemDefaultLCID();
  342. if(lpValue && strlen(lpValue))
  343. {
  344. //Get the locale id from string
  345. Utility_GetLocaleIDFromString(lpValue, dwLocaleID);
  346. }
  347. if (pProcSetThreadLocale)
  348. {
  349. //Now set the thread locale
  350. if((*pProcSetThreadLocale)(dwLocaleID))
  351. {
  352. CString myText;
  353. myText.Format("\nWBEM ODBC Driver : Set ThreadLocaleID OK to: %d\n",dwLocaleID);
  354. ODBCTRACE(myText);
  355. }
  356. else
  357. {
  358. (*pProcSetThreadLocale)(GetSystemDefaultLCID());
  359. CString myText;
  360. myText.Format("\nWBEM ODBC Driver : Set ThreadLocaleID OK to system default: %d\n",GetSystemDefaultLCID());
  361. ODBCTRACE(myText);
  362. }
  363. }
  364. }
  365. int Utility_WideCharToDBCS(IN _bstr_t& _sWCharData,
  366. char** rgbValue,
  367. SDWORD cbValueMax)
  368. {
  369. DWORD dwDBCSBuffLen = cbValueMax;
  370. UINT cpThread = Utility_GetCodePageFromLCID(GetThreadLocale());
  371. // Tried WC_COMPOSITECHECK, didn't seem to work on Japanese machine
  372. int dwDBCSLen = WideCharToMultiByte(cpThread,WC_COMPOSITECHECK, (const wchar_t*)_sWCharData, -1,
  373. *rgbValue, cbValueMax, NULL, NULL);
  374. //The return length included the NULL terminator
  375. //so we need to remove this
  376. if (dwDBCSLen)
  377. --dwDBCSLen;
  378. return dwDBCSLen;
  379. }
  380. void Utility_DBCSToWideChar(IN const char* _dbcsData,
  381. OUT wchar_t** _sOutData, SWORD cbLen)
  382. {
  383. DWORD dwDbcsLen = cbLen ? (cbLen+1) : (_mbstrlen(_dbcsData)+1);
  384. // alloca is much faster (see TN059)
  385. *_sOutData = new wchar_t [dwDbcsLen + 1];
  386. *_sOutData[0] = 0;
  387. UINT cpThread = Utility_GetCodePageFromLCID(GetThreadLocale());
  388. // tried MB_COMPOSITE didn't work on German machine
  389. int dwNumWideChars = MultiByteToWideChar(cpThread, MB_PRECOMPOSED, _dbcsData,
  390. cbLen ? dwDbcsLen : -1,
  391. *_sOutData,dwDbcsLen);
  392. if (!dwNumWideChars)
  393. {
  394. *_sOutData[0] = 0;
  395. }
  396. else
  397. {
  398. if (cbLen)
  399. (*_sOutData)[cbLen] = 0;
  400. }
  401. }
  402. class ThreadLocaleIdManager
  403. {
  404. private:
  405. LCID m_lcid;
  406. HINSTANCE hKernelApi;
  407. ULPSETTHREADLOCALE pProcSetThreadLocale;
  408. public :
  409. ThreadLocaleIdManager(IN LPISAM lpISAM);
  410. ThreadLocaleIdManager(LPUSTR lpLocale);
  411. ~ThreadLocaleIdManager();
  412. };
  413. ThreadLocaleIdManager::ThreadLocaleIdManager(IN LPISAM lpISAM)
  414. {
  415. hKernelApi = NULL;
  416. //Save current thread locale id
  417. m_lcid = GetThreadLocale();
  418. pProcSetThreadLocale = NULL;
  419. if (lpISAM->hKernelApi)
  420. {
  421. pProcSetThreadLocale = (ULPSETTHREADLOCALE) GetProcAddress(lpISAM->hKernelApi, "SetThreadLocale");
  422. }
  423. //Change thread locale id
  424. Utility_SetThreadLocale(lpISAM->m_Locale, pProcSetThreadLocale);
  425. }
  426. ThreadLocaleIdManager::ThreadLocaleIdManager(LPUSTR lpLocale)
  427. {
  428. hKernelApi = LoadLibrary("KERNEL32.DLL");
  429. m_lcid = GetThreadLocale();
  430. pProcSetThreadLocale = NULL;
  431. if (hKernelApi)
  432. {
  433. pProcSetThreadLocale = (ULPSETTHREADLOCALE) GetProcAddress(hKernelApi, "SetThreadLocale");
  434. }
  435. //Change thread locale id
  436. Utility_SetThreadLocale((char*)lpLocale, pProcSetThreadLocale);
  437. }
  438. ThreadLocaleIdManager::~ThreadLocaleIdManager()
  439. {
  440. //Restore thread locale id on destruction
  441. if (pProcSetThreadLocale)
  442. {
  443. (*pProcSetThreadLocale)(m_lcid);
  444. }
  445. if (hKernelApi)
  446. {
  447. BOOL status = FreeLibrary(hKernelApi);
  448. if (! status)
  449. {
  450. DWORD err = GetLastError();
  451. CString message ("\n\n***** FreeLibrary KERNEL32 failed : %ld*****\n\n", err);
  452. ODBCTRACE(message);
  453. }
  454. }
  455. }
  456. void ISAMStringConcat(char** resultString, char* myStr)
  457. {
  458. if (myStr)
  459. {
  460. ULONG len = s_lstrlen(myStr);
  461. ULONG oldLen = 0;
  462. if (resultString && *resultString)
  463. oldLen = s_lstrlen(*resultString);
  464. char* buffer = new char [oldLen + len + 1];
  465. buffer[0] = 0;
  466. if (oldLen)
  467. {
  468. sprintf (buffer, "%s%s", *resultString, myStr);
  469. }
  470. else
  471. {
  472. s_lstrcpy(buffer, myStr);
  473. }
  474. //delete old string
  475. if (resultString && *resultString)
  476. delete (*resultString);
  477. //replace with new string
  478. *resultString = buffer;
  479. }
  480. }
  481. ImpersonationManager::ImpersonationManager(char* org_szUser, char* org_szPassword, char* org_szAuthority)
  482. {
  483. ODBCTRACE(_T("\nWBEM ODBC Driver : ImpersonationManager constructor\n"));
  484. hToken = NULL;
  485. hAdvApi = NULL;
  486. // hKernelApi = NULL;
  487. pProcLogonUser = NULL;
  488. pProcImpersonateLoggedOnUser = NULL;
  489. pProcRevertToSelf = NULL;
  490. fImpersonatingNow = FALSE;
  491. //We need to do a LoadLibrary
  492. //as the inpersonation struff is not avaiable on
  493. //Windows 95 and Win32s
  494. fImpersonate = DoInitialChecks();
  495. if ( CanWeImpersonate() )
  496. {
  497. //Extract logon info
  498. ExtractLogonInfo(org_szUser, org_szPassword, org_szAuthority);
  499. }
  500. }
  501. void ImpersonationManager::ExtractLogonInfo(char* org_szUser, char* szPassword, char* szAuthority)
  502. {
  503. //The user name could be the domain and user id
  504. //Make a copy of the username
  505. szUser[0] = 0;
  506. if (org_szUser && strlen(org_szUser))
  507. strncpy(szUser, org_szUser, MAX_USER_NAME_LENGTH);
  508. szUser[MAX_USER_NAME_LENGTH] = 0;
  509. //Find backslash character
  510. char* lpDomain = NULL;
  511. char* lpUser = szUser;
  512. int ch = '\\';
  513. char* backslashPtr = strchr(szUser, ch);
  514. if (backslashPtr)
  515. {
  516. //Found backslash, therefore username
  517. //is domain<blackslash>userid
  518. lpDomain = szUser;
  519. lpUser = backslashPtr + 1;
  520. *backslashPtr = 0; //NULL the backslash so we get two strings
  521. }
  522. else
  523. {
  524. //no domain in user name
  525. //so set domain to authority value
  526. lpDomain = szAuthority;
  527. }
  528. //Call LogonUser via pointer to function
  529. BOOL status = (*pProcLogonUser)( lpUser,
  530. lpDomain,
  531. szPassword,
  532. LOGON32_LOGON_INTERACTIVE,
  533. LOGON32_PROVIDER_DEFAULT,
  534. &hToken
  535. );
  536. if (!status)
  537. {
  538. status = (*pProcLogonUser)( lpUser,
  539. lpDomain,
  540. szPassword,
  541. LOGON32_LOGON_BATCH,
  542. LOGON32_PROVIDER_DEFAULT,
  543. &hToken
  544. );
  545. }
  546. if (status)
  547. {
  548. ODBCTRACE(_T("\nWBEM ODBC Driver : LogonUser call SUCCEEDED, now impersonating user "));
  549. ODBCTRACE(_T(lpUser));
  550. if (lpDomain && strlen(lpDomain))
  551. {
  552. ODBCTRACE(_T(" on domain "));
  553. ODBCTRACE(_T(lpDomain));
  554. }
  555. ODBCTRACE(_T("\n"));
  556. Impersonate();
  557. }
  558. else
  559. {
  560. ODBCTRACE(_T("\nWBEM ODBC Driver : LogonUser call failed, not doing impersonation for user "));
  561. ODBCTRACE(_T(lpUser));
  562. if (lpDomain && strlen(lpDomain))
  563. {
  564. ODBCTRACE(_T(" on domain "));
  565. ODBCTRACE(_T(lpDomain));
  566. }
  567. ODBCTRACE(_T("\n"));
  568. CString lastErr;
  569. lastErr.Format ("Last Error = %ld \n", GetLastError() );
  570. ODBCTRACE (lastErr);
  571. hToken = NULL;
  572. fImpersonate = FALSE;
  573. }
  574. }
  575. BOOL ImpersonationManager::DoInitialChecks()
  576. {
  577. BOOL fError = FALSE;
  578. //Retieve pointer to functions you want to call
  579. // (only on Windows NT)
  580. hAdvApi = LoadLibrary("ADVAPI32.DLL");
  581. // hKernelApi = LoadLibrary("KERNEL32.DLL");
  582. // if (hAdvApi && hKernelApi)
  583. if (hAdvApi)
  584. {
  585. //LogonUser
  586. pProcLogonUser = (ULPLOGONUSER) GetProcAddress(hAdvApi, "LogonUserA");
  587. //ImpersonateLoggedOnUser
  588. pProcImpersonateLoggedOnUser = (ULPIMPERSONLOGGEDONUSER) GetProcAddress(hAdvApi, "ImpersonateLoggedOnUser");
  589. //RevertToSelf
  590. pProcRevertToSelf = (ULPREVERTTOSELF) GetProcAddress(hAdvApi, "RevertToSelf");
  591. //Check that you have valid pointers to all of these functions
  592. if ( (!pProcLogonUser) || (!pProcImpersonateLoggedOnUser) || (!pProcRevertToSelf) )
  593. {
  594. fError = TRUE;
  595. }
  596. }
  597. else
  598. {
  599. fError = TRUE;
  600. hAdvApi = NULL;
  601. }
  602. if (fError)
  603. {
  604. //Can't load libaries so fail
  605. ODBCTRACE(_T("\nWBEM ODBC Driver : Impersonation libraries/function failier !!!\n"));
  606. if (hAdvApi)
  607. {
  608. FreeLibrary(hAdvApi);
  609. hAdvApi = NULL;
  610. }
  611. // if (hKernelApi)
  612. // {
  613. // FreeLibrary(hKernelApi);
  614. // hKernelApi = NULL;
  615. // }
  616. }
  617. else
  618. {
  619. //success
  620. ODBCTRACE(_T("\nWBEM ODBC Driver : We can do impersonation !!!\n"));
  621. return TRUE;
  622. }
  623. //Default is failure to impersonate
  624. return FALSE;
  625. }
  626. ImpersonationManager::~ImpersonationManager()
  627. {
  628. ODBCTRACE(_T("\nWBEM ODBC Driver : ImpersonationManager DESTRUCTOR\n"));
  629. //If you are doing a SQLDisconnect this class will
  630. //be deleted by something like ISAMClose
  631. //Revert back to original user at this point
  632. //as it won't be done in destructor of MyImpersonator
  633. RevertToYourself();
  634. if (hAdvApi)
  635. {
  636. ODBCTRACE(_T("\nWBEM ODBC Driver : FreeLibrary(hAdvApi)\n"));
  637. FreeLibrary(hAdvApi);
  638. }
  639. // if (hKernelApi)
  640. // {
  641. // FreeLibrary(hKernelApi);
  642. // }
  643. if (hToken)
  644. {
  645. ODBCTRACE(_T("\nWBEM ODBC Driver : CloseHandle(hToken)\n"));
  646. CloseHandle(hToken);
  647. }
  648. }
  649. void ImpersonationManager::Impersonate(char* str)
  650. {
  651. if (fImpersonatingNow)
  652. {
  653. ODBCTRACE("\nWBEM ODBC Driver : ImpersonationManager::Impersonate - already impersonating\n");
  654. }
  655. //Call ImpersonateLoggedOnUser via pointer to function
  656. if ( CanWeImpersonate() && hToken && !fImpersonatingNow )
  657. {
  658. BOOL status = (*pProcImpersonateLoggedOnUser)( hToken );
  659. CString myText(_T("\nWBEM ODBC Driver : "));
  660. //Name of function
  661. if (str)
  662. {
  663. myText += str;
  664. myText += _T(" : ");
  665. }
  666. myText += _T("Impersonating the logged on user ");
  667. //User account you are impersonating
  668. if (szUser)
  669. {
  670. myText += _T("[");
  671. myText += _T(szUser);
  672. myText += _T("]");
  673. }
  674. if (status)
  675. {
  676. myText += _T("\n");
  677. }
  678. else
  679. {
  680. myText += _T(" FAILED\n");
  681. }
  682. ODBCTRACE(myText);
  683. if (status)
  684. fImpersonatingNow = TRUE;
  685. }
  686. }
  687. void ImpersonationManager::RevertToYourself(char* str)
  688. {
  689. //If impersonation is taking place
  690. //revert to original user
  691. //Call RevertToSelf via pointer to function
  692. if ( CanWeImpersonate() && fImpersonatingNow )
  693. {
  694. (*pProcRevertToSelf)();
  695. fImpersonatingNow = FALSE;
  696. CString myText(_T("\nWBEM ODBC Driver : "));
  697. if (str)
  698. {
  699. myText += _T(str);
  700. myText += _T(" : ");
  701. }
  702. myText += _T("Reverting To Self\n");
  703. ODBCTRACE(myText);
  704. }
  705. }
  706. /***********************************************/
  707. MyImpersonator::MyImpersonator(LPDBC myHandle, char* str)
  708. {
  709. hdl = myHandle;
  710. hstmt = NULL;
  711. lpISAM = NULL;
  712. lpImpersonator = NULL;
  713. displayStr = str;
  714. if (hdl->lpISAM && hdl->lpISAM->Impersonate)
  715. {
  716. hdl->lpISAM->Impersonate->Impersonate(displayStr);
  717. }
  718. }
  719. MyImpersonator::MyImpersonator(LPSTMT myHandle, char* str)
  720. {
  721. hdl = NULL;
  722. lpISAM = NULL;
  723. hstmt = myHandle;
  724. displayStr = str;
  725. lpImpersonator = NULL;
  726. if (hstmt->lpdbc && hstmt->lpdbc->lpISAM && hstmt->lpdbc->lpISAM->Impersonate)
  727. {
  728. hstmt->lpdbc->lpISAM->Impersonate->Impersonate(displayStr);
  729. }
  730. }
  731. MyImpersonator::MyImpersonator(LPISAM myHandle, char* str)
  732. {
  733. hdl = NULL;
  734. hstmt = NULL;
  735. lpISAM = myHandle;
  736. displayStr = str;
  737. lpImpersonator = NULL;
  738. if ( !lpISAM )
  739. ODBCTRACE("\nWBEM ODBC Driver : lpISAM is NULL\n");
  740. if (lpISAM && lpISAM->Impersonate)
  741. {
  742. BOOL copyOfFlag = lpISAM->Impersonate->fImpersonatingNow;
  743. lpISAM->Impersonate->fImpersonatingNow = FALSE;
  744. lpISAM->Impersonate->Impersonate(displayStr);
  745. lpISAM->Impersonate->fImpersonatingNow = copyOfFlag;
  746. }
  747. else
  748. {
  749. ODBCTRACE("\nWBEM ODBC Driver : lpISAM->Impersonate is NULL\n");
  750. }
  751. }
  752. MyImpersonator::MyImpersonator(char* szUser, char* szPassword, char* szAuthority, char* str)
  753. {
  754. hdl = NULL;
  755. hstmt = NULL;
  756. lpISAM = NULL;
  757. displayStr = str;
  758. lpImpersonator = new ImpersonationManager(szUser, szPassword, szAuthority);
  759. lpImpersonator->Impersonate(displayStr);
  760. }
  761. MyImpersonator::~MyImpersonator()
  762. {
  763. if (hdl)
  764. {
  765. if (hdl->lpISAM && hdl->lpISAM->Impersonate)
  766. {
  767. hdl->lpISAM->Impersonate->RevertToYourself(displayStr);
  768. }
  769. }
  770. else if (hstmt)
  771. {
  772. if (hstmt->lpdbc && hstmt->lpdbc->lpISAM && hstmt->lpdbc->lpISAM->Impersonate)
  773. {
  774. hstmt->lpdbc->lpISAM->Impersonate->RevertToYourself(displayStr);
  775. }
  776. }
  777. else if (lpISAM)
  778. {
  779. if (lpISAM->Impersonate)
  780. {
  781. BOOL copyOfFlag = lpISAM->Impersonate->fImpersonatingNow;
  782. lpISAM->Impersonate->fImpersonatingNow = TRUE;
  783. lpISAM->Impersonate->RevertToYourself(displayStr);
  784. lpISAM->Impersonate->fImpersonatingNow = copyOfFlag;
  785. }
  786. }
  787. else if (lpImpersonator)
  788. {
  789. //deleting will call RevertToYourself
  790. delete lpImpersonator;
  791. }
  792. }
  793. CBString::CBString(int nSize)
  794. {
  795. m_pString = SysAllocStringLen(NULL, nSize);
  796. m_temp = NULL;
  797. }
  798. CBString::CBString(WCHAR* pwszString, BOOL fInterpretAsBlank)
  799. {
  800. m_temp = NULL;
  801. m_pString = NULL;
  802. if (pwszString)
  803. {
  804. if ( wcslen(pwszString) )
  805. {
  806. m_pString = SysAllocString(pwszString);
  807. }
  808. else
  809. {
  810. //OK, we have a string of zero length
  811. //check if we interpret this as blank or NULL
  812. if (fInterpretAsBlank)
  813. {
  814. m_temp = new wchar_t[1];
  815. m_temp[0] = 0;
  816. m_pString = SysAllocString(m_temp);
  817. }
  818. }
  819. }
  820. }
  821. CBString::~CBString()
  822. {
  823. delete m_temp;
  824. if(m_pString) {
  825. SysFreeString(m_pString);
  826. m_pString = NULL;
  827. }
  828. }
  829. /***************************************************************************/
  830. /* Formats string parameter for output in square braces */
  831. SWORD INTFUNC ISAMFormatCharParm (char* theValue, BOOL &fOutOfBufferSpace,
  832. char* rgbValue, SDWORD cbValueMax, SDWORD FAR* pcbValue,
  833. BOOL fIsBinaryOutput, SDWORD fInt64Check = 0, BOOL fAllElements = TRUE)
  834. {
  835. //Now we must add in string value in the format [string]
  836. //However, if the string contains either [ or ] we must double
  837. //this character in the string sequence
  838. fOutOfBufferSpace = FALSE;
  839. //First store a reference to length of current string
  840. //in case we run out of buffer space when adding this string
  841. SDWORD pcbOldValue = (*pcbValue);
  842. //Do we need to show surrounding braces
  843. //Not for binary output or if we only want to
  844. //show one instance
  845. BOOL fSurroundingBraces = TRUE;
  846. if (fIsBinaryOutput)
  847. fSurroundingBraces = FALSE;
  848. if (!fAllElements)
  849. fSurroundingBraces = FALSE;
  850. //Add leading [ character (not for binary)
  851. if (fSurroundingBraces)
  852. {
  853. if ((1 + (*pcbValue)) <= cbValueMax)
  854. {
  855. rgbValue[(*pcbValue)] = '[';
  856. (*pcbValue) += 1;
  857. }
  858. else
  859. {
  860. fOutOfBufferSpace = TRUE;
  861. }
  862. }
  863. //Add each character in string checking for [ or ] (not for binary)
  864. ULONG cLengthOfElementString = 0;
  865. if (theValue)
  866. cLengthOfElementString = lstrlen(theValue);
  867. if (!fOutOfBufferSpace && cLengthOfElementString)
  868. {
  869. //Copy each character
  870. ULONG cIndex = 0;
  871. while ( (!fOutOfBufferSpace) && theValue[cIndex] )
  872. {
  873. //How much buffer space do we have left
  874. SDWORD cbSpaceLeft = cbValueMax - (*pcbValue);
  875. //???We need to add the character(s) and a NULL terminator
  876. // if ( (fSurroundingBraces) && ((theValue[cIndex] == '[') || (theValue[cIndex] == ']'))
  877. // && (cbSpaceLeft >= 2) )
  878. if ( (fSurroundingBraces) && ((theValue[cIndex] == '[') || (theValue[cIndex] == ']')) )
  879. {
  880. // if (cbSpaceLeft >= 3)
  881. if (cbSpaceLeft >= 2)
  882. {
  883. //Add the character in TWICE
  884. rgbValue[(*pcbValue)] = theValue[cIndex];
  885. rgbValue[(*pcbValue) + 1] = theValue[cIndex];
  886. //rgbValue[(*pcbValue) + 2] = 0;
  887. (*pcbValue) += 2;
  888. }
  889. else
  890. {
  891. fOutOfBufferSpace = TRUE;
  892. }
  893. }
  894. else
  895. {
  896. // if (cbSpaceLeft >= 2)
  897. if (cbSpaceLeft)
  898. {
  899. //Add the character in ONCE
  900. rgbValue[(*pcbValue)] = theValue[cIndex];
  901. //rgbValue[(*pcbValue) + 1] = 0;
  902. (*pcbValue) += 1;
  903. }
  904. else
  905. {
  906. fOutOfBufferSpace = TRUE;
  907. }
  908. }
  909. //Extra check if this is a 64 bit integer
  910. if (fInt64Check == WBEM_DSDT_SINT64)
  911. {
  912. switch (theValue[cIndex])
  913. {
  914. case '0':
  915. case '1':
  916. case '2':
  917. case '3':
  918. case '4':
  919. case '5':
  920. case '6':
  921. case '7':
  922. case '8':
  923. case '9':
  924. case '+':
  925. case '-':
  926. //OK
  927. break;
  928. default:
  929. {
  930. *pcbValue = 0;
  931. return ERR_INVALID_INTEGER;
  932. }
  933. break;
  934. }
  935. }
  936. if (fInt64Check == WBEM_DSDT_UINT64)
  937. {
  938. switch (theValue[cIndex])
  939. {
  940. case '0':
  941. case '1':
  942. case '2':
  943. case '3':
  944. case '4':
  945. case '5':
  946. case '6':
  947. case '7':
  948. case '8':
  949. case '9':
  950. //OK
  951. break;
  952. default:
  953. {
  954. *pcbValue = 0;
  955. return ERR_INVALID_INTEGER;
  956. }
  957. break;
  958. }
  959. }
  960. cIndex++;
  961. }
  962. }
  963. //Add trailing ] character (not for binary)
  964. if (fSurroundingBraces)
  965. {
  966. if ((!fOutOfBufferSpace) && ((1 + (*pcbValue)) <= cbValueMax))
  967. {
  968. rgbValue[(*pcbValue)] = ']';
  969. (*pcbValue) += 1;
  970. }
  971. else
  972. {
  973. fOutOfBufferSpace = TRUE;
  974. }
  975. }
  976. //If you run out of buffer space indicate to truncate
  977. if (fOutOfBufferSpace)
  978. {
  979. (*pcbValue) = pcbOldValue;
  980. return ISAM_TRUNCATION;
  981. }
  982. return NO_ISAM_ERR;
  983. }
  984. /***************************************************************************/
  985. /* This static function attempts to extract the precision from a property SYNTAX/CIMTYPE string */
  986. /* The SYNTAX/CIMTYPE string will be in the format: */
  987. /* name(precision) [ e.g. STRING(10) ] */
  988. /* The value of 'name' is input as the 1st parameter to this function */
  989. /* The 2nd parameter to this function is the whole SYNTAX/CIMTYPE string */
  990. /* The return value is the precision extracted */
  991. /* If an error occurs 0 is returned */
  992. static LONG GetPrecisionFromSyntaxStr(char* lpHeaderStr, char* lpString)
  993. {
  994. //Check for a valid input strings
  995. if (!lpHeaderStr || !lpString)
  996. return 0;
  997. //Check lengths of strings
  998. LONG cHeaderLen = lstrlen(lpHeaderStr);
  999. LONG cStrLen = lstrlen(lpString);
  1000. if ( !cHeaderLen || !cStrLen || (cStrLen < cHeaderLen) )
  1001. return 0;
  1002. //Set position to expected '('
  1003. char* pSearchPos = lpString + cHeaderLen;
  1004. char* pNumStart = NULL;
  1005. //skip leading white space
  1006. while (*pSearchPos && (*pSearchPos == ' '))
  1007. {
  1008. pSearchPos += 1;
  1009. }
  1010. if (*pSearchPos != '(')
  1011. {
  1012. return 0;
  1013. }
  1014. else
  1015. {
  1016. //OK, matched the first '(', now continue searching
  1017. //until you reach the end of the string or the ')'
  1018. pSearchPos += 1;
  1019. pNumStart = pSearchPos;
  1020. while ( *pSearchPos != ')' )
  1021. {
  1022. //Check if we have reached end of string before
  1023. //finding the ')'. If so return 0
  1024. if (*pSearchPos == 0)
  1025. return 0;
  1026. else
  1027. pSearchPos += 1;
  1028. }
  1029. *pSearchPos = 0;
  1030. }
  1031. return atoi (pNumStart);
  1032. }
  1033. /***************************************************************************/
  1034. BOOL INTFUNC ISAMGetWbemVariantType(LONG pType, SWORD& wTheVariantType)
  1035. {
  1036. BOOL fValidType = TRUE;
  1037. switch ( pType )
  1038. {
  1039. case CIM_SINT8: //was VT_I1:
  1040. {
  1041. wTheVariantType = WBEM_VARIANT_VT_I1;
  1042. }
  1043. break;
  1044. case CIM_UINT8: //was VT_UI1:
  1045. {
  1046. wTheVariantType = WBEM_VARIANT_VT_UI1;
  1047. }
  1048. break;
  1049. case CIM_SINT16: //was VT_I2:
  1050. {
  1051. wTheVariantType = WBEM_VARIANT_VT_I2;
  1052. }
  1053. break;
  1054. case CIM_UINT16: //was VT_UI2:
  1055. {
  1056. wTheVariantType = WBEM_VARIANT_VT_UI2;
  1057. }
  1058. break;
  1059. case CIM_REAL32: //was VT_R4:
  1060. {
  1061. wTheVariantType = WBEM_VARIANT_VT_R4;
  1062. }
  1063. break;
  1064. case CIM_REAL64: //was VT_R8:
  1065. {
  1066. wTheVariantType = WBEM_VARIANT_VT_R8;
  1067. }
  1068. break;
  1069. case CIM_BOOLEAN: //was VT_BOOL:
  1070. {
  1071. wTheVariantType = WBEM_VARIANT_VT_BOOL;
  1072. }
  1073. break;
  1074. case CIM_SINT32: //was VT_I4:
  1075. {
  1076. wTheVariantType = WBEM_VARIANT_VT_I4;
  1077. }
  1078. break;
  1079. case CIM_UINT32: //was VT_UI4:
  1080. {
  1081. wTheVariantType = WBEM_VARIANT_VT_UI4;
  1082. }
  1083. break;
  1084. case CIM_SINT64: //was VT_I8:
  1085. {
  1086. wTheVariantType = WBEM_VARIANT_VT_I8;
  1087. }
  1088. break;
  1089. case CIM_UINT64: //was VT_UI8:
  1090. {
  1091. wTheVariantType = WBEM_VARIANT_VT_UI8;
  1092. }
  1093. break;
  1094. case CIM_REFERENCE:
  1095. case CIM_STRING: //was VT_BSTR
  1096. case CIM_DATETIME:
  1097. {
  1098. wTheVariantType = WBEM_VARIANT_VT_BSTR;
  1099. }
  1100. break;
  1101. default:
  1102. {
  1103. //Check if it is a CIM_FLAG_ARRAY type
  1104. if (pType == (CIM_FLAG_ARRAY | CIM_SINT8))
  1105. {
  1106. wTheVariantType = WBEM_VARIANT_VT_ARRAY_I1;
  1107. }
  1108. else if (pType == (CIM_FLAG_ARRAY | CIM_UINT8))
  1109. {
  1110. wTheVariantType = WBEM_VARIANT_VT_ARRAY_UI1;
  1111. }
  1112. else if (pType == (CIM_FLAG_ARRAY | CIM_SINT32))
  1113. {
  1114. wTheVariantType = WBEM_VARIANT_VT_ARRAY_I4;
  1115. }
  1116. else if (pType == (CIM_FLAG_ARRAY | CIM_UINT32))
  1117. {
  1118. wTheVariantType = WBEM_VARIANT_VT_ARRAY_UI4;
  1119. }
  1120. else if (pType == (CIM_FLAG_ARRAY | CIM_SINT16))
  1121. {
  1122. wTheVariantType = WBEM_VARIANT_VT_ARRAY_I2;
  1123. }
  1124. else if (pType == (CIM_FLAG_ARRAY | CIM_UINT16))
  1125. {
  1126. wTheVariantType = WBEM_VARIANT_VT_ARRAY_UI2;
  1127. }
  1128. else if (pType == (CIM_FLAG_ARRAY | CIM_SINT64))
  1129. {
  1130. wTheVariantType = WBEM_VARIANT_VT_ARRAY_I8;
  1131. }
  1132. else if (pType == (CIM_FLAG_ARRAY | CIM_UINT64))
  1133. {
  1134. wTheVariantType = WBEM_VARIANT_VT_ARRAY_UI8;
  1135. }
  1136. else if (pType == (CIM_FLAG_ARRAY | CIM_REAL32))
  1137. {
  1138. wTheVariantType = WBEM_VARIANT_VT_ARRAY_R4;
  1139. }
  1140. else if (pType == (CIM_FLAG_ARRAY | CIM_REAL64))
  1141. {
  1142. wTheVariantType = WBEM_VARIANT_VT_ARRAY_R8;
  1143. }
  1144. else if (pType == (CIM_FLAG_ARRAY | CIM_BOOLEAN))
  1145. {
  1146. wTheVariantType = WBEM_VARIANT_VT_ARRAY_BOOL;
  1147. }
  1148. else if (pType == (CIM_FLAG_ARRAY | CIM_STRING))
  1149. {
  1150. wTheVariantType = WBEM_VARIANT_VT_ARRAY_BSTR;
  1151. }
  1152. else if (pType == (CIM_FLAG_ARRAY | CIM_REFERENCE))
  1153. {
  1154. wTheVariantType = WBEM_VARIANT_VT_ARRAY_BSTR;
  1155. }
  1156. else if (pType == (CIM_FLAG_ARRAY | CIM_DATETIME))
  1157. {
  1158. wTheVariantType = WBEM_VARIANT_VT_ARRAY_BSTR;
  1159. }
  1160. else
  1161. {
  1162. //unknown type
  1163. fValidType = FALSE;
  1164. }
  1165. }
  1166. break;
  1167. }
  1168. return fValidType;
  1169. }
  1170. /***************************************************************************/
  1171. BOOL INTFUNC ISAMGetDataSourceDependantTypeInfo(SWORD wVariantType, BSTR syntaxStr, SDWORD maxLenVal, SWORD& wDSDT, SWORD& fSqlType, UDWORD& cbPrecision)
  1172. {
  1173. //Initialize
  1174. BOOL fValidType = TRUE;
  1175. wDSDT = WBEM_DSDT_UNKNOWN;
  1176. switch (wVariantType)
  1177. {
  1178. case WBEM_VARIANT_VT_I1:
  1179. {
  1180. fSqlType = SQL_TINYINT;
  1181. cbPrecision = UTINYINT_PRECISION;
  1182. wDSDT = WBEM_DSDT_SINT8;
  1183. }
  1184. break;
  1185. case WBEM_VARIANT_VT_UI1:
  1186. {
  1187. fSqlType = SQL_TINYINT;
  1188. cbPrecision = UTINYINT_PRECISION;
  1189. wDSDT = WBEM_DSDT_UINT8;
  1190. }
  1191. break;
  1192. case WBEM_VARIANT_VT_I2:
  1193. {
  1194. wDSDT = WBEM_DSDT_SINT16;
  1195. fSqlType = SQL_SMALLINT;
  1196. cbPrecision = SMALLINT_PRECISION;
  1197. }
  1198. break;
  1199. case WBEM_VARIANT_VT_UI2:
  1200. {
  1201. wDSDT = WBEM_DSDT_UINT16;
  1202. fSqlType = SQL_SMALLINT;
  1203. cbPrecision = SMALLINT_PRECISION;
  1204. }
  1205. break;
  1206. case WBEM_VARIANT_VT_I4:
  1207. {
  1208. wDSDT = WBEM_DSDT_SINT32;
  1209. fSqlType = SQL_INTEGER;
  1210. cbPrecision = ULONG_PRECISION;
  1211. }
  1212. break;
  1213. case WBEM_VARIANT_VT_UI4:
  1214. {
  1215. wDSDT = WBEM_DSDT_UINT32;
  1216. fSqlType = SQL_INTEGER;
  1217. cbPrecision = ULONG_PRECISION;
  1218. }
  1219. break;
  1220. case WBEM_VARIANT_VT_I8:
  1221. {
  1222. fSqlType = SQL_BIGINT;
  1223. cbPrecision = 19;
  1224. wDSDT = WBEM_DSDT_SINT64;
  1225. }
  1226. break;
  1227. case WBEM_VARIANT_VT_UI8:
  1228. {
  1229. fSqlType = SQL_BIGINT;
  1230. cbPrecision = 20;
  1231. wDSDT = WBEM_DSDT_UINT64;
  1232. }
  1233. break;
  1234. case WBEM_VARIANT_VT_BSTR:
  1235. {
  1236. if (syntaxStr)
  1237. {
  1238. if (_wcsnicmp(WBEM_WSYNTAX_STRING, syntaxStr, WBEM_WSYNTAX_STRING_LEN) ==0)
  1239. {
  1240. LONG cbThePrecision = 254;
  1241. //The precision of a string could optionally be stored in
  1242. //the MAXLEN qualifier, let us try and get it
  1243. if (maxLenVal > 0)
  1244. {
  1245. cbThePrecision = maxLenVal;
  1246. //Double check for *bad* MAXLEN values
  1247. if (cbThePrecision == 0)
  1248. {
  1249. cbThePrecision = 254;
  1250. }
  1251. }
  1252. if (cbThePrecision > 254)
  1253. {
  1254. fSqlType = SQL_LONGVARCHAR;
  1255. //Got precision, so use it
  1256. cbPrecision = (cbThePrecision > (long)ISAM_MAX_LONGVARCHAR) ? ISAM_MAX_LONGVARCHAR : cbThePrecision;
  1257. wDSDT = WBEM_DSDT_STRING;
  1258. }
  1259. else
  1260. {
  1261. fSqlType = SQL_VARCHAR;
  1262. if (cbThePrecision)
  1263. {
  1264. //Got precision, so use it
  1265. cbPrecision = cbThePrecision;
  1266. }
  1267. else
  1268. {
  1269. //Could not get precision so use default
  1270. cbPrecision = 254;
  1271. }
  1272. wDSDT = WBEM_DSDT_SMALL_STRING;
  1273. }
  1274. }
  1275. else if(_wcsicmp(WBEM_WSYNTAX_DATETIME, syntaxStr) == 0)
  1276. {
  1277. fSqlType = SQL_TIMESTAMP;
  1278. #if TIMESTAMP_SCALE
  1279. cbPrecision = 20 + TIMESTAMP_SCALE;
  1280. #else
  1281. cbPrecision = 19;
  1282. #endif
  1283. wDSDT = WBEM_DSDT_TIMESTAMP;
  1284. }
  1285. else
  1286. {
  1287. //No match, default to SMALL_STRING
  1288. fSqlType = SQL_VARCHAR;
  1289. cbPrecision = 254;
  1290. wDSDT = WBEM_DSDT_SMALL_STRING;
  1291. }
  1292. }
  1293. else
  1294. {
  1295. //No Syntax string, default to SMALL_STRING
  1296. fSqlType = SQL_VARCHAR;
  1297. cbPrecision = 254;
  1298. wDSDT = WBEM_DSDT_SMALL_STRING;
  1299. }
  1300. }
  1301. break;
  1302. case WBEM_VARIANT_VT_R4:
  1303. {
  1304. fSqlType = SQL_DOUBLE;
  1305. cbPrecision = REAL_PRECISION;
  1306. wDSDT = WBEM_DSDT_REAL;
  1307. }
  1308. break;
  1309. case WBEM_VARIANT_VT_R8:
  1310. {
  1311. fSqlType = SQL_DOUBLE;
  1312. cbPrecision = DOUBLE_PRECISION;
  1313. wDSDT = WBEM_DSDT_DOUBLE; //WBEM_DSDT_REAL;
  1314. }
  1315. break;
  1316. case WBEM_VARIANT_VT_BOOL:
  1317. {
  1318. fSqlType = SQL_BIT;
  1319. cbPrecision = BOOL_PRECISION;
  1320. wDSDT = WBEM_DSDT_BIT; //WBEM_DSDT_REAL;
  1321. }
  1322. break;
  1323. case WBEM_VARIANT_VT_ARRAY_I1:
  1324. {
  1325. fSqlType = SQL_TINYINT;//SQL_LONGVARBINARY;
  1326. cbPrecision = 3;//ISAM_MAX_LONGVARCHAR;
  1327. wDSDT = WBEM_DSDT_SINT8_ARRAY;
  1328. }
  1329. break;
  1330. case WBEM_VARIANT_VT_ARRAY_UI1:
  1331. {
  1332. fSqlType = SQL_TINYINT; //SQL_LONGVARBINARY;
  1333. cbPrecision = 3; //ISAM_MAX_LONGVARCHAR;
  1334. wDSDT = WBEM_DSDT_UINT8_ARRAY;
  1335. }
  1336. break;
  1337. case WBEM_VARIANT_VT_ARRAY_I2:
  1338. {
  1339. fSqlType = SQL_SMALLINT; //SQL_LONGVARBINARY;
  1340. cbPrecision = 5; //ISAM_MAX_LONGVARCHAR;
  1341. wDSDT = WBEM_DSDT_SINT16_ARRAY;
  1342. }
  1343. break;
  1344. case WBEM_VARIANT_VT_ARRAY_UI2:
  1345. {
  1346. fSqlType = SQL_SMALLINT; //SQL_LONGVARBINARY;
  1347. cbPrecision = SMALLINT_PRECISION; //ISAM_MAX_LONGVARCHAR;
  1348. wDSDT = WBEM_DSDT_UINT16_ARRAY;
  1349. }
  1350. break;
  1351. case WBEM_VARIANT_VT_ARRAY_I4:
  1352. {
  1353. fSqlType = SQL_INTEGER; //SQL_LONGVARBINARY;
  1354. cbPrecision = 10; //ISAM_MAX_LONGVARCHAR;
  1355. wDSDT = WBEM_DSDT_SINT32_ARRAY;
  1356. }
  1357. break;
  1358. case WBEM_VARIANT_VT_ARRAY_UI4:
  1359. {
  1360. fSqlType = SQL_INTEGER; //SQL_LONGVARBINARY;
  1361. cbPrecision = 10; //ISAM_MAX_LONGVARCHAR;
  1362. wDSDT = WBEM_DSDT_UINT32_ARRAY;
  1363. }
  1364. break;
  1365. case WBEM_VARIANT_VT_ARRAY_I8:
  1366. {
  1367. fSqlType = SQL_BIGINT; //SQL_LONGVARBINARY;
  1368. cbPrecision = 19; //ISAM_MAX_LONGVARCHAR;
  1369. wDSDT = WBEM_DSDT_SINT64_ARRAY;
  1370. }
  1371. break;
  1372. case WBEM_VARIANT_VT_ARRAY_UI8:
  1373. {
  1374. fSqlType = SQL_BIGINT; //SQL_LONGVARBINARY;
  1375. cbPrecision = 20; //ISAM_MAX_LONGVARCHAR;
  1376. wDSDT = WBEM_DSDT_UINT64_ARRAY;
  1377. }
  1378. break;
  1379. case WBEM_VARIANT_VT_ARRAY_BOOL:
  1380. {
  1381. fSqlType = SQL_BIT; //SQL_LONGVARBINARY;
  1382. cbPrecision = BOOL_PRECISION; //ISAM_MAX_LONGVARCHAR;
  1383. wDSDT = WBEM_DSDT_BOOL_ARRAY;
  1384. }
  1385. break;
  1386. case WBEM_VARIANT_VT_ARRAY_R4:
  1387. {
  1388. fSqlType = SQL_DOUBLE; //SQL_LONGVARBINARY;
  1389. cbPrecision = REAL_PRECISION; //ISAM_MAX_LONGVARCHAR;
  1390. wDSDT = WBEM_DSDT_REAL_ARRAY;
  1391. }
  1392. break;
  1393. case WBEM_VARIANT_VT_ARRAY_R8:
  1394. {
  1395. fSqlType = SQL_DOUBLE; //SQL_LONGVARBINARY;
  1396. cbPrecision = 15; //ISAM_MAX_LONGVARCHAR;
  1397. wDSDT = WBEM_DSDT_DOUBLE_ARRAY;
  1398. }
  1399. break;
  1400. case WBEM_VARIANT_VT_ARRAY_BSTR:
  1401. {
  1402. fSqlType = SQL_VARCHAR; //SQL_LONGVARCHAR; //SQL_LONGVARBINARY;
  1403. cbPrecision = 254; //ISAM_MAX_LONGVARCHAR;
  1404. if (syntaxStr)
  1405. {
  1406. if (_wcsnicmp(WBEM_WSYNTAX_STRING, syntaxStr, WBEM_WSYNTAX_STRING_LEN) ==0)
  1407. {
  1408. LONG cbThePrecision = 254;
  1409. //The precision of a string could optionally be stored in
  1410. //the MAXLEN qualifier, let us try and get it
  1411. if (maxLenVal > 0)
  1412. {
  1413. cbThePrecision = maxLenVal;
  1414. //Double check for *bad* MAXLEN values
  1415. if (cbThePrecision == 0)
  1416. {
  1417. cbThePrecision = 254;
  1418. }
  1419. }
  1420. if (cbThePrecision > 254)
  1421. {
  1422. fSqlType = SQL_LONGVARCHAR;
  1423. //Got precision, so use it
  1424. cbPrecision = (cbThePrecision > (long)ISAM_MAX_LONGVARCHAR) ? ISAM_MAX_LONGVARCHAR : cbThePrecision;
  1425. wDSDT = WBEM_DSDT_STRING_ARRAY;
  1426. }
  1427. else
  1428. {
  1429. fSqlType = SQL_VARCHAR;
  1430. if (cbThePrecision)
  1431. {
  1432. //Got precision, so use it
  1433. cbPrecision = cbThePrecision;
  1434. }
  1435. else
  1436. {
  1437. //Could not get precision so use default
  1438. cbPrecision = 254;
  1439. }
  1440. wDSDT = WBEM_DSDT_SMALL_STRING_ARRAY;
  1441. }
  1442. }
  1443. else if (_wcsicmp(WBEM_WSYNTAX_DATETIME, syntaxStr) == 0)
  1444. {
  1445. wDSDT = WBEM_DSDT_TIMESTAMP_ARRAY;
  1446. fSqlType = SQL_TIMESTAMP;
  1447. #if TIMESTAMP_SCALE
  1448. cbPrecision = 20 + TIMESTAMP_SCALE;
  1449. #else
  1450. cbPrecision = 19;
  1451. #endif
  1452. }
  1453. else
  1454. {
  1455. //No match, default to SMALL STRING array
  1456. wDSDT = WBEM_DSDT_SMALL_STRING_ARRAY;
  1457. }
  1458. }
  1459. else
  1460. {
  1461. //No Syntax String, default to SMALL STRING array
  1462. wDSDT = WBEM_DSDT_SMALL_STRING_ARRAY;
  1463. }
  1464. }
  1465. break;
  1466. default:
  1467. fValidType = FALSE;
  1468. break;
  1469. }
  1470. //Return indication if this is a valid type
  1471. return fValidType;
  1472. }
  1473. /***************************************************************************/
  1474. /* Returns Data-Source Dependent type name in pre-allocated buffer */
  1475. void INTFUNC ISAMGetDataSourceDependantTypeStr(SWORD wDSDT, char* lpString)
  1476. {
  1477. lpString[0] = 0;
  1478. switch (wDSDT)
  1479. {
  1480. case WBEM_DSDT_SINT8:
  1481. lstrcpy(lpString, "SINT8");
  1482. break;
  1483. case WBEM_DSDT_UINT8:
  1484. lstrcpy(lpString, "UINT8");
  1485. break;
  1486. case WBEM_DSDT_SINT64:
  1487. lstrcpy(lpString, "SINT64");
  1488. break;
  1489. case WBEM_DSDT_UINT64:
  1490. lstrcpy(lpString, "UINT64");
  1491. break;
  1492. // case WBEM_DSDT_INTERVAL:
  1493. // lstrcpy(lpString, "INTERVAL");
  1494. // break;
  1495. case WBEM_DSDT_TIMESTAMP:
  1496. lstrcpy(lpString, "TIMESTAMP");
  1497. break;
  1498. // case WBEM_DSDT_DATE:
  1499. // lstrcpy(lpString, "DATE");
  1500. // break;
  1501. // case WBEM_DSDT_TIME:
  1502. // lstrcpy(lpString, "TIME");
  1503. // break;
  1504. case WBEM_DSDT_SMALL_STRING:
  1505. lstrcpy(lpString, "SMALL_STRING");
  1506. break;
  1507. case WBEM_DSDT_STRING:
  1508. lstrcpy(lpString, "STRING");
  1509. break;
  1510. case WBEM_DSDT_UINT32:
  1511. lstrcpy(lpString, "UINT32");
  1512. break;
  1513. case WBEM_DSDT_SINT32:
  1514. lstrcpy(lpString, "SINT32");
  1515. break;
  1516. case WBEM_DSDT_SINT16:
  1517. lstrcpy(lpString, "SINT16");
  1518. break;
  1519. case WBEM_DSDT_UINT16:
  1520. lstrcpy(lpString, "UINT16");
  1521. break;
  1522. case WBEM_DSDT_REAL:
  1523. lstrcpy(lpString, "REAL");
  1524. break;
  1525. case WBEM_DSDT_DOUBLE:
  1526. lstrcpy(lpString, "DOUBLE");
  1527. break;
  1528. case WBEM_DSDT_BIT:
  1529. lstrcpy(lpString, "BIT");
  1530. break;
  1531. case WBEM_DSDT_SINT8_ARRAY:
  1532. lstrcpy(lpString, "SINT8_ARRAY");
  1533. break;
  1534. case WBEM_DSDT_UINT8_ARRAY:
  1535. lstrcpy(lpString, "UINT8_ARRAY");
  1536. break;
  1537. case WBEM_DSDT_UINT32_ARRAY:
  1538. lstrcpy(lpString, "UINT32_ARRAY");
  1539. break;
  1540. case WBEM_DSDT_SINT32_ARRAY:
  1541. lstrcpy(lpString, "SINT32_ARRAY");
  1542. break;
  1543. case WBEM_DSDT_BOOL_ARRAY:
  1544. lstrcpy(lpString, "BOOL_ARRAY");
  1545. break;
  1546. case WBEM_DSDT_SINT16_ARRAY:
  1547. lstrcpy(lpString, "SINT16_ARRAY");
  1548. break;
  1549. case WBEM_DSDT_UINT16_ARRAY:
  1550. lstrcpy(lpString, "UINT16_ARRAY");
  1551. break;
  1552. case WBEM_DSDT_REAL_ARRAY:
  1553. lstrcpy(lpString, "REAL_ARRAY");
  1554. break;
  1555. case WBEM_DSDT_DOUBLE_ARRAY:
  1556. lstrcpy(lpString, "DOUBLE_ARRAY");
  1557. break;
  1558. case WBEM_DSDT_SINT64_ARRAY:
  1559. lstrcpy(lpString, "SINT64_ARRAY");
  1560. break;
  1561. case WBEM_DSDT_UINT64_ARRAY:
  1562. lstrcpy(lpString, "UINT64_ARRAY");
  1563. break;
  1564. case WBEM_DSDT_STRING_ARRAY:
  1565. lstrcpy(lpString, "STRING_ARRAY");
  1566. break;
  1567. case WBEM_DSDT_SMALL_STRING_ARRAY:
  1568. lstrcpy(lpString, "SMALL_STRING_ARRAY");
  1569. break;
  1570. // case WBEM_DSDT_INTERVAL_ARRAY:
  1571. // lstrcpy(lpString, "INTERVAL_ARRAY");
  1572. // break;
  1573. case WBEM_DSDT_TIMESTAMP_ARRAY:
  1574. lstrcpy(lpString, "TIMESTAMP_ARRAY");
  1575. break;
  1576. // case WBEM_DSDT_DATE_ARRAY:
  1577. // lstrcpy(lpString, "DATE_ARRAY");
  1578. // break;
  1579. // case WBEM_DSDT_TIME_ARRAY:
  1580. // lstrcpy(lpString, "TIME_ARRAY");
  1581. // break;
  1582. default:
  1583. break;
  1584. }
  1585. }
  1586. /***************************************************************************/
  1587. /***************************************************************************/
  1588. /***************************************************************************/
  1589. //
  1590. // Methods for ClassColumnInfo
  1591. //
  1592. /***************************************************************************/
  1593. /* ClassColumnInfo constructor */
  1594. /* */
  1595. /* Parameter pType is the Variant type of the property */ //
  1596. /* Parameter pSYNTAX contains NULL or the SYNTAX string for the property */
  1597. /* Parameter fGotSyntax indicates if a SYNTAX string is present */
  1598. /* This class is only used internaly by ClassColumnInfoBase and provides */
  1599. /* extracts property attribute values, like type, precision, scale */
  1600. ClassColumnInfo :: ClassColumnInfo(LONG pType, VARIANT* pSYNTAX, SDWORD maxLenVal, BOOL fGotSyntax, BOOL fIsLazy)
  1601. {
  1602. //Initialize
  1603. VariantInit(&aVariantSYNTAX);
  1604. szTypeName[0] = 0;
  1605. fValidType = TRUE;
  1606. varType = pType;
  1607. SWORD wDSDT = WBEM_DSDT_UNKNOWN;
  1608. SWORD wTheVariantType = 0;
  1609. ibScale = 0;
  1610. fIsLazyProperty = fIsLazy;
  1611. //Make a copy of input variants
  1612. if (fGotSyntax)
  1613. VariantCopy(&aVariantSYNTAX, pSYNTAX);
  1614. //Now work out info
  1615. // Get the column Type, Precision, Scale etc...
  1616. //You may need to get info from both column value
  1617. //and SYNTAX attributes in order to map column type to SQL_* type
  1618. //You may be able to directly map variant type to SQL_* type
  1619. //however, for some variant types there may be multiple mappings
  1620. //and so the SYNTAX attribute needs to be fetched in order to
  1621. //complete the mapping to SQL_* type.
  1622. fValidType = ISAMGetWbemVariantType(pType, wTheVariantType);
  1623. if (fValidType)
  1624. {
  1625. fValidType = ISAMGetDataSourceDependantTypeInfo
  1626. (wTheVariantType,
  1627. (fGotSyntax && aVariantSYNTAX.bstrVal) ? aVariantSYNTAX.bstrVal : NULL,
  1628. maxLenVal,
  1629. wDSDT, fSqlType, cbPrecision);
  1630. if (fValidType)
  1631. ISAMGetDataSourceDependantTypeStr(wDSDT, (char*)szTypeName);
  1632. }
  1633. }
  1634. /***************************************************************************/
  1635. /* Destructor */
  1636. ClassColumnInfo :: ~ClassColumnInfo()
  1637. {
  1638. //Tidy up
  1639. VariantClear(&aVariantSYNTAX);
  1640. }
  1641. /***************************************************************************/
  1642. //
  1643. // Methods of Class ClassColumnInfoBase
  1644. //
  1645. /***************************************************************************/
  1646. /***************************************************************************/
  1647. /***************************************************************************/
  1648. /* ClassColumnInfoBase Constructor */
  1649. /* */
  1650. /* This class is used as a repository */
  1651. /* to extract information about a */
  1652. /* property */
  1653. ClassColumnInfoBase :: ClassColumnInfoBase(LPISAMTABLEDEF pOrgTableDef, BOOL fIs__Gen)
  1654. {
  1655. //Initialize
  1656. isValid = TRUE;
  1657. pTableDef = pOrgTableDef;
  1658. pColumnInformation = NULL;
  1659. iColumnNumber = 0;
  1660. fIs__Generic = fIs__Gen;
  1661. cSystemProperties = 0;
  1662. embedded = NULL;
  1663. embeddedSize = 0;
  1664. //We need to get column information for a column
  1665. //The information we need is stored in a VALUE variant and the property attribute "SYNTAX"
  1666. //To get the property attribute "SYNTAX" variant we need the property/column name
  1667. //Get the column/property name
  1668. //We do this by getting the list of all property names in a SAFEARRAY
  1669. //create SAFEARRAY to store BSTR's
  1670. rgSafeArray = NULL;
  1671. //Check for pass-through SQL
  1672. if ( ! (pTableDef->pSingleTable) )
  1673. {
  1674. isValid = FALSE;
  1675. return;
  1676. }
  1677. //Get the names of all the properties/columns
  1678. SCODE scT = pTableDef->pSingleTable->GetNames ( NULL, 0, NULL, &rgSafeArray );
  1679. if (FAILED(scT))
  1680. {
  1681. rgSafeArray = NULL;
  1682. isValid = FALSE;
  1683. }
  1684. else
  1685. {
  1686. SafeArrayLock(rgSafeArray);
  1687. }
  1688. //Work out number of properties/columns
  1689. SafeArrayGetLBound(rgSafeArray, 1, &iLBound );
  1690. SafeArrayGetUBound(rgSafeArray, 1, &iUBound );
  1691. cColumnDefs = (UWORD) (iUBound - iLBound + 1);
  1692. if (fIs__Generic)
  1693. {
  1694. //This class is the prototype class for
  1695. //a passthrough SQL result set
  1696. //calculate additional embedded proprties
  1697. Get__GenericProfile();
  1698. }
  1699. }
  1700. /***************************************************************************/
  1701. /* Destructor */
  1702. ClassColumnInfoBase :: ~ClassColumnInfoBase()
  1703. {
  1704. //Tidy Up
  1705. if (rgSafeArray)
  1706. {
  1707. SafeArrayUnlock(rgSafeArray);
  1708. SafeArrayDestroy(rgSafeArray);
  1709. }
  1710. if (pColumnInformation)
  1711. delete pColumnInformation;
  1712. //SAI ADDED if (cSystemProperties)
  1713. {
  1714. if (embedded)
  1715. {
  1716. for (UWORD i = 0; i < embeddedSize; i++)
  1717. {
  1718. if (embedded[i])
  1719. {
  1720. delete embedded[i];
  1721. embedded[i] = NULL;
  1722. }
  1723. }
  1724. delete embedded;
  1725. embedded = NULL;
  1726. }
  1727. }
  1728. }
  1729. /***************************************************************************/
  1730. /* Sets up extra column information for the selected */
  1731. /* column if required */
  1732. BOOL ClassColumnInfoBase :: Setup(LONG iColumnNum)
  1733. {
  1734. //Sets up extra column information of specified column
  1735. if ( (!pColumnInformation) || (iColumnNumber != iColumnNum) )
  1736. {
  1737. //Wrong column info, delete old column info
  1738. //and create for new column
  1739. if (pColumnInformation)
  1740. {
  1741. delete pColumnInformation;
  1742. pColumnInformation = NULL;
  1743. }
  1744. //Setup column info
  1745. if ( FAILED(GetColumnInfo(iColumnNum)) )
  1746. {
  1747. return FALSE;
  1748. }
  1749. else
  1750. {
  1751. //Check the newly created column information
  1752. if (! pColumnInformation->IsValidInfo() )
  1753. return FALSE;
  1754. iColumnNumber = iColumnNum;
  1755. }
  1756. }
  1757. return TRUE;
  1758. }
  1759. /***************************************************************************/
  1760. BOOL ClassColumnInfoBase :: GetVariantType(LONG iColumnNum, LONG &lVariant)
  1761. {
  1762. if ( !Setup(iColumnNum) )
  1763. return FALSE;
  1764. lVariant = pColumnInformation->GetVariantType();
  1765. return TRUE;
  1766. }
  1767. /***************************************************************************/
  1768. BOOL ClassColumnInfoBase :: GetSQLType(LONG iColumnNum, SWORD &wSQLType)
  1769. {
  1770. if ( !Setup(iColumnNum) )
  1771. return FALSE;
  1772. wSQLType = pColumnInformation->GetSQLType();
  1773. return TRUE;
  1774. }
  1775. /***************************************************************************/
  1776. BOOL ClassColumnInfoBase :: GetTypeName(LONG iColumnNum, UCHAR* &pbTypeName)
  1777. {
  1778. if ( !Setup(iColumnNum) )
  1779. return FALSE;
  1780. pbTypeName = pColumnInformation->GetTypeName();
  1781. return TRUE;
  1782. }
  1783. /***************************************************************************/
  1784. BOOL ClassColumnInfoBase :: GetPrecision(LONG iColumnNum, UDWORD &uwPrecision)
  1785. {
  1786. if ( !Setup(iColumnNum) )
  1787. return FALSE;
  1788. uwPrecision = pColumnInformation->GetPrecision();
  1789. return TRUE;
  1790. }
  1791. /***************************************************************************/
  1792. BOOL ClassColumnInfoBase :: GetScale(LONG iColumnNum, SWORD &wScale)
  1793. {
  1794. if ( !Setup(iColumnNum) )
  1795. return FALSE;
  1796. wScale = pColumnInformation->GetScale();
  1797. return TRUE;
  1798. }
  1799. /***************************************************************************/
  1800. BOOL ClassColumnInfoBase :: IsNullable(LONG iColumnNum, SWORD &wNullable)
  1801. {
  1802. if ( !Setup(iColumnNum) )
  1803. return FALSE;
  1804. wNullable = pColumnInformation->IsNullable();
  1805. return TRUE;
  1806. }
  1807. /***************************************************************************/
  1808. BOOL ClassColumnInfoBase :: IsLazy(LONG iColumnNum, BOOL &fLazy)
  1809. {
  1810. if ( !Setup(iColumnNum) )
  1811. return FALSE;
  1812. fLazy = pColumnInformation->IsLazy();
  1813. return TRUE;
  1814. }
  1815. /***************************************************************************/
  1816. BOOL ClassColumnInfoBase :: GetDataTypeInfo(LONG iColumnNum, LPSQLTYPE &pSQLType)
  1817. {
  1818. if ( !Setup(iColumnNum) )
  1819. return FALSE;
  1820. pSQLType = pColumnInformation->GetDataTypeInfo();
  1821. return TRUE;
  1822. }
  1823. /***************************************************************************/
  1824. SWORD ClassColumnInfoBase :: GetColumnName(LONG iColumnNumber, LPSTR pColumnName, LPSTR pColumnAlias)
  1825. {
  1826. //Create a store for column name
  1827. BSTR lpbString;
  1828. //Now we want column number "iColumnNumber"
  1829. CBString myString;
  1830. if (fIs__Generic)
  1831. {
  1832. CBString myAlias;
  1833. GetClassObject(iColumnNumber, myString, myAlias);
  1834. lpbString = myString.GetString();
  1835. //Copy across alias
  1836. if (pColumnAlias)
  1837. {
  1838. pColumnAlias[0] = 0;
  1839. //RAID 42256
  1840. char* pTemp = (char*) pColumnAlias;
  1841. _bstr_t myValue((BSTR)myAlias.GetString());
  1842. Utility_WideCharToDBCS(myValue, &pTemp, MAX_COLUMN_NAME_LENGTH);
  1843. pColumnAlias[MAX_COLUMN_NAME_LENGTH] = 0;
  1844. }
  1845. }
  1846. else
  1847. {
  1848. if ( FAILED(SafeArrayGetElement(rgSafeArray, &iColumnNumber, &lpbString)) )
  1849. {
  1850. return SQL_ERROR;
  1851. }
  1852. }
  1853. //copy column name
  1854. pColumnName[0] = 0;
  1855. //RAID 42256
  1856. char* pTemp = (char*) pColumnName;
  1857. _bstr_t myValue((BSTR)lpbString);
  1858. Utility_WideCharToDBCS(myValue, &pTemp, MAX_COLUMN_NAME_LENGTH);
  1859. pColumnName[MAX_COLUMN_NAME_LENGTH] = 0;
  1860. //SAI ADDED
  1861. if (!fIs__Generic)
  1862. SysFreeString(lpbString);
  1863. return SQL_SUCCESS;
  1864. }
  1865. /***************************************************************************/
  1866. // Checked for SetInterfaceSecurityEx on IWbemServices
  1867. UWORD ClassColumnInfoBase ::Get__GenericProfile()
  1868. {
  1869. UWORD propertyCount = cColumnDefs;
  1870. SAFEARRAY FAR* rgSafeArrayExtra = NULL;
  1871. //Get the names of the non-system properties/columns
  1872. SCODE scT = pTableDef->pSingleTable->GetNames ( NULL, WBEM_FLAG_NONSYSTEM_ONLY, NULL, &rgSafeArrayExtra );
  1873. if (FAILED(scT))
  1874. {
  1875. rgSafeArrayExtra = NULL;
  1876. return cColumnDefs;
  1877. }
  1878. //Lower bound
  1879. LONG iLBoundExtra;
  1880. //Upper bound
  1881. LONG iUBoundExtra;
  1882. SafeArrayGetLBound(rgSafeArrayExtra, 1, &iLBoundExtra );
  1883. SafeArrayGetUBound(rgSafeArrayExtra, 1, &iUBoundExtra );
  1884. UWORD cNumColumnDefs = (UWORD) (iUBoundExtra - iLBoundExtra + 1);
  1885. //As we know the total number of properties (cColumnDefs)
  1886. //and the total number of non-system properties (cNumColumnDefs)
  1887. //we can calculate the number of system properties
  1888. cSystemProperties = cColumnDefs - cNumColumnDefs;
  1889. embedded = new CEmbeddedDataItems* [cNumColumnDefs];
  1890. embeddedSize = cNumColumnDefs;
  1891. for (long i = 0; i < embeddedSize; i++)
  1892. {
  1893. embedded[i] = new CEmbeddedDataItems();
  1894. }
  1895. //Update number of columns (from ISAMTableDef)
  1896. if (pTableDef && pTableDef->passthroughMap)
  1897. {
  1898. cColumnDefs = (UWORD) pTableDef->passthroughMap->GetCount();
  1899. }
  1900. for (i = 0; i < cNumColumnDefs; i++)
  1901. {
  1902. //Create a store for column name
  1903. BSTR lpbString;
  1904. //Now we want column number "i"
  1905. if ( FAILED(SafeArrayGetElement(rgSafeArrayExtra, &i, &lpbString)) )
  1906. {
  1907. return cColumnDefs;
  1908. }
  1909. //Get the property type and value
  1910. CIMTYPE vType;
  1911. VARIANT pVal;
  1912. if ( FAILED(pTableDef->pSingleTable->Get(lpbString, 0, &pVal, &vType, 0)) )
  1913. {
  1914. return cColumnDefs;
  1915. }
  1916. //We are looking for embedded objects
  1917. if (vType == CIM_OBJECT)
  1918. {
  1919. (embedded[i])->embeddedName = lpbString;
  1920. IWbemClassObject* myEmbeddedObj = NULL;
  1921. IUnknown* myUnk = pVal.punkVal;
  1922. //(5)
  1923. myUnk->QueryInterface(IID_IWbemClassObject, (void**)&myEmbeddedObj);
  1924. if (myEmbeddedObj)
  1925. {
  1926. //Get the __CLASS property
  1927. //Get the property type and value
  1928. VARIANT pVal2;
  1929. CBString cimClass(L"__CLASS", FALSE);
  1930. if ( SUCCEEDED(myEmbeddedObj->Get(cimClass.GetString(), 0, &pVal2, NULL, 0)) )
  1931. {
  1932. _bstr_t wEmbeddedClassName = pVal2.bstrVal;
  1933. (embedded[i])->cClassObject = NULL;
  1934. IWbemServicesPtr myServicesPtr = NULL;
  1935. ISAMGetIWbemServices(pTableDef->lpISAM, *(pTableDef->pGateway2), myServicesPtr);
  1936. myServicesPtr->GetObject(wEmbeddedClassName, 0, pTableDef->pContext, &((embedded[i])->cClassObject), NULL);
  1937. VariantClear(&pVal2);
  1938. }
  1939. myEmbeddedObj->Release();
  1940. }
  1941. VariantClear(&pVal);
  1942. }
  1943. SysFreeString(lpbString);
  1944. }
  1945. //Tidy Up
  1946. SafeArrayDestroy(rgSafeArrayExtra);
  1947. return propertyCount;
  1948. }
  1949. /***************************************************************************/
  1950. IWbemClassObject* ClassColumnInfoBase :: GetClassObject(LONG iColumnNumber, CBString& lpPropName, CBString& cbTableAlias)
  1951. {
  1952. //Examine the zero-based column number and return the
  1953. //parent class object containing the requested property
  1954. if (pTableDef->passthroughMap)
  1955. {
  1956. PassthroughLookupTable* passthroughElement = NULL;
  1957. WORD myIndex = (WORD)iColumnNumber;
  1958. BOOL status = pTableDef->passthroughMap->Lookup(myIndex, (void*&)passthroughElement);
  1959. if (status)
  1960. {
  1961. lpPropName.AddString(passthroughElement->GetColumnName(), FALSE);
  1962. char* lpTableAlias = passthroughElement->GetTableAlias();
  1963. if (!lpTableAlias || !strlen(lpTableAlias))
  1964. return NULL;
  1965. cbTableAlias.AddString(lpTableAlias, FALSE);
  1966. //Now get the class object
  1967. UWORD cNumColumnDefs = cColumnDefs; //(as this value has been updated)
  1968. UWORD index = 0;
  1969. while (index < cNumColumnDefs)
  1970. {
  1971. if ((embedded[index])->embeddedName.GetString())
  1972. {
  1973. if (_wcsicmp((embedded[index])->embeddedName.GetString(), cbTableAlias.GetString()) == 0)
  1974. {
  1975. //found embedded object
  1976. return ((embedded[index])->cClassObject);
  1977. }
  1978. }
  1979. index++;
  1980. }
  1981. }
  1982. }
  1983. //should not reach here
  1984. return NULL;
  1985. }
  1986. /***************************************************************************/
  1987. SWORD ClassColumnInfoBase :: GetColumnInfo(LONG iColumnNumber)
  1988. {
  1989. //Create a store for column name
  1990. BSTR lpbString;
  1991. IWbemClassObjectPtr parentClass = NULL;
  1992. CBString myString;
  1993. if (fIs__Generic)
  1994. {
  1995. CBString myAlias; //not used
  1996. parentClass = GetClassObject(iColumnNumber, myString, myAlias);
  1997. lpbString = myString.GetString();
  1998. }
  1999. else
  2000. {
  2001. parentClass = pTableDef->pSingleTable;
  2002. //Now we want column number "iColumnNumber"
  2003. if ( FAILED(SafeArrayGetElement(rgSafeArray, &iColumnNumber, &lpbString)) )
  2004. {
  2005. return SQL_ERROR;
  2006. }
  2007. }
  2008. #ifdef TESTING
  2009. //copy column name
  2010. char pColumnName [MAX_COLUMN_NAME_LENGTH+1];
  2011. pColumnName[0] = 0;
  2012. wcstombs(pColumnName, lpbString, MAX_COLUMN_NAME_LENGTH);
  2013. pColumnName[MAX_COLUMN_NAME_LENGTH] = 0;
  2014. #endif
  2015. //Get the "Type" value
  2016. CIMTYPE pColumnType;
  2017. if ( FAILED(parentClass->Get(lpbString, 0, NULL, &pColumnType, 0)) )
  2018. {
  2019. if (!fIs__Generic)
  2020. SysFreeString(lpbString);
  2021. return SQL_ERROR;
  2022. }
  2023. //flag to indicate if property is marked 'lazy'
  2024. BOOL fIsLazyProperty = FALSE;
  2025. //Now get the qualifiers (if available)
  2026. IWbemQualifierSetPtr pQualifierSet = NULL;
  2027. if ( S_OK != (parentClass->GetPropertyQualifierSet
  2028. (lpbString, &pQualifierSet)) )
  2029. {
  2030. if (!fIs__Generic)
  2031. SysFreeString(lpbString);
  2032. //No qualifers, therefore no CIMTYPE, MAX & LAZY qualifiers
  2033. pColumnInformation = new ClassColumnInfo(pColumnType, NULL, NULL, FALSE, fIsLazyProperty);
  2034. return SQL_SUCCESS;
  2035. }
  2036. //Get the lazy qualifer (if applicable)
  2037. VARIANT pValLazy;
  2038. BSTR lazyStr = SysAllocString(WBEMDR32_L_LAZY);
  2039. if ( S_OK == (pQualifierSet->Get(lazyStr, 0, &pValLazy, NULL)) )
  2040. {
  2041. fIsLazyProperty = TRUE;
  2042. VariantClear(&pValLazy);
  2043. }
  2044. else
  2045. {
  2046. fIsLazyProperty = FALSE;
  2047. }
  2048. SysFreeString(lazyStr);
  2049. VARIANT pVal;
  2050. //Get the CIMTYPE qualifier
  2051. BSTR cimTypeStr = SysAllocString(WBEMDR32_L_CIMTYPE);
  2052. if ( S_OK != (pQualifierSet->Get(cimTypeStr, 0, &pVal, NULL)) )
  2053. {
  2054. //No CIMTYPE qualifier (therefore no max string)
  2055. pColumnInformation = new ClassColumnInfo(pColumnType, NULL,//&pVal
  2056. NULL, FALSE, fIsLazyProperty);
  2057. }
  2058. else
  2059. {
  2060. //Got the CIMTYPE qualifier
  2061. //Now get the optional MAX qualifier
  2062. long cbMaxValue = 0;
  2063. VARIANT pVal2;
  2064. BSTR maxStr = SysAllocString(WBEMDR32_L_MAX);
  2065. if ( S_OK != (pQualifierSet->Get(maxStr, 0, &pVal2, NULL)) )
  2066. {
  2067. //Got CIMTYPE but no MAX qualifier
  2068. pColumnInformation = new ClassColumnInfo(pColumnType, &pVal, NULL, TRUE, fIsLazyProperty);
  2069. }
  2070. else
  2071. {
  2072. //Got CIMTYPE and got MAX qualifier
  2073. SDWORD maxLenVal = pVal2.iVal;
  2074. pColumnInformation = new ClassColumnInfo(pColumnType, &pVal, maxLenVal, TRUE, fIsLazyProperty);
  2075. VariantClear(&pVal2);
  2076. }
  2077. SysFreeString(maxStr);
  2078. VariantClear(&pVal);
  2079. }
  2080. SysFreeString(cimTypeStr);
  2081. if (!fIs__Generic)
  2082. SysFreeString(lpbString);
  2083. return SQL_SUCCESS;
  2084. }
  2085. /***************************************************************************/
  2086. SWORD ClassColumnInfoBase :: GetKey(LONG iColumnNumber, BOOL &isAKey)
  2087. {
  2088. //We return FALSE for now as we don't support SQLPrimaryKeys
  2089. //If we do implement SQLPrimaryKeys we can comment out the next two lines
  2090. isAKey = FALSE;
  2091. return SQL_SUCCESS;
  2092. //Create a store for column name
  2093. BSTR lpbString;
  2094. //Now we want column number "iColumnNumber"
  2095. if ( FAILED(SafeArrayGetElement(rgSafeArray, &iColumnNumber, &lpbString)) )
  2096. {
  2097. return SQL_ERROR;
  2098. }
  2099. //Now get the Key attribute value (if available)
  2100. IWbemQualifierSetPtr pQualifierSet = NULL;
  2101. if ( S_OK != (pTableDef->pSingleTable->GetPropertyQualifierSet
  2102. (lpbString, &pQualifierSet)) )
  2103. {
  2104. SysFreeString(lpbString);
  2105. return SQL_ERROR;
  2106. }
  2107. //SAI ADDED - Tidy up
  2108. SysFreeString(lpbString);
  2109. lpbString = NULL;
  2110. //Now get the KEY attribute value (if available)
  2111. VARIANT pVal;
  2112. isAKey = FALSE;
  2113. BSTR keyBSTR = SysAllocString(WBEMDR32_L_KEY);
  2114. if ( S_OK == (pQualifierSet->Get(keyBSTR, 0, &pVal, NULL)) )
  2115. {
  2116. isAKey = (pVal.boolVal != 0) ? TRUE : FALSE;
  2117. //TidyUp
  2118. VariantClear(&pVal);
  2119. }
  2120. SysFreeString(keyBSTR);
  2121. return SQL_SUCCESS;
  2122. }
  2123. /***************************************************************************/
  2124. SWORD ClassColumnInfoBase :: GetColumnAttr(LONG iColumnNumber, LPSTR pAttrStr, SDWORD cbValueMax, SDWORD &cbBytesCopied)
  2125. {
  2126. SWORD err = SQL_SUCCESS;
  2127. cbBytesCopied = 0;
  2128. //Create a store for column name
  2129. BSTR lpbString;
  2130. //Now we want column number "iColumnNumber"
  2131. if ( FAILED(SafeArrayGetElement(rgSafeArray, &iColumnNumber, &lpbString)) )
  2132. {
  2133. return SQL_ERROR;
  2134. }
  2135. #ifdef TESTING
  2136. //copy column name
  2137. char pColumnName [MAX_COLUMN_NAME_LENGTH+1];
  2138. pColumnName[0] = 0;
  2139. wcstombs(pColumnName, lpbString, MAX_COLUMN_NAME_LENGTH);
  2140. pColumnName[MAX_COLUMN_NAME_LENGTH] = 0;
  2141. #endif
  2142. //Get attributes for chosen column
  2143. IWbemQualifierSetPtr pQualifierSet = NULL;
  2144. if ( S_OK != (pTableDef->pSingleTable->GetPropertyQualifierSet(lpbString, &pQualifierSet)) )
  2145. {
  2146. SysFreeString(lpbString);
  2147. return SQL_ERROR;
  2148. }
  2149. SysFreeString(lpbString);
  2150. lpbString = NULL;
  2151. //Get CIMTYPE String
  2152. VARIANT pVal2;
  2153. BSTR syntaxStr = NULL;
  2154. BOOL fClearpVal2 = FALSE;
  2155. BSTR cimTypeBSTR = SysAllocString(WBEMDR32_L_CIMTYPE);
  2156. if ( S_OK == (pQualifierSet->Get(cimTypeBSTR, 0, &pVal2, NULL)) )
  2157. {
  2158. if (pVal2.bstrVal)
  2159. syntaxStr = pVal2.bstrVal;
  2160. fClearpVal2 = TRUE;
  2161. }
  2162. SysFreeString(cimTypeBSTR);
  2163. //Get the MAX String
  2164. VARIANT pVal3;
  2165. SDWORD maxLenVal = 0;
  2166. BOOL fClearpVal3 = FALSE;
  2167. BSTR maxBSTR = SysAllocString(WBEMDR32_L_MAX);
  2168. if ( S_OK == (pQualifierSet->Get(maxBSTR, 0, &pVal3, NULL)) )
  2169. {
  2170. maxLenVal = pVal3.iVal;
  2171. fClearpVal3 = TRUE;
  2172. }
  2173. SysFreeString(maxBSTR);
  2174. //Now get list of attribute names from attribute set
  2175. //create SAFEARRAY to store attribute names
  2176. SAFEARRAY FAR* rgNames = NULL;
  2177. //Fetch attribute names
  2178. pQualifierSet->GetNames(0, &rgNames);
  2179. SafeArrayLock(rgNames);
  2180. //Get the upper and lower bounds of SAFEARRAY
  2181. long lowerBound;
  2182. SafeArrayGetLBound(rgNames, 1, &lowerBound);
  2183. long upperBound;
  2184. SafeArrayGetUBound(rgNames, 1, &upperBound);
  2185. //Get each name out
  2186. BSTR pTheAttrName;
  2187. for (long ix = lowerBound; ix <= upperBound; ix++)
  2188. {
  2189. if ( SUCCEEDED(SafeArrayGetElement(rgNames, &ix, &pTheAttrName)) )
  2190. {
  2191. //Get variant value of named attribute
  2192. VARIANT pVal;
  2193. if ( S_OK == (pQualifierSet->Get(pTheAttrName, 0, &pVal, NULL)) )
  2194. {
  2195. //Decode variant value, as we do not know actual size of value
  2196. //beforehand we will create buffers in increments of 200 bytes
  2197. //until we can get the value with truncation
  2198. ULONG cwAttemptToGetValue = 0;
  2199. ULONG wBufferLen = 0;
  2200. char* buffer = NULL;
  2201. SDWORD cbValue;
  2202. SWORD err = ISAM_TRUNCATION;
  2203. while ( err == ISAM_TRUNCATION )
  2204. {
  2205. if (buffer)
  2206. delete buffer;
  2207. wBufferLen = 200 * (++cwAttemptToGetValue);
  2208. buffer = new char [wBufferLen + 1];
  2209. buffer[0] = 0;
  2210. err = ISAMGetValueFromVariant(pVal, SQL_C_CHAR, buffer, wBufferLen, &cbValue, 0, syntaxStr, maxLenVal);
  2211. }
  2212. VariantClear (&pVal);
  2213. if (fClearpVal2)
  2214. VariantClear (&pVal2);
  2215. if (fClearpVal3)
  2216. VariantClear (&pVal3);
  2217. //Check for error
  2218. if (err != NO_ISAM_ERR)
  2219. {
  2220. pTableDef->lpISAM->errcode = err;
  2221. SafeArrayUnlock(rgNames);
  2222. SafeArrayDestroy(rgNames);
  2223. SysFreeString(pTheAttrName);
  2224. delete buffer;
  2225. return SQL_ERROR;
  2226. }
  2227. //Once we have the name and value of the attribute let us try and add
  2228. //it to the output buffer
  2229. //First try and save the attribute name
  2230. //Save old number of bytes copied so that if truncation
  2231. //occurs we can roll back to original state
  2232. SDWORD pdbOldValue = cbBytesCopied;
  2233. //If this is not the first attribute in the list
  2234. //we must separate the attribute/value pairs with "\n" character
  2235. if ( (cbValueMax - cbBytesCopied) && cbBytesCopied)
  2236. {
  2237. pAttrStr[cbBytesCopied++] = '\n';
  2238. }
  2239. //Now add in attribute name
  2240. //first convert it from a BSTR to a char*
  2241. char* lpTheAttrString = NULL;
  2242. ULONG cLength = 0;
  2243. if (pTheAttrName)
  2244. {
  2245. cLength = wcslen(pTheAttrName);
  2246. lpTheAttrString = new char [cLength + 1];
  2247. lpTheAttrString[0] = 0;
  2248. wcstombs(lpTheAttrString, pTheAttrName, cLength);
  2249. lpTheAttrString[cLength] = 0;
  2250. }
  2251. BOOL fOutOfBufferSpace = FALSE;
  2252. err = ISAMFormatCharParm (lpTheAttrString, fOutOfBufferSpace,
  2253. pAttrStr, cbValueMax, &cbBytesCopied, FALSE);
  2254. delete lpTheAttrString;
  2255. //Now add in value
  2256. if (err == NO_ISAM_ERR)
  2257. {
  2258. err = ISAMFormatCharParm (buffer, fOutOfBufferSpace,
  2259. pAttrStr, cbValueMax, &cbBytesCopied, FALSE);
  2260. }
  2261. delete buffer;
  2262. buffer = NULL;
  2263. if (err != NO_ISAM_ERR)
  2264. {
  2265. //Truncation took place so rollback
  2266. cbBytesCopied = pdbOldValue;
  2267. //Null terminate
  2268. pAttrStr[cbBytesCopied] = 0;
  2269. SafeArrayUnlock(rgNames);
  2270. SafeArrayDestroy(rgNames);
  2271. SysFreeString(pTheAttrName);
  2272. return SQL_SUCCESS_WITH_INFO;
  2273. }
  2274. //Null terminate
  2275. pAttrStr[cbBytesCopied] = 0;
  2276. }
  2277. else
  2278. {
  2279. //Error, tidy up and then quit
  2280. SysFreeString(pTheAttrName);
  2281. SafeArrayUnlock(rgNames);
  2282. SafeArrayDestroy(rgNames);
  2283. return SQL_ERROR;
  2284. }
  2285. SysFreeString(pTheAttrName);
  2286. }
  2287. else
  2288. {
  2289. //Error, tidy up and then quit
  2290. SafeArrayUnlock(rgNames);
  2291. SafeArrayDestroy(rgNames);
  2292. return SQL_ERROR;
  2293. }
  2294. }
  2295. //Tidy Up
  2296. SafeArrayUnlock(rgNames);
  2297. SafeArrayDestroy(rgNames);
  2298. return SQL_SUCCESS;
  2299. }
  2300. /***************************************************************************/
  2301. SWORD INTFUNC ISAMGetTableAttr(LPISAMTABLEDEF lpISAMTableDef, LPSTR pAttrStr, SDWORD cbValueMax, SDWORD &cbBytesCopied)
  2302. {
  2303. SWORD err = SQL_SUCCESS;
  2304. cbBytesCopied = 0;
  2305. //Get attributes for chosen table
  2306. IWbemQualifierSetPtr pQualifierSet = NULL;
  2307. if ( S_OK != (lpISAMTableDef->pSingleTable->GetQualifierSet(&pQualifierSet)) )
  2308. {
  2309. return SQL_ERROR;
  2310. }
  2311. //Now get list of attribute names from attribute set
  2312. //create SAFEARRAY to store attribute names
  2313. SAFEARRAY FAR* rgNames = NULL;
  2314. //Fetch attribute names
  2315. pQualifierSet->GetNames(0, &rgNames);
  2316. SafeArrayLock(rgNames);
  2317. //Get the upper and lower bounds of SAFEARRAY
  2318. long lowerBound;
  2319. SafeArrayGetLBound(rgNames, 1, &lowerBound);
  2320. long upperBound;
  2321. SafeArrayGetUBound(rgNames, 1, &upperBound);
  2322. //Get each name out
  2323. BSTR pTheAttrName;
  2324. for (long ix = lowerBound; ix <= upperBound; ix++)
  2325. {
  2326. if ( SUCCEEDED(SafeArrayGetElement(rgNames, &ix, &pTheAttrName)) )
  2327. {
  2328. //Get variant value of named attribute
  2329. VARIANT pVal;
  2330. if ( S_OK == (pQualifierSet->Get(pTheAttrName, 0, &pVal, NULL)) )
  2331. {
  2332. //Get attribute set for column
  2333. IWbemQualifierSetPtr pQualifierSet2 = NULL;
  2334. if ( S_OK != (lpISAMTableDef->pSingleTable->GetPropertyQualifierSet(pTheAttrName, &pQualifierSet2)) )
  2335. {
  2336. SysFreeString(pTheAttrName);
  2337. return SQL_ERROR;
  2338. }
  2339. //Get CIMTYPE String
  2340. VARIANT pVal2;
  2341. BSTR syntaxStr = NULL;
  2342. BOOL fClearpVal2 = FALSE;
  2343. BSTR cimTypeBSTR = SysAllocString(WBEMDR32_L_CIMTYPE);
  2344. if ( S_OK == (pQualifierSet2->Get(cimTypeBSTR, 0, &pVal2, NULL)) )
  2345. {
  2346. if (pVal2.bstrVal)
  2347. syntaxStr = pVal2.bstrVal;
  2348. fClearpVal2 = TRUE;
  2349. }
  2350. SysFreeString(cimTypeBSTR);
  2351. //Get the MAX String
  2352. VARIANT pVal3;
  2353. SDWORD maxLenVal = 0;
  2354. BOOL fClearpVal3 = FALSE;
  2355. BSTR maxBSTR = SysAllocString(WBEMDR32_L_MAX);
  2356. if ( S_OK == (pQualifierSet->Get(maxBSTR, 0, &pVal3, NULL)) )
  2357. {
  2358. maxLenVal = pVal3.iVal;
  2359. fClearpVal3 = TRUE;
  2360. }
  2361. SysFreeString(maxBSTR);
  2362. //Decode variant value, as we do not know actual size of value
  2363. //beforehand we will create buffers in increments of 200 bytes
  2364. //until we can get the value with truncation
  2365. ULONG cwAttemptToGetValue = 0;
  2366. ULONG wBufferLen = 0;
  2367. char* buffer = NULL;
  2368. SDWORD cbValue;
  2369. SWORD err = ISAM_TRUNCATION;
  2370. while ( err == ISAM_TRUNCATION )
  2371. {
  2372. if (buffer)
  2373. delete buffer;
  2374. wBufferLen = 200 * (++cwAttemptToGetValue);
  2375. buffer = new char [wBufferLen + 1];
  2376. buffer[0] = 0;
  2377. err = ISAMGetValueFromVariant(pVal, SQL_C_CHAR, buffer, wBufferLen, &cbValue, 0, syntaxStr, maxLenVal);
  2378. }
  2379. VariantClear (&pVal);
  2380. if (fClearpVal2)
  2381. VariantClear (&pVal2);
  2382. if (fClearpVal3)
  2383. VariantClear (&pVal3);
  2384. //Check for error
  2385. if (err != NO_ISAM_ERR)
  2386. {
  2387. lpISAMTableDef->lpISAM->errcode = err;
  2388. SafeArrayUnlock(rgNames);
  2389. SafeArrayDestroy(rgNames);
  2390. SysFreeString(pTheAttrName);
  2391. delete buffer;
  2392. return SQL_ERROR;
  2393. }
  2394. //Once we have the name and value of the attribute let us try and add
  2395. //it to the output buffer
  2396. //First try and save the attribute name
  2397. //Save old number of bytes copied so that if truncation
  2398. //occurs we can roll back to original state
  2399. SDWORD pdbOldValue = cbBytesCopied;
  2400. //If this is not the first attribute in the list
  2401. //we must separate the attribute/value pairs with "\n" character
  2402. if ( (cbValueMax - cbBytesCopied) && cbBytesCopied)
  2403. {
  2404. pAttrStr[cbBytesCopied++] = '\n';
  2405. }
  2406. //Now add in attribute name
  2407. //first convert it from a BSTR to a char*
  2408. char* lpTheAttrString = NULL;
  2409. ULONG cLength = 0;
  2410. if (pTheAttrName)
  2411. {
  2412. cLength = wcslen(pTheAttrName);
  2413. lpTheAttrString = new char [cLength + 1];
  2414. lpTheAttrString[0] = 0;
  2415. wcstombs(lpTheAttrString, pTheAttrName, cLength);
  2416. lpTheAttrString[cLength] = 0;
  2417. }
  2418. BOOL fOutOfBufferSpace = FALSE;
  2419. err = ISAMFormatCharParm (lpTheAttrString, fOutOfBufferSpace,
  2420. pAttrStr, cbValueMax, &cbBytesCopied, FALSE);
  2421. delete lpTheAttrString;
  2422. //Now add in value
  2423. if (err == NO_ISAM_ERR)
  2424. {
  2425. err = ISAMFormatCharParm (buffer, fOutOfBufferSpace,
  2426. pAttrStr, cbValueMax, &cbBytesCopied, FALSE);
  2427. }
  2428. delete buffer;
  2429. buffer = NULL;
  2430. if (err != NO_ISAM_ERR)
  2431. {
  2432. //Truncation took place so rollback
  2433. cbBytesCopied = pdbOldValue;
  2434. //Null terminate
  2435. pAttrStr[cbBytesCopied] = 0;
  2436. SysFreeString(pTheAttrName);
  2437. return SQL_SUCCESS_WITH_INFO;
  2438. }
  2439. //Null terminate
  2440. pAttrStr[cbBytesCopied] = 0;
  2441. }
  2442. else
  2443. {
  2444. //Error, tidy up and then quit
  2445. SafeArrayUnlock(rgNames);
  2446. SafeArrayDestroy(rgNames);
  2447. return SQL_ERROR;
  2448. }
  2449. SysFreeString(pTheAttrName);
  2450. }
  2451. else
  2452. {
  2453. //Error, tidy up and then quit
  2454. SafeArrayUnlock(rgNames);
  2455. SafeArrayDestroy(rgNames);
  2456. return SQL_ERROR;
  2457. }
  2458. }
  2459. //Tidy Up
  2460. SafeArrayUnlock(rgNames);
  2461. SafeArrayDestroy(rgNames);
  2462. return SQL_SUCCESS;
  2463. }
  2464. /***************************************************************************/
  2465. UWORD INTFUNC GetNumberOfColumnsInTable(LPISAMTABLEDEF lpISAMTableDef)
  2466. {
  2467. //Get number of columns
  2468. ClassColumnInfoBase* cInfoBase = lpISAMTableDef->pColumnInfo;
  2469. if ( !cInfoBase->IsValid() )
  2470. {
  2471. return 0;
  2472. }
  2473. return cInfoBase->GetNumberOfColumns();
  2474. }
  2475. /***************************************************************************/
  2476. /* This method checks if a string contains any */
  2477. /* character preference control characters */
  2478. /* such as %, _, \\ */
  2479. /* */
  2480. /* this method was cut and pasted out of an */
  2481. /* existing class and converted into a function */
  2482. static BOOL INTFUNC IsRegularExpression(char* lpPattern)
  2483. {
  2484. //First check if input string is valid and if it has any
  2485. //characters to check for
  2486. ULONG cLen = 0;
  2487. char m_cWildcard = '%';
  2488. char m_cAnySingleChar = '_';
  2489. char m_cEscapeSeq = '\\';
  2490. if (lpPattern)
  2491. cLen = strlen (lpPattern);
  2492. ULONG iIndex = 0;
  2493. if (cLen)
  2494. {
  2495. //Go through string checking for the 'wildcard' and 'single char' characters
  2496. while (iIndex < cLen)
  2497. {
  2498. //Check for 'wildcard' and 'single char' characters
  2499. if ( (lpPattern[iIndex] == m_cWildcard) || (lpPattern[iIndex] == m_cAnySingleChar) )
  2500. {
  2501. return TRUE;
  2502. }
  2503. //Skip any characters which are preceeded by escape sequence character
  2504. if ( lpPattern[iIndex] == m_cEscapeSeq)
  2505. {
  2506. //skip escape character and next one
  2507. iIndex++;
  2508. }
  2509. //Increment index in string
  2510. iIndex++;
  2511. }
  2512. }
  2513. else
  2514. {
  2515. //No character to check
  2516. return FALSE;
  2517. }
  2518. //If you reach here then input string must not be a regular expression
  2519. return FALSE;
  2520. }
  2521. /***************************************************************************/
  2522. CNotifyTableNames ::CNotifyTableNames(LPISAMTABLELIST lpTblList)
  2523. {
  2524. //Initialize reference count and backpointer to table list
  2525. m_cRef = 0;
  2526. lpISAMTableList = lpTblList;
  2527. //create mutex (no owed by anyone yet)
  2528. m_mutex = CreateMutex(NULL, FALSE, NULL);
  2529. }
  2530. /***************************************************************************/
  2531. CNotifyTableNames :: ~CNotifyTableNames()
  2532. {
  2533. //Tidy Up
  2534. CloseHandle(m_mutex);
  2535. }
  2536. /***************************************************************************/
  2537. STDMETHODIMP_(ULONG) CNotifyTableNames :: AddRef(void)
  2538. {
  2539. return ++m_cRef;
  2540. }
  2541. /***************************************************************************/
  2542. STDMETHODIMP_(ULONG) CNotifyTableNames :: Release(void) // FOLLOWUP: why is the decrement commented out?
  2543. {
  2544. // if (--m_cRef != 0)
  2545. // {
  2546. // return m_cRef;
  2547. // }
  2548. //If you reached this point the reference count is zero
  2549. //Therefore we have got all information back
  2550. lpISAMTableList->iIndex = lpISAMTableList->pTblList->GetHeadPosition();
  2551. lpISAMTableList->fGotAllInfo = TRUE;
  2552. delete this;
  2553. return 0;
  2554. }
  2555. /***************************************************************************/
  2556. STDMETHODIMP CNotifyTableNames :: QueryInterface(REFIID riid, LPVOID FAR* ppv)
  2557. {
  2558. *ppv = NULL;
  2559. if (IID_IUnknown == riid || IID_IWbemObjectSink == riid)
  2560. *ppv = this;
  2561. if (*ppv == NULL)
  2562. return ResultFromScode(E_NOINTERFACE);
  2563. return NOERROR;
  2564. }
  2565. /***************************************************************************/
  2566. STDMETHODIMP_(SCODE) CNotifyTableNames :: Notify(long lObjectCount, IWbemClassObject** pObjArray)
  2567. {
  2568. //remember to mutex protect writing to table list
  2569. WaitForSingleObject(m_mutex, INFINITE);
  2570. for (long i = 0; i < lObjectCount; i++)
  2571. {
  2572. if (pObjArray[i])
  2573. {
  2574. pObjArray[i]->AddRef();
  2575. lpISAMTableList->pTblList->AddTail(pObjArray[i]);
  2576. }
  2577. }
  2578. ReleaseMutex(m_mutex);
  2579. return WBEM_NO_ERROR;
  2580. }
  2581. /***************************************************************************/
  2582. /* Setups up ISAM structure which stores data-source information */
  2583. SWORD INTFUNC ISAMOpen(LPUSTR lpszServer,
  2584. LPUSTR lpszDatabase,
  2585. LPUSTR lpszDSN,
  2586. // WBEM_LOGIN_AUTHENTICATION loginMethod,
  2587. LPUSTR lpszUsername,
  2588. LPUSTR lpszPassword,
  2589. LPUSTR lpszLocale,
  2590. LPUSTR lpszAuthority,
  2591. BOOL fSysProps,
  2592. CMapStringToOb *pNamespaceMap,
  2593. LPISAM FAR *lplpISAM,
  2594. LPUSTR lpszErrorMessage,
  2595. BOOL fOptimization,
  2596. BOOL fImpersonation,
  2597. BOOL fPassthroughOnly,
  2598. BOOL fIntpretEmptPwdAsBlk)
  2599. {
  2600. s_lstrcpy(lpszErrorMessage, "");
  2601. // ODBCTRACE("\nWBEM ODBC Driver : ISAMOpen\n");
  2602. //Extra check for table qualifier
  2603. if (!lpszDatabase || !s_lstrlen (lpszDatabase)) // need to check in args here too
  2604. {
  2605. LoadString(s_hModule, ISAM_NS_QUALMISSING, (LPSTR)lpszErrorMessage,
  2606. MAX_ERROR_LENGTH+1);
  2607. *lplpISAM = NULL;
  2608. return ISAM_NS_QUALMISSING;
  2609. }
  2610. HGLOBAL h;
  2611. LPISAM lpISAM;
  2612. h = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (ISAM));
  2613. if (h == NULL || (lpISAM = (LPISAM) GlobalLock (h)) == NULL) {
  2614. if (h)
  2615. GlobalFree(h);
  2616. LoadString(s_hModule, ISAM_MEMALLOCFAIL, (LPSTR)lpszErrorMessage,
  2617. MAX_ERROR_LENGTH+1);
  2618. *lplpISAM = NULL;
  2619. return ISAM_MEMALLOCFAIL;
  2620. }
  2621. lpISAM->cSQLTypes = NumTypes();
  2622. lpISAM->SQLTypes = SQLTypes;
  2623. lpISAM->fTxnCapable = SQL_TC_NONE;
  2624. lpISAM->fSchemaInfoTransactioned = FALSE;
  2625. lpISAM->fMultipleActiveTxn = FALSE;
  2626. lpISAM->fTxnIsolationOption = SQL_TXN_READ_UNCOMMITTED;
  2627. lpISAM->fDefaultTxnIsolation = SQL_TXN_READ_UNCOMMITTED;
  2628. lpISAM->udwNetISAMVersion = 0;
  2629. lpISAM->hKernelApi = LoadLibrary("KERNEL32.DLL");
  2630. lpISAM->netConnection = NULL;
  2631. lpISAM->netISAM = NET_OPAQUE_INVALID;
  2632. lpISAM->fCaseSensitive = FALSE;
  2633. s_lstrcpy(lpISAM->szName, "");
  2634. s_lstrcpy(lpISAM->szVersion, "");
  2635. lpISAM->cbMaxTableNameLength = 0;
  2636. lpISAM->cbMaxColumnNameLength = 0;
  2637. //WBEM Client Recognition variables
  2638. //(dummy values which will be overridden)
  2639. lpISAM->dwAuthLevel = 0;
  2640. lpISAM->dwImpLevel = 0;
  2641. lpISAM->gpAuthIdentity = NULL;
  2642. lpISAM->pNamespaceMap = pNamespaceMap;
  2643. s_lstrcpy (lpISAM->szServer, lpszServer);
  2644. s_lstrcpy (lpISAM->szDatabase, lpszDatabase);
  2645. s_lstrcpy (lpISAM->szUser, lpszUsername);
  2646. s_lstrcpy (lpISAM->szPassword, lpszPassword);
  2647. s_lstrcpy (lpISAM->szRootDb, "root");
  2648. //Flags for cloaking
  2649. lpISAM->fIsLocalConnection = IsLocalServer((LPSTR) lpszServer);
  2650. lpISAM->fW2KOrMore = IsW2KOrMore();
  2651. //Make copies of locale and authority
  2652. lpISAM->m_Locale = NULL;
  2653. if (lpszLocale)
  2654. {
  2655. int localeLen = lstrlen((char*)lpszLocale);
  2656. lpISAM->m_Locale = new char [localeLen + 1];
  2657. (lpISAM->m_Locale)[0] = 0;
  2658. lstrcpy(lpISAM->m_Locale, (char*)lpszLocale);
  2659. }
  2660. lpISAM->m_Authority = NULL;
  2661. if (lpszAuthority)
  2662. {
  2663. int authLen = lstrlen((char*)lpszAuthority);
  2664. lpISAM->m_Authority = new char [authLen + 1];
  2665. (lpISAM->m_Authority)[0] = 0;
  2666. lstrcpy(lpISAM->m_Authority, (char*)lpszAuthority);
  2667. }
  2668. lpISAM->fOptimization = fOptimization;
  2669. lpISAM->fSysProps = fSysProps;
  2670. lpISAM->fPassthroughOnly = fPassthroughOnly;
  2671. lpISAM->fIntpretEmptPwdAsBlank = fIntpretEmptPwdAsBlk;
  2672. //Check if impersonation is requested
  2673. lpISAM->Impersonate = NULL;
  2674. if (fImpersonation)
  2675. {
  2676. //Now check if impersonation is necessary
  2677. //only if connecting locally
  2678. if (IsLocalServer((LPSTR) lpszServer))
  2679. {
  2680. lpISAM->Impersonate = new ImpersonationManager(lpISAM->szUser, lpISAM->szPassword, lpISAM->m_Authority);
  2681. }
  2682. else
  2683. {
  2684. ODBCTRACE("\nWBEM ODBC Driver : Server not detected as local, not impersonating\n");
  2685. }
  2686. }
  2687. lpISAM->errcode = NO_ISAM_ERR;
  2688. //SAI new - make sure there is nothing in old
  2689. //ISAM before you assign to it
  2690. if (*lplpISAM)
  2691. ISAMClose(*lplpISAM);
  2692. *lplpISAM = lpISAM;
  2693. //Check if impersonation worked
  2694. if (fImpersonation && lpISAM->Impersonate)
  2695. {
  2696. if ( ! lpISAM->Impersonate->CanWeImpersonate() )
  2697. {
  2698. lpISAM->pNamespaceMap = NULL; //protect against deleting namespace map
  2699. ISAMClose(lpISAM);
  2700. *lplpISAM = NULL;
  2701. return ISAM_ERROR;
  2702. }
  2703. }
  2704. return NO_ISAM_ERR;
  2705. }
  2706. /***************************************************************************/
  2707. /* Creates a communication channel to the Gateway Server */
  2708. // Checked for SetInterfaceSecurityEx on IWbemServices
  2709. void INTFUNC ISAMGetGatewayServer(IWbemServicesPtr& pGateway, LPISAM lpISAM, LPUSTR lpQualifierName,
  2710. SWORD cbQualifierName)
  2711. {
  2712. ThreadLocaleIdManager myThread(lpISAM);
  2713. //First get the locator interface
  2714. IWbemLocator* pLocator = NULL;
  2715. SCODE sc = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER , IID_IWbemLocator, (void**) (&pLocator) );
  2716. //Bug fix for dbWeb
  2717. if ( FAILED(sc) )
  2718. {
  2719. //If you fail, initialize OLE and try again
  2720. OleInitialize(0);
  2721. sc = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER , IID_IWbemLocator, (void**) (&pLocator) );
  2722. }
  2723. if ( FAILED(sc) )
  2724. {
  2725. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 2 : Error position 1\n");
  2726. return;
  2727. }
  2728. //Get user and password fields
  2729. //Get handle to gateway server interface
  2730. pGateway = NULL;
  2731. long refcount = 0;
  2732. //Check if we want the default database or something else
  2733. //We will be building the fully qualified database pathname
  2734. //so we work out some lengths first
  2735. SWORD cbServerLen = (SWORD) _mbstrlen((LPSTR)lpISAM->szServer);
  2736. //RAID 57673 WMI has changed such that if you
  2737. //connect locally and pass a username and password
  2738. //it will fail
  2739. //Check for local connection
  2740. // CBString myServerStr;
  2741. // myServerStr.AddString( (LPSTR)lpISAM->szServer, FALSE );
  2742. // CServerLocationCheck myCheck (myServerStr);
  2743. BOOL fIsLocalConnection = lpISAM->fIsLocalConnection;//myCheck.IsLocal();
  2744. //Used to store the fully qualified database pathname
  2745. wchar_t pWcharName [MAX_DATABASE_NAME_LENGTH+1];
  2746. pWcharName[0] = 0;
  2747. if (cbQualifierName)
  2748. {
  2749. //We want something else
  2750. //We need to prepend server name to qualifier name
  2751. //Need to make sure everything fits in buffer size
  2752. if ( (cbServerLen + cbQualifierName + 1) > MAX_DATABASE_NAME_LENGTH )
  2753. {
  2754. pLocator->Release();
  2755. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 2 : Error position 2\n");
  2756. return;
  2757. }
  2758. CBString namespaceBSTR;
  2759. //Construct string
  2760. if (cbServerLen)
  2761. {
  2762. char pCharName [MAX_DATABASE_NAME_LENGTH+1];
  2763. pCharName[0] = 0;
  2764. sprintf (pCharName, "%s\\%s", (LPUSTR)lpISAM->szServer, (LPSTR)lpQualifierName);
  2765. CString myText;
  2766. myText.Format("\nWBEM ODBC Driver : Connecting using : %s\n", pCharName);
  2767. ODBCTRACE(myText);
  2768. //Convert to wide string
  2769. namespaceBSTR.AddString(pCharName, FALSE);
  2770. }
  2771. else
  2772. {
  2773. if (lpQualifierName)
  2774. {
  2775. namespaceBSTR.AddString((LPSTR)lpQualifierName, FALSE, cbQualifierName);
  2776. }
  2777. }
  2778. //Convert wide characters to BSTR for DCOM
  2779. //----------------------------------------
  2780. CBString userBSTR;
  2781. if (!fIsLocalConnection)
  2782. userBSTR.AddString((LPSTR)lpISAM->szUser, FALSE);
  2783. CBString passwdBSTR;
  2784. if (!fIsLocalConnection)
  2785. passwdBSTR.AddString((LPSTR)lpISAM->szPassword, lpISAM->fIntpretEmptPwdAsBlank);
  2786. CBString localeBSTR;
  2787. CBString authorityBSTR;
  2788. localeBSTR.AddString(lpISAM->m_Locale, FALSE);
  2789. //Get the local and authority fields
  2790. authorityBSTR.AddString(lpISAM->m_Authority, FALSE);
  2791. sc = pLocator->ConnectServer (namespaceBSTR.GetString(), userBSTR.GetString(), passwdBSTR.GetString(), localeBSTR.GetString(), 0, authorityBSTR.GetString(), NULL, &pGateway);
  2792. if (sc == S_OK)
  2793. {
  2794. sc = GetAuthImp( pGateway, &(lpISAM->dwAuthLevel), &(lpISAM->dwImpLevel));
  2795. if(sc == S_OK)
  2796. {
  2797. if (lpISAM->dwAuthLevel > RPC_C_AUTHN_LEVEL_NONE)
  2798. lpISAM->dwImpLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  2799. if ( lpISAM->gpAuthIdentity )
  2800. {
  2801. WbemFreeAuthIdentity( lpISAM->gpAuthIdentity );
  2802. lpISAM->gpAuthIdentity = NULL;
  2803. }
  2804. sc = ISAMSetCloaking1( pGateway,
  2805. lpISAM->fIsLocalConnection,
  2806. lpISAM->fW2KOrMore,
  2807. lpISAM->dwAuthLevel,
  2808. lpISAM->dwImpLevel,
  2809. authorityBSTR.GetString(),
  2810. userBSTR.GetString(),
  2811. passwdBSTR.GetString(),
  2812. &(lpISAM->gpAuthIdentity) );
  2813. /*
  2814. if ( fIsLocalConnection && IsW2KOrMore() )
  2815. {
  2816. WbemSetDynamicCloaking(pGateway, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
  2817. }
  2818. else
  2819. {
  2820. sc = SetInterfaceSecurityEx(pGateway, authorityBSTR.GetString(), userBSTR.GetString(), passwdBSTR.GetString(),
  2821. lpISAM->dwAuthLevel, lpISAM->dwImpLevel, EOAC_NONE, &(lpISAM->gpAuthIdentity), &gpPrincipal );
  2822. }
  2823. */
  2824. }
  2825. }
  2826. }
  2827. else
  2828. {
  2829. //We want the default database
  2830. //Get default connection from LPISAM == <root>\default
  2831. //We need to prepend server name to <root>\default
  2832. //Need to make sure everything fits in buffer size
  2833. SWORD cbRootLen = strlen ((LPSTR)lpISAM->szRootDb);
  2834. if ( (cbServerLen + cbRootLen + 9) > MAX_DATABASE_NAME_LENGTH)
  2835. {
  2836. pLocator->Release();
  2837. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 2 : Error position 3\n");
  2838. return;
  2839. }
  2840. //Construct string
  2841. CBString namespaceBSTR;
  2842. if (cbServerLen)
  2843. {
  2844. char pCharName [MAX_DATABASE_NAME_LENGTH+1];
  2845. pCharName[0] = 0;
  2846. sprintf (pCharName, "%s\\%s\\default", (LPUSTR)lpISAM->szServer, (LPSTR)lpISAM->szRootDb);
  2847. //Convert to wide string
  2848. namespaceBSTR.AddString(pCharName, FALSE);
  2849. }
  2850. else
  2851. {
  2852. if ((LPSTR)lpISAM->szRootDb)
  2853. {
  2854. char pCharName [MAX_DATABASE_NAME_LENGTH+1];
  2855. pCharName[0] = 0;
  2856. sprintf (pCharName, "%s\\default", (LPSTR)lpISAM->szRootDb);
  2857. namespaceBSTR.AddString(pCharName, FALSE);
  2858. }
  2859. }
  2860. //Convert wide characters to BSTR for DCOM
  2861. //----------------------------------------
  2862. CBString userBSTR;
  2863. if (!fIsLocalConnection)
  2864. userBSTR.AddString((LPSTR)lpISAM->szUser, FALSE);
  2865. CBString passwdBSTR;
  2866. if (!fIsLocalConnection)
  2867. passwdBSTR.AddString((LPSTR)lpISAM->szPassword, lpISAM->fIntpretEmptPwdAsBlank);
  2868. CBString localeBSTR;
  2869. CBString authorityBSTR;
  2870. //Get the local and authority fields
  2871. localeBSTR.AddString(lpISAM->m_Locale, FALSE);
  2872. authorityBSTR.AddString(lpISAM->m_Authority, FALSE);
  2873. sc = pLocator->ConnectServer (namespaceBSTR.GetString(), userBSTR.GetString(), passwdBSTR.GetString(), localeBSTR.GetString(), 0, authorityBSTR.GetString(), NULL, &pGateway);
  2874. if (sc == S_OK)
  2875. {
  2876. sc = GetAuthImp( pGateway, &(lpISAM->dwAuthLevel), &(lpISAM->dwImpLevel));
  2877. if(sc == S_OK)
  2878. {
  2879. if (lpISAM->dwAuthLevel > RPC_C_AUTHN_LEVEL_NONE)
  2880. lpISAM->dwImpLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  2881. if ( lpISAM->gpAuthIdentity )
  2882. {
  2883. WbemFreeAuthIdentity( lpISAM->gpAuthIdentity );
  2884. lpISAM->gpAuthIdentity = NULL;
  2885. }
  2886. sc = ISAMSetCloaking1( pGateway,
  2887. lpISAM->fIsLocalConnection,
  2888. lpISAM->fW2KOrMore,
  2889. lpISAM->dwAuthLevel,
  2890. lpISAM->dwImpLevel,
  2891. authorityBSTR.GetString(),
  2892. userBSTR.GetString(),
  2893. passwdBSTR.GetString(),
  2894. &(lpISAM->gpAuthIdentity) );
  2895. /*
  2896. if ( fIsLocalConnection && IsW2KOrMore() )
  2897. {
  2898. WbemSetDynamicCloaking(pGateway, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
  2899. }
  2900. else
  2901. {
  2902. sc = SetInterfaceSecurityEx(pGateway, authorityBSTR.GetString(), userBSTR.GetString(), passwdBSTR.GetString(),
  2903. lpISAM->dwAuthLevel, lpISAM->dwImpLevel, EOAC_NONE, &(lpISAM->gpAuthIdentity), &gpPrincipal);
  2904. }
  2905. */
  2906. }
  2907. }
  2908. }
  2909. //We have now finished with the locator so we can release it
  2910. pLocator->Release();
  2911. if ( FAILED(sc) )
  2912. {
  2913. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 2 : Error position 4\n");
  2914. return;
  2915. }
  2916. }
  2917. /***************************************************************************/
  2918. /* Creates a communication channel to the Gateway Server */
  2919. // Checked for SetInterfaceSecurityEx on IWbemServices
  2920. void INTFUNC ISAMGetGatewayServer(IWbemServicesPtr& pGateway,
  2921. LPUSTR lpServerName,
  2922. // WBEM_LOGIN_AUTHENTICATION loginMethod,
  2923. LPUSTR objectPath, LPUSTR lpUserName, LPUSTR lpPassword, LPUSTR lpLocale, LPUSTR lpAuthority,
  2924. DWORD &dwAuthLevel, DWORD &dwImpLevel, BOOL fIntpretEmptPwdAsBlank, COAUTHIDENTITY** ppAuthIdent)
  2925. {
  2926. ThreadLocaleIdManager myThread(lpLocale);
  2927. *ppAuthIdent = NULL;
  2928. IWbemLocator* pLocator = NULL;
  2929. SCODE sc = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER , IID_IWbemLocator, (void**) (&pLocator) );
  2930. if ( FAILED(sc) )
  2931. {
  2932. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 1 : Error position 1\n");
  2933. return;
  2934. }
  2935. pGateway = NULL;
  2936. //SAI ADDED
  2937. long refcount = 0;
  2938. //We need to prepend server name to object path
  2939. //Need to make sure everything fits in buffer size
  2940. SWORD cbServerLen = 0;
  2941. SWORD cbObjPathLen = 0;
  2942. if (lpServerName)
  2943. cbServerLen = (SWORD) _mbstrlen( (LPSTR)lpServerName);
  2944. //RAID 57673 WMI has changed such that if you
  2945. //connect locally and pass a username and password
  2946. //it will fail
  2947. //Check for local connection
  2948. BOOL fIsLocalConnection = IsLocalServer((LPSTR) lpServerName);
  2949. if (objectPath)
  2950. cbObjPathLen = strlen ( (LPSTR)objectPath);
  2951. if ( (cbServerLen + cbObjPathLen + 1) > MAX_DATABASE_NAME_LENGTH)
  2952. {
  2953. pLocator->Release();
  2954. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 1 : Error position 2\n");
  2955. return;
  2956. }
  2957. //Construct string (namespace)
  2958. CBString namespaceBSTR;
  2959. if (cbServerLen)
  2960. {
  2961. char pCharBuff [MAX_DATABASE_NAME_LENGTH + 1];
  2962. pCharBuff[0] = 0;
  2963. sprintf (pCharBuff, "%s\\%s", (LPUSTR)lpServerName, (LPSTR)objectPath);
  2964. CString myText;
  2965. myText.Format("\nWBEM ODBC Driver : Connecting using : %s\n", pCharBuff);
  2966. ODBCTRACE(myText);
  2967. //Convert to wide string
  2968. namespaceBSTR.AddString(pCharBuff, FALSE);
  2969. }
  2970. else
  2971. {
  2972. if (objectPath)
  2973. {
  2974. namespaceBSTR.AddString((LPSTR)objectPath, FALSE);
  2975. }
  2976. }
  2977. //Get user and password fields
  2978. CBString localeBSTR;
  2979. CBString authorityBSTR;
  2980. localeBSTR.AddString((char*)lpLocale, FALSE);
  2981. authorityBSTR.AddString((char*)lpAuthority, FALSE);
  2982. //Convert wide characters to BSTR for DCOM
  2983. //----------------------------------------
  2984. CBString userBSTR;
  2985. if (!fIsLocalConnection)
  2986. userBSTR.AddString((LPSTR)lpUserName, FALSE);
  2987. CBString passwdBSTR;
  2988. if (!fIsLocalConnection)
  2989. passwdBSTR.AddString((LPSTR)lpPassword, fIntpretEmptPwdAsBlank);
  2990. sc = pLocator->ConnectServer (namespaceBSTR.GetString(), userBSTR.GetString(), passwdBSTR.GetString(), localeBSTR.GetString(), 0, authorityBSTR.GetString(), NULL, &pGateway);
  2991. if (sc == S_OK)
  2992. {
  2993. sc = GetAuthImp( pGateway, &dwAuthLevel, &dwImpLevel);
  2994. if(sc == S_OK)
  2995. {
  2996. if (dwAuthLevel > RPC_C_AUTHN_LEVEL_NONE)
  2997. dwImpLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  2998. sc = ISAMSetCloaking1( pGateway,
  2999. fIsLocalConnection,
  3000. IsW2KOrMore(),
  3001. dwAuthLevel,
  3002. dwImpLevel,
  3003. authorityBSTR.GetString(),
  3004. userBSTR.GetString(),
  3005. passwdBSTR.GetString(),
  3006. ppAuthIdent );
  3007. /*
  3008. if ( fIsLocalConnection && IsW2KOrMore() )
  3009. {
  3010. WbemSetDynamicCloaking(pGateway, dwAuthLevel, dwImpLevel);
  3011. }
  3012. else
  3013. {
  3014. sc = SetInterfaceSecurityEx(pGateway, authorityBSTR.GetString(), userBSTR.GetString(), passwdBSTR.GetString(),
  3015. dwAuthLevel, dwImpLevel, EOAC_NONE, ppAuthIdent, &gpPrincipal);
  3016. }
  3017. */
  3018. }
  3019. }
  3020. pLocator->Release();
  3021. if ( FAILED(sc) )
  3022. {
  3023. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 1 : Error position 3\n");
  3024. return;
  3025. }
  3026. }
  3027. /***************************************************************************/
  3028. /* Function to fix MSQuery bug which appends */
  3029. /* a \ infront of _ characters in table names */
  3030. void ISAM_MSQueryBugFix(LPSTR lpOrigPattern, LPSTR lpNewPattern, SWORD &cbPattern)
  3031. {
  3032. SWORD iNewPatternIndex = 0;
  3033. for (SWORD iIndex = 0; iIndex < cbPattern; iIndex++)
  3034. {
  3035. //Check for '\' character follwed by a '_'
  3036. if ( (lpOrigPattern[iIndex] == '\\') && (lpOrigPattern[iIndex + 1] == '_') )
  3037. {
  3038. //Skip underscore character
  3039. iIndex++;
  3040. }
  3041. //Copy character
  3042. lpNewPattern[iNewPatternIndex++] = lpOrigPattern[iIndex];
  3043. }
  3044. //Null terminate new string
  3045. lpNewPattern[iNewPatternIndex] = 0;
  3046. //Update length of new string
  3047. cbPattern = iNewPatternIndex;
  3048. }
  3049. /***************************************************************************/
  3050. /* Stores the necessary information to obtain a list of database tables */
  3051. /* with match the search pattern */
  3052. SWORD INTFUNC ISAMGetTableList (LPISAM lpISAM, LPUSTR lpPattern, SWORD cbPattern,
  3053. LPUSTR lpQualifierName, SWORD cbQualifierName,
  3054. LPISAMTABLELIST FAR *lplpISAMTableList, BOOL fWantSysTables, BOOL fEmptyList)
  3055. {
  3056. //Local Variables
  3057. HGLOBAL h;
  3058. LPISAMTABLELIST lpISAMTableList;
  3059. lpISAM->errcode = NO_ISAM_ERR;
  3060. //Allocate memory for table list structure on the heap
  3061. h = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (ISAMTABLELIST));
  3062. if (h == NULL || (lpISAMTableList = (LPISAMTABLELIST) GlobalLock (h)) == NULL)
  3063. {
  3064. if (h)
  3065. GlobalFree(h);
  3066. lpISAM->errcode = ISAM_MEMALLOCFAIL;
  3067. return ISAM_MEMALLOCFAIL;
  3068. }
  3069. //Check table name
  3070. //There is a bug in MSQuery which appends extra \ character(s)
  3071. //to table names which have underscore(s)
  3072. //If this is the case we remove the \ character(s)
  3073. char* lpNewPattern = new char [cbPattern + 1];
  3074. ISAM_MSQueryBugFix((LPSTR)lpPattern, lpNewPattern, cbPattern);
  3075. //Copy search pattern
  3076. _fmemcpy(lpISAMTableList->lpPattern, lpNewPattern, cbPattern);
  3077. //Save search pattern length
  3078. lpISAMTableList->cbPattern = cbPattern;
  3079. //Delete tempory buffer
  3080. delete lpNewPattern;
  3081. //Copy qualifer name if it is non-null and not the default database
  3082. lpISAMTableList->lpQualifierName[0] = 0;
  3083. if (cbQualifierName)
  3084. {
  3085. strncpy((LPSTR)lpISAMTableList->lpQualifierName, (LPSTR)lpQualifierName, cbQualifierName);
  3086. }
  3087. else
  3088. {
  3089. cbQualifierName = 0;
  3090. }
  3091. lpISAMTableList->lpQualifierName[cbQualifierName] = 0;
  3092. #ifdef TESTING
  3093. //Remember to remove this printf
  3094. printf ("Qualifier = %s", (char*)lpISAMTableList->lpQualifierName );
  3095. #endif
  3096. //Is this table list going to be an empty one because
  3097. //we requested a table type other than TABLE or SYSTEM TABLE ?
  3098. lpISAMTableList->fEmptyList = fEmptyList;
  3099. //Do we want System Tables ?
  3100. lpISAMTableList->fWantSysTables = fWantSysTables;
  3101. //Save the qualifier length
  3102. lpISAMTableList->cbQualifierName = cbQualifierName;
  3103. //Save flag to indicate if this is the first time table list is accessed
  3104. lpISAMTableList->fFirstTime = TRUE;
  3105. //Save information to create a context to database
  3106. lpISAMTableList->lpISAM = lpISAM;
  3107. //Initialize pointer to enumerated list of tables
  3108. lpISAMTableList->pTblList = new CPtrList();
  3109. //Create an object to store WbemServices pointer
  3110. lpISAMTableList->pGateway2 = new CSafeWbemServices();
  3111. //Setup output parameter
  3112. *lplpISAMTableList = lpISAMTableList;
  3113. lpISAMTableList->netISAMTableList = NET_OPAQUE_INVALID;
  3114. return NO_ISAM_ERR;
  3115. }
  3116. /***************************************************************************/
  3117. /* Stores the necessary information to obtain a list of database qualifiers */
  3118. SWORD INTFUNC ISAMGetQualifierList(LPISAM lpISAM, LPISAMQUALIFIERLIST FAR *lplpISAMQualifierList)
  3119. {
  3120. //Local Variables
  3121. HGLOBAL h;
  3122. LPISAMQUALIFIERLIST lpISAMQualifierList;
  3123. lpISAM->errcode = NO_ISAM_ERR;
  3124. //Allocate memory for qualifier list structure on heap
  3125. h = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (ISAMQUALIFIERLIST));
  3126. if (h == NULL || (lpISAMQualifierList = (LPISAMQUALIFIERLIST) GlobalLock (h)) == NULL)
  3127. {
  3128. if (h)
  3129. GlobalFree(h);
  3130. lpISAM->errcode = ISAM_MEMALLOCFAIL;
  3131. return ISAM_MEMALLOCFAIL;
  3132. }
  3133. //Save flag to indicate if this is the first qualifier list is accessed
  3134. lpISAMQualifierList->fFirstTime = TRUE;
  3135. //Save information to create a context to database
  3136. lpISAMQualifierList->lpISAM = lpISAM;
  3137. //Setup output parameter
  3138. *lplpISAMQualifierList = lpISAMQualifierList;
  3139. return NO_ISAM_ERR;
  3140. }
  3141. /***************************************************************************/
  3142. /* Retrieves next table name from table list */
  3143. // Checked for SetInterfaceSecurityEx on IWbemServices
  3144. SWORD INTFUNC ISAMGetNextTableName(UDWORD fSyncMode, LPISAMTABLELIST lpISAMTableList, LPUSTR lpTableName, LPUSTR lpTableType)
  3145. {
  3146. //Initialize, no errors found yet
  3147. lpISAMTableList->lpISAM->errcode = NO_ISAM_ERR;
  3148. IWbemClassObject* pSingleTable = NULL;
  3149. BOOL fReleaseSingleTable = FALSE;
  3150. //Check if we have detacted an empty table list due
  3151. //to the fact that we requested a table type other than TABLE
  3152. if (lpISAMTableList->fEmptyList)
  3153. {
  3154. lpISAMTableList->lpISAM->errcode = ISAM_EOF;
  3155. return ISAM_EOF;
  3156. }
  3157. //We need to get the next table in the list from the LPISAMTABLELIST
  3158. //However, if this is the first time this function is called, no table list
  3159. //will be present, and we will need to get it from the Gateway Server
  3160. // First time through?
  3161. if (lpISAMTableList->fFirstTime)
  3162. {
  3163. //Clear out any old values
  3164. if (lpISAMTableList->pTblList && lpISAMTableList->pTblList->GetCount())
  3165. {
  3166. POSITION thePos = NULL;
  3167. for ( thePos = lpISAMTableList->pTblList->GetHeadPosition(); thePos != NULL; )
  3168. {
  3169. IWbemClassObject* pTheValue = (IWbemClassObject*) lpISAMTableList->pTblList->GetNext(thePos);
  3170. pTheValue->Release();
  3171. }
  3172. lpISAMTableList->pTblList->RemoveAll();
  3173. }
  3174. //Initialize
  3175. if (lpISAMTableList->pGateway2)
  3176. lpISAMTableList->pGateway2->Invalidate();
  3177. lpISAMTableList->iIndex = NULL;
  3178. lpISAMTableList->fFirstTime = FALSE;
  3179. lpISAMTableList->fGotAllInfo = FALSE;
  3180. //Get list of tables from the
  3181. //Gateway Server which match search pattern
  3182. //First get the Gateway Interface
  3183. //remember to Release it after use
  3184. lpISAMTableList->pGateway2->SetInterfacePtr
  3185. (lpISAMTableList->lpISAM, (LPUSTR)lpISAMTableList->lpQualifierName, lpISAMTableList->cbQualifierName);
  3186. //Check if a valid interface was returned
  3187. if ( ! lpISAMTableList->pGateway2->IsValid() )
  3188. {
  3189. //Could not create a Gateway Interface, return error
  3190. lpISAMTableList->lpISAM->errcode = ISAM_PROVIDERFAIL;
  3191. return ISAM_PROVIDERFAIL;
  3192. }
  3193. //First check if we need to get one table or a list of tables
  3194. //by using the pattern matcher class
  3195. if ( IsRegularExpression((char*)lpISAMTableList->lpPattern) )
  3196. {
  3197. //We want a table LIST
  3198. //We enumerate for tables, the resultant enumeration will be allocated on
  3199. //the HEAP by the Gateway Server and referneced by pEnum
  3200. BSTR emptySuperClass = SysAllocString(L"");
  3201. //Check if we want to get list asynchronously
  3202. if (fSyncMode == SQL_ASYNC_ENABLE_ON)
  3203. {
  3204. //Create notification object
  3205. CNotifyTableNames* pNotifyTable = new CNotifyTableNames(lpISAMTableList);
  3206. IWbemContext* pContext = ISAMCreateLocaleIDContextObject(lpISAMTableList->lpISAM->m_Locale);
  3207. IWbemServicesPtr myServicesPtr = NULL;
  3208. ISAMGetIWbemServices(lpISAMTableList->lpISAM, *(lpISAMTableList->pGateway2), myServicesPtr);
  3209. //cloaking
  3210. BOOL fIsLocalConnection = lpISAMTableList->lpISAM->fIsLocalConnection;
  3211. if ( fIsLocalConnection && (lpISAMTableList->lpISAM->fW2KOrMore) )
  3212. {
  3213. WbemSetDynamicCloaking(myServicesPtr, lpISAMTableList->lpISAM->dwAuthLevel, lpISAMTableList->lpISAM->dwImpLevel);
  3214. }
  3215. if ( FAILED(myServicesPtr->CreateClassEnumAsync
  3216. (_bstr_t(), WBEM_FLAG_DEEP, pContext, pNotifyTable)) )
  3217. {
  3218. //Tidy Up
  3219. lpISAMTableList->pGateway2->Invalidate();
  3220. SysFreeString(emptySuperClass);
  3221. if (pContext)
  3222. pContext->Release();
  3223. //Flag error
  3224. lpISAMTableList->lpISAM->errcode = ISAM_TABLELISTFAIL;
  3225. return ISAM_TABLELISTFAIL;
  3226. }
  3227. //Tidy Up
  3228. SysFreeString(emptySuperClass);
  3229. if (pContext)
  3230. pContext->Release();
  3231. //BREAK OUT OF THIS FUNCTION
  3232. return ISAM_STILL_EXECUTING;
  3233. }
  3234. IEnumWbemClassObjectPtr pEnum = NULL;
  3235. IWbemContext* pContext = ISAMCreateLocaleIDContextObject(lpISAMTableList->lpISAM->m_Locale);
  3236. IWbemServicesPtr myServicesPtr = NULL;
  3237. ISAMGetIWbemServices(lpISAMTableList->lpISAM, *(lpISAMTableList->pGateway2), myServicesPtr);
  3238. //cloaking
  3239. BOOL fIsLocalConnection = lpISAMTableList->lpISAM->fIsLocalConnection;
  3240. if ( fIsLocalConnection && (lpISAMTableList->lpISAM->fW2KOrMore) )
  3241. {
  3242. WbemSetDynamicCloaking(myServicesPtr, lpISAMTableList->lpISAM->dwAuthLevel, lpISAMTableList->lpISAM->dwImpLevel);
  3243. }
  3244. HRESULT hRes = myServicesPtr->CreateClassEnum
  3245. (_bstr_t(), WBEM_FLAG_DEEP, pContext, &pEnum);
  3246. if (pContext)
  3247. pContext->Release();
  3248. ISAMSetCloaking2(pEnum,
  3249. fIsLocalConnection,
  3250. lpISAMTableList->lpISAM->fW2KOrMore,
  3251. lpISAMTableList->lpISAM->dwAuthLevel,
  3252. lpISAMTableList->lpISAM->dwImpLevel,
  3253. lpISAMTableList->lpISAM->gpAuthIdentity);
  3254. /*
  3255. if ( fIsLocalConnection && (lpISAMTableList->lpISAM->fW2KOrMore) )
  3256. {
  3257. WbemSetDynamicCloaking(pEnum, lpISAMTableList->lpISAM->dwAuthLevel, lpISAMTableList->lpISAM->dwImpLevel);
  3258. }
  3259. else
  3260. {
  3261. SetInterfaceSecurityEx(pEnum, lpISAMTableList->lpISAM->gpAuthIdentity, gpPrincipal, lpISAMTableList->lpISAM->dwAuthLevel, lpISAMTableList->lpISAM->dwImpLevel);
  3262. }
  3263. */
  3264. //Tidy Up
  3265. SysFreeString(emptySuperClass);
  3266. if (FAILED(hRes))
  3267. {
  3268. //Tidy Up
  3269. lpISAMTableList->pGateway2->Invalidate();
  3270. //Flag error
  3271. lpISAMTableList->lpISAM->errcode = ISAM_TABLELISTFAIL;
  3272. return ISAM_TABLELISTFAIL;
  3273. }
  3274. //Now we have the table enumeration get the first item
  3275. ULONG puReturned;
  3276. SCODE sc1 = pEnum->Reset();
  3277. SCODE sc2 = pEnum->Next(-1, 1, &pSingleTable, &puReturned);
  3278. BOOL f1 = (S_OK == sc1) ? TRUE : FALSE;
  3279. BOOL f2 = ( S_OK == sc2) ? TRUE : FALSE;
  3280. if ( (pEnum == NULL) || (!f1) || (!f2)
  3281. )
  3282. {
  3283. //Tidy Up
  3284. lpISAMTableList->pGateway2->Invalidate();
  3285. //Flag error
  3286. lpISAMTableList->lpISAM->errcode = ISAM_EOF;
  3287. return ISAM_EOF;
  3288. }
  3289. else
  3290. {
  3291. fReleaseSingleTable = TRUE;
  3292. //Place any remaining tables in the pTblList
  3293. IWbemClassObject* pSingleTable2 = NULL;
  3294. while (S_OK == pEnum->Next(-1, 1, &pSingleTable2, &puReturned))
  3295. {
  3296. lpISAMTableList->pTblList->AddTail(pSingleTable2);
  3297. }
  3298. //Set index to correct start position for next items
  3299. lpISAMTableList->iIndex = lpISAMTableList->pTblList->GetHeadPosition();
  3300. }
  3301. }
  3302. else
  3303. {
  3304. //We want a SINGLE table
  3305. //Set this flag in case you are asynchronously requesting
  3306. //for 1 table !!!
  3307. lpISAMTableList->fGotAllInfo = TRUE;
  3308. //Create a pointer to store table class definition
  3309. //the class definition object will be CREATED on the HEAP
  3310. //by the GetClass function
  3311. pSingleTable = NULL;
  3312. LONG cLength = lstrlen((char*)lpISAMTableList->lpPattern);
  3313. wchar_t* pWClassName = new wchar_t [cLength + 1];
  3314. pWClassName[0] = 0;
  3315. int iItemsCopied = mbstowcs(pWClassName, (char*)lpISAMTableList->lpPattern, cLength);
  3316. pWClassName[cLength] = 0;
  3317. BSTR pTheTableName = SysAllocStringLen(pWClassName, cLength);
  3318. IWbemContext* pContext = ISAMCreateLocaleIDContextObject(lpISAMTableList->lpISAM->m_Locale);
  3319. IWbemServicesPtr myServicesPtr = NULL;
  3320. ISAMGetIWbemServices(lpISAMTableList->lpISAM, *(lpISAMTableList->pGateway2), myServicesPtr);
  3321. SCODE sStatus = myServicesPtr->GetObject(pTheTableName, 0, pContext, &pSingleTable, NULL);
  3322. if (pContext)
  3323. pContext->Release();
  3324. fReleaseSingleTable = TRUE;
  3325. SysFreeString(pTheTableName);
  3326. delete pWClassName;
  3327. if ( FAILED(sStatus) || (!pSingleTable) )
  3328. {
  3329. //Failed to get named class definition
  3330. //Tidy Up
  3331. lpISAMTableList->pGateway2->Invalidate();
  3332. //Flag error
  3333. lpISAMTableList->lpISAM->errcode = ISAM_EOF;
  3334. return ISAM_EOF;
  3335. }
  3336. }
  3337. }
  3338. else
  3339. {
  3340. //Get next item in enumeration if applicable
  3341. //Check if function is asynchronous, if so
  3342. //we must first check the fGotAllInfo flag
  3343. //if we have all the info we can get the next table
  3344. //we assign the pSingleTable pointer
  3345. if ( (fSyncMode == SQL_ASYNC_ENABLE_ON) && (!lpISAMTableList->fGotAllInfo) )
  3346. return ISAM_STILL_EXECUTING;
  3347. //Get Next
  3348. if (lpISAMTableList->iIndex)
  3349. {
  3350. pSingleTable = (IWbemClassObject*)lpISAMTableList->pTblList->GetNext(lpISAMTableList->iIndex);
  3351. }
  3352. else
  3353. {
  3354. lpISAMTableList->lpISAM->errcode = ISAM_EOF;
  3355. return ISAM_EOF;
  3356. }
  3357. }
  3358. //Now we have the class definition object
  3359. //for the next table let us get table name
  3360. SWORD sc = S_OK; // ISAMGetNextTableName2(pSingleTable, fSyncMode, lpISAMTableList,lpTableName);
  3361. //Because of stack overflow problems I have moved the
  3362. //ISAMGetNextTableName2 code here
  3363. BOOL fMatchingPattern = FALSE;
  3364. do
  3365. {
  3366. //Now we have the class definition object
  3367. //The table name is held in the property attribute __CLASS
  3368. VARIANT grVariant;
  3369. BSTR classBSTR = SysAllocString(WBEMDR32_L_CLASS);
  3370. if (FAILED(pSingleTable->Get(classBSTR, 0, &grVariant, NULL, NULL)))
  3371. {
  3372. lpISAMTableList->lpISAM->errcode = ISAM_TABLENAMEFAIL;
  3373. SysFreeString(classBSTR);
  3374. sc = ISAM_TABLENAMEFAIL;
  3375. }
  3376. else
  3377. {
  3378. SysFreeString(classBSTR);
  3379. /* Does this filename match the pattern? */
  3380. char pBuffer [MAX_TABLE_NAME_LENGTH+1];
  3381. pBuffer[0] = 0;
  3382. wcstombs(pBuffer, grVariant.bstrVal, MAX_TABLE_NAME_LENGTH);
  3383. pBuffer[MAX_TABLE_NAME_LENGTH] = 0;
  3384. //Also do not add any class which starts with __ to table list
  3385. //If you don't want SYSTEM TABLES
  3386. if ( !PatternMatch(TRUE, (LPUSTR) pBuffer, SQL_NTS,
  3387. (LPUSTR)lpISAMTableList->lpPattern, lpISAMTableList->cbPattern,
  3388. ISAMCaseSensitive(lpISAMTableList->lpISAM)) || (!(lpISAMTableList->fWantSysTables) && !_strnicmp("__", pBuffer, 2)) )
  3389. {
  3390. /* No. Get the next one */
  3391. VariantClear(&grVariant);
  3392. //Get the next table here
  3393. if (lpISAMTableList->iIndex)
  3394. {
  3395. if (fReleaseSingleTable)
  3396. pSingleTable->Release();
  3397. pSingleTable = NULL;
  3398. fReleaseSingleTable = FALSE;
  3399. pSingleTable = (IWbemClassObject*)lpISAMTableList->pTblList->GetNext(lpISAMTableList->iIndex);
  3400. }
  3401. else
  3402. {
  3403. lpISAMTableList->lpISAM->errcode = ISAM_EOF;
  3404. return ISAM_EOF;
  3405. }
  3406. }
  3407. else
  3408. {
  3409. /* Return the name found */
  3410. lpTableName[0] = 0;
  3411. //RAID 42256
  3412. char* pTemp = (char*) lpTableName;
  3413. _bstr_t myValue((BSTR)grVariant.bstrVal);
  3414. Utility_WideCharToDBCS(myValue, &pTemp, MAX_TABLE_NAME_LENGTH);
  3415. lpTableName[MAX_TABLE_NAME_LENGTH] = 0;
  3416. VariantClear(&grVariant);
  3417. fMatchingPattern = TRUE; //to break out of loop
  3418. sc = NO_ISAM_ERR;
  3419. }
  3420. }
  3421. } while (!fMatchingPattern);
  3422. //Setup table type, either SYSTEM TABLE or TABLE
  3423. if (sc == NO_ISAM_ERR)
  3424. {
  3425. lpTableType[0] = 0;
  3426. if (lpTableName && strlen((LPSTR)lpTableName) && (_strnicmp("__", (LPSTR)lpTableName, 2) == 0))
  3427. {
  3428. s_lstrcpy(lpTableType, "SYSTEM TABLE");
  3429. }
  3430. else
  3431. {
  3432. s_lstrcpy(lpTableType, "TABLE");
  3433. }
  3434. }
  3435. //We have finished with interfaces
  3436. //so release them
  3437. if (fReleaseSingleTable)
  3438. pSingleTable->Release();
  3439. return sc;
  3440. }
  3441. /***************************************************************************/
  3442. /* Retrieves next qualifier name from qualifier list */
  3443. SWORD INTFUNC ISAMGetNextQualifierName(UDWORD fSyncMode, LPISAMQUALIFIERLIST lpISAMQualifierList,
  3444. LPUSTR lpQualifierName)
  3445. {
  3446. //Initialize, no errors found yet
  3447. lpISAMQualifierList->lpISAM->errcode = NO_ISAM_ERR;
  3448. //We need to get the next qualifier in the list from the LPISAMQUALIFIERLIST
  3449. //However, if this is the first time this function is called, no qualifier list
  3450. //will be present, and we will need to get it
  3451. // First time through?
  3452. if (lpISAMQualifierList->fFirstTime)
  3453. {
  3454. //Initialize
  3455. lpISAMQualifierList->iIndex = NULL;
  3456. lpISAMQualifierList->fFirstTime = FALSE;
  3457. //Get list of qualifiers from the
  3458. //Gateway Server, this maps to getting a list
  3459. //of namespaces. However, this list is already held in the
  3460. //ISAM structure, so we simply extract from there
  3461. //All we need to do is setup the correct position within the list
  3462. //Setup first position in qualifier list
  3463. lpISAMQualifierList->iIndex = lpISAMQualifierList->lpISAM->pNamespaceMap->GetStartPosition();
  3464. }
  3465. //Get the next qualifier (namespace)
  3466. return ISAMGetNextQualifierName2(lpISAMQualifierList, lpQualifierName);
  3467. }
  3468. /***************************************************************************/
  3469. /* This is the second phase of getting the next qualifier name */
  3470. /* This function is called when we have got all the information back */
  3471. /* from the MO Server */
  3472. SWORD INTFUNC ISAMGetNextQualifierName2(LPISAMQUALIFIERLIST lpISAMQualifierList, LPUSTR lpQualifierName)
  3473. {
  3474. //Now we have the namespace list, we need to get the 'iIndex' item for the next qualifier
  3475. //If the 'iIndex' item is NULL we have reached the end of the list
  3476. CString key;
  3477. CNamespace* pN;
  3478. CString pStr;
  3479. if (lpISAMQualifierList->iIndex)
  3480. {
  3481. lpISAMQualifierList->lpISAM->pNamespaceMap->GetNextAssoc(lpISAMQualifierList->iIndex, key, (CObject* &)pN);
  3482. pStr = pN->GetName();
  3483. }
  3484. else
  3485. {
  3486. lpISAMQualifierList->lpISAM->errcode = ISAM_EOF;
  3487. return ISAM_EOF;
  3488. }
  3489. //Return Qualifier name
  3490. lpQualifierName[0] = 0;
  3491. s_lstrcpy (lpQualifierName, pStr);
  3492. return NO_ISAM_ERR;
  3493. }
  3494. /***************************************************************************/
  3495. /* Frees the table list stored in the LPISAMTABLELIST structure */
  3496. SWORD INTFUNC ISAMFreeTableList(LPISAMTABLELIST lpISAMTableList)
  3497. {
  3498. lpISAMTableList->lpISAM->errcode = NO_ISAM_ERR;
  3499. if (lpISAMTableList->pTblList)
  3500. {
  3501. if (lpISAMTableList->pTblList->GetCount())
  3502. {
  3503. POSITION thePos = NULL;
  3504. for ( thePos = lpISAMTableList->pTblList->GetHeadPosition(); thePos != NULL; )
  3505. {
  3506. IWbemClassObject* pTheValue = (IWbemClassObject*) lpISAMTableList->pTblList->GetNext(thePos);
  3507. pTheValue->Release();
  3508. }
  3509. lpISAMTableList->pTblList->RemoveAll();
  3510. }
  3511. delete lpISAMTableList->pTblList;
  3512. lpISAMTableList->pTblList = NULL;
  3513. }
  3514. if (lpISAMTableList->pGateway2)
  3515. {
  3516. delete lpISAMTableList->pGateway2;
  3517. lpISAMTableList->pGateway2 = NULL;
  3518. }
  3519. GlobalUnlock (GlobalPtrHandle(lpISAMTableList));
  3520. GlobalFree (GlobalPtrHandle(lpISAMTableList));
  3521. return NO_ISAM_ERR;
  3522. }
  3523. /***************************************************************************/
  3524. /* Frees the qualifier list stored in the LPISAMQUALIFIERLIST structure */
  3525. SWORD INTFUNC ISAMFreeQualifierList(LPISAMQUALIFIERLIST lpISAMQualifierList)
  3526. {
  3527. lpISAMQualifierList->lpISAM->errcode = NO_ISAM_ERR;
  3528. //Initialize
  3529. lpISAMQualifierList->iIndex = NULL;
  3530. GlobalUnlock (GlobalPtrHandle(lpISAMQualifierList));
  3531. GlobalFree (GlobalPtrHandle(lpISAMQualifierList));
  3532. return NO_ISAM_ERR;
  3533. }
  3534. /***************************************************************************/
  3535. SWORD INTFUNC ISAMForeignKey(LPISAM lpISAM, LPUSTR lpszPrimaryKeyTableName,
  3536. LPUSTR lpszForeignKeyTableName, LPUSTR lpPrimaryKeyName,
  3537. LPUSTR lpForeignKeyName, SWORD FAR *lpfUpdateRule,
  3538. SWORD FAR *lpfDeleteRule, UWORD FAR *lpcISAMKeyColumnList,
  3539. LPISAMKEYCOLUMNNAME ISAMPrimaryKeyColumnList,
  3540. LPISAMKEYCOLUMNNAME ISAMForeignKeyColumnList)
  3541. {
  3542. /* Never any foreign keys */
  3543. return ISAM_EOF;
  3544. }
  3545. /***************************************************************************/
  3546. SWORD INTFUNC ISAMCreateTable(LPISAM lpISAM, LPUSTR lpszTableName,
  3547. LPISAMTABLEDEF FAR *lplpISAMTableDef)
  3548. {
  3549. return ISAM_NOTSUPPORTED;
  3550. }
  3551. /***************************************************************************/
  3552. SWORD INTFUNC ISAMAddColumn(LPISAMTABLEDEF lpISAMTableDef, LPUSTR lpszColumnName,
  3553. UWORD iSqlType, UDWORD udParam1, UDWORD udParam2)
  3554. {
  3555. return ISAM_NOTSUPPORTED;
  3556. }
  3557. /***************************************************************************/
  3558. SWORD INTFUNC ISAMCreateIndex(LPISAMTABLEDEF lpISAMTableDef,
  3559. LPUSTR lpszIndexName, BOOL fUnique, UWORD count,
  3560. UWORD FAR *icol, BOOL FAR *fDescending)
  3561. {
  3562. return ISAM_NOTSUPPORTED;
  3563. }
  3564. /***************************************************************************/
  3565. SWORD INTFUNC ISAMDeleteIndex(LPISAM lpISAM, LPUSTR lpszIndexName)
  3566. {
  3567. return ISAM_NOTSUPPORTED;
  3568. }
  3569. /***************************************************************************/
  3570. /* Opens a specific table and produces a table definition to clearly define the table structure */
  3571. // Checked for SetInterfaceSecurityEx on IWbemServices
  3572. SWORD INTFUNC ISAMOpenTable(LPISAM lpISAM, LPUSTR szTableQualifier, SWORD cbTableQualifier,
  3573. LPUSTR lpszTableName, BOOL fReadOnly,
  3574. LPISAMTABLEDEF FAR *lplpISAMTableDef, LPSTMT lpstmt)
  3575. {
  3576. HGLOBAL h;
  3577. LPISAMTABLEDEF lpISAMTableDef;
  3578. LPDBASEFILE lpFile;
  3579. /* Opening the passthrough SQL result set? */
  3580. lpISAM->errcode = NO_ISAM_ERR;
  3581. //Create a pointer to store table class definition
  3582. //the class definition object will be CREATED on the HEAP
  3583. //by the GetClass function or left a NULL pointer
  3584. IWbemClassObject* pSingleTable = NULL;
  3585. //Allocate memory for DBASEFILE
  3586. h = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (DBASEFILE));
  3587. if (h == NULL || (lpFile = (LPDBASEFILE) GlobalLock (h)) == NULL)
  3588. {
  3589. if (h)
  3590. GlobalFree(h);
  3591. lpISAM->errcode = ISAM_MEMALLOCFAIL;
  3592. return ISAM_MEMALLOCFAIL;
  3593. }
  3594. //Allocate memory for TABLEDEF
  3595. h = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (ISAMTABLEDEF));
  3596. if (h == NULL || (lpISAMTableDef = (LPISAMTABLEDEF) GlobalLock (h)) == NULL)
  3597. {
  3598. if (h)
  3599. GlobalFree(h);
  3600. if (lpFile)
  3601. {
  3602. GlobalUnlock(GlobalPtrHandle(lpFile));
  3603. GlobalFree(GlobalPtrHandle(lpFile));
  3604. lpFile = NULL;
  3605. }
  3606. lpISAM->errcode = ISAM_MEMALLOCFAIL;
  3607. return ISAM_MEMALLOCFAIL;
  3608. }
  3609. //Initialize
  3610. lpFile->tempEnum = new CSafeIEnumWbemClassObject();
  3611. lpISAMTableDef->pGateway2 = new CSafeWbemServices();
  3612. lpISAMTableDef->pBStrTableName = NULL;
  3613. lpISAMTableDef->pSingleTable = NULL;
  3614. lpISAMTableDef->pColumnInfo = NULL;
  3615. lpISAMTableDef->passthroughMap = NULL;
  3616. lpISAMTableDef->firstPassthrInst = NULL;
  3617. lpISAMTableDef->virtualInstances = new VirtualInstanceManager();
  3618. //Check if PassthroughSQL
  3619. BOOL fIsPassthroughSQL = FALSE;
  3620. char* virTbl = WBEMDR32_VIRTUAL_TABLE2;
  3621. if (lpstmt && (s_lstrcmp(lpszTableName, virTbl) == 0))
  3622. {
  3623. fIsPassthroughSQL = TRUE;
  3624. }
  3625. lpISAMTableDef->fIsPassthroughSQL = fIsPassthroughSQL;
  3626. // if (s_lstrcmpi(lpszTableName, WBEMDR32_VIRTUAL_TABLE))
  3627. {
  3628. //Ignore below statement
  3629. /* NO, not passthough */
  3630. //First get the Gateway Interface
  3631. //remember to Release it after use
  3632. if (fIsPassthroughSQL)
  3633. {
  3634. lpISAMTableDef->pGateway2->Transfer(*(lpstmt->lpISAMStatement->pProv));
  3635. lpISAMTableDef->passthroughMap = lpstmt->lpISAMStatement->passthroughMap;
  3636. lpstmt->lpISAMStatement->passthroughMap = NULL;
  3637. lpISAMTableDef->firstPassthrInst= lpstmt->lpISAMStatement->firstPassthrInst;
  3638. lpstmt->lpISAMStatement->firstPassthrInst = NULL;
  3639. }
  3640. else
  3641. {
  3642. lpISAMTableDef->pGateway2->SetInterfacePtr( lpISAM, szTableQualifier, cbTableQualifier);
  3643. }
  3644. //Check if a valid interface was returned
  3645. if ( ! lpISAMTableDef->pGateway2->IsValid() )
  3646. {
  3647. //Could not create a Gateway Interface, return error
  3648. if (lpFile)
  3649. {
  3650. if (lpFile->tempEnum)
  3651. {
  3652. delete lpFile->tempEnum;
  3653. lpFile->tempEnum = NULL;
  3654. }
  3655. GlobalUnlock(GlobalPtrHandle(lpFile));
  3656. GlobalFree(GlobalPtrHandle(lpFile));
  3657. lpFile = NULL;
  3658. }
  3659. if (lpISAMTableDef->virtualInstances)
  3660. {
  3661. delete (lpISAMTableDef->virtualInstances);
  3662. lpISAMTableDef->virtualInstances = NULL;
  3663. }
  3664. if (lpISAMTableDef->pBStrTableName)
  3665. {
  3666. delete lpISAMTableDef->pBStrTableName;
  3667. lpISAMTableDef->pBStrTableName = NULL;
  3668. }
  3669. if (lpISAMTableDef->pGateway2)
  3670. {
  3671. delete lpISAMTableDef->pGateway2;
  3672. lpISAMTableDef->pGateway2 = NULL;
  3673. }
  3674. if (lpISAMTableDef)
  3675. {
  3676. GlobalUnlock(GlobalPtrHandle(lpISAMTableDef));
  3677. GlobalFree(GlobalPtrHandle(lpISAMTableDef));
  3678. lpISAMTableDef = NULL;
  3679. }
  3680. lpISAM->errcode = ISAM_PROVIDERFAIL;
  3681. return ISAM_PROVIDERFAIL;
  3682. }
  3683. lpISAMTableDef->pBStrTableName = new CBString();
  3684. lpISAMTableDef->pBStrTableName->AddString((LPSTR)lpszTableName, FALSE);
  3685. //Get the class definition
  3686. if (fIsPassthroughSQL)
  3687. {
  3688. //Get class definition from lpstmt
  3689. pSingleTable = lpstmt->lpISAMStatement->classDef;
  3690. lpstmt->lpISAMStatement->classDef = NULL;
  3691. }
  3692. else
  3693. {
  3694. IWbemServicesPtr myServicesPtr = NULL;
  3695. ISAMGetIWbemServices(lpISAM, *(lpISAMTableDef->pGateway2), myServicesPtr);
  3696. if ( FAILED(myServicesPtr->GetObject(lpISAMTableDef->pBStrTableName->GetString(), 0, lpISAMTableDef->pContext, &pSingleTable, NULL)) )
  3697. {
  3698. //Failed to get named class definition
  3699. if (lpFile)
  3700. {
  3701. if (lpFile->tempEnum)
  3702. {
  3703. delete lpFile->tempEnum;
  3704. lpFile->tempEnum = NULL;
  3705. }
  3706. GlobalUnlock(GlobalPtrHandle(lpFile));
  3707. GlobalFree(GlobalPtrHandle(lpFile));
  3708. lpFile = NULL;
  3709. }
  3710. if (lpISAMTableDef->virtualInstances)
  3711. {
  3712. delete (lpISAMTableDef->virtualInstances);
  3713. lpISAMTableDef->virtualInstances = NULL;
  3714. }
  3715. if (lpISAMTableDef->pBStrTableName)
  3716. {
  3717. delete lpISAMTableDef->pBStrTableName;
  3718. lpISAMTableDef->pBStrTableName = NULL;
  3719. }
  3720. if (lpISAMTableDef->pGateway2)
  3721. {
  3722. delete lpISAMTableDef->pGateway2;
  3723. lpISAMTableDef->pGateway2 = NULL;
  3724. }
  3725. if (lpISAMTableDef)
  3726. {
  3727. GlobalUnlock(GlobalPtrHandle(lpISAMTableDef));
  3728. GlobalFree(GlobalPtrHandle(lpISAMTableDef));
  3729. lpISAMTableDef = NULL;
  3730. }
  3731. lpISAM->errcode = ISAM_TABLEFAIL;
  3732. return ISAM_TABLEFAIL;
  3733. }
  3734. }
  3735. }
  3736. /* Fill in table definition */
  3737. lpISAMTableDef->szTableName[0] = 0;
  3738. s_lstrcpy(lpISAMTableDef->szTableName, lpszTableName);
  3739. s_lstrcpy(lpISAMTableDef->szPrimaryKeyName, "");
  3740. lpISAMTableDef->lpISAM = lpISAM;
  3741. lpISAMTableDef->lpFile = lpFile;
  3742. lpISAMTableDef->fFirstRead = TRUE;
  3743. lpISAMTableDef->iRecord = -1;
  3744. if (lpFile)
  3745. {
  3746. lpISAMTableDef->lpFile->sortArray = NULL;
  3747. if (fIsPassthroughSQL)
  3748. {
  3749. lpISAMTableDef->lpFile->pAllRecords = new CMapWordToPtr();
  3750. lpISAMTableDef->lpFile->fMoreToCome = TRUE; //more instances need to be fetched (none fetched so far)
  3751. if (lpISAMTableDef->lpFile->tempEnum)
  3752. delete (lpISAMTableDef->lpFile->tempEnum);
  3753. lpISAMTableDef->lpFile->tempEnum = lpstmt->lpISAMStatement->tempEnum;
  3754. lpstmt->lpISAMStatement->tempEnum = NULL; //SAI NEW to avoid enumeration being deleted in ISAMFreeStatement
  3755. }
  3756. else
  3757. {
  3758. lpISAMTableDef->lpFile->pAllRecords = new CMapWordToPtr();
  3759. delete lpISAMTableDef->lpFile->tempEnum;
  3760. lpISAMTableDef->lpFile->tempEnum = new CSafeIEnumWbemClassObject();
  3761. lpISAMTableDef->lpFile->fMoreToCome = FALSE; //not used but set it with a value anyway
  3762. }
  3763. lpISAMTableDef->lpFile->record = NULL;
  3764. }
  3765. lpISAMTableDef->netISAMTableDef = NET_OPAQUE_INVALID;
  3766. lpISAMTableDef->hPreFetchedValues = NULL;
  3767. lpISAMTableDef->cbBookmark = 0;
  3768. lpISAMTableDef->bookmark.currentRecord = 0;
  3769. lpISAMTableDef->bookmark.currentInstance = 0;
  3770. //this is 8 - see assinment above
  3771. lpISAMTableDef->pSingleTable = pSingleTable; //Contains class info
  3772. //We must indicate to the class below how to parse the information
  3773. //Ther unique case is when we do passthrough for multi-tables
  3774. //and we get a __Generic class
  3775. //We check for this
  3776. BOOL fIs__Generic = FALSE;
  3777. if (fIsPassthroughSQL)
  3778. {
  3779. //Extract class name from class definition
  3780. //The table name is held in the property attribute __CLASS
  3781. VARIANT grVariant;
  3782. BSTR classBSTR = SysAllocString(WBEMDR32_L_CLASS);
  3783. if (FAILED(pSingleTable->Get(classBSTR, 0, &grVariant, NULL, NULL)))
  3784. {
  3785. //SAI ADDED - Failed should we also
  3786. //free pSingleTable ?
  3787. lpISAM->errcode = ISAM_NOTSUPPORTED;
  3788. SysFreeString(classBSTR);
  3789. if (lpFile)
  3790. {
  3791. if (lpFile->tempEnum)
  3792. {
  3793. delete lpFile->tempEnum;
  3794. lpFile->tempEnum = NULL;
  3795. }
  3796. GlobalUnlock(GlobalPtrHandle(lpFile));
  3797. GlobalFree(GlobalPtrHandle(lpFile));
  3798. lpFile = NULL;
  3799. }
  3800. if (lpISAMTableDef->virtualInstances)
  3801. {
  3802. delete (lpISAMTableDef->virtualInstances);
  3803. lpISAMTableDef->virtualInstances = NULL;
  3804. }
  3805. if (lpISAMTableDef->pBStrTableName)
  3806. {
  3807. delete lpISAMTableDef->pBStrTableName;
  3808. lpISAMTableDef->pBStrTableName = NULL;
  3809. }
  3810. if (lpISAMTableDef->pGateway2)
  3811. {
  3812. delete lpISAMTableDef->pGateway2;
  3813. lpISAMTableDef->pGateway2 = NULL;
  3814. }
  3815. if (lpISAMTableDef->pSingleTable)
  3816. {
  3817. lpISAMTableDef->pSingleTable->Release();
  3818. lpISAMTableDef->pSingleTable = NULL;
  3819. }
  3820. if (lpISAMTableDef)
  3821. {
  3822. GlobalUnlock(GlobalPtrHandle(lpISAMTableDef));
  3823. GlobalFree(GlobalPtrHandle(lpISAMTableDef));
  3824. lpISAMTableDef = NULL;
  3825. }
  3826. return ISAM_NOTSUPPORTED;
  3827. }
  3828. SysFreeString(classBSTR);
  3829. //Compare with __Generic
  3830. if (_wcsicmp(grVariant.bstrVal, L"__Generic") == 0)
  3831. {
  3832. fIs__Generic = TRUE;
  3833. }
  3834. }
  3835. lpISAMTableDef->fIs__Generic = fIs__Generic;
  3836. ClassColumnInfoBase* tempInfo = new ClassColumnInfoBase(lpISAMTableDef,lpISAMTableDef->fIs__Generic);
  3837. lpISAMTableDef->pColumnInfo = tempInfo;
  3838. //DCR 29279
  3839. //Add LocaleID context object
  3840. lpISAMTableDef->pContext = NULL;
  3841. ISAMAddLocaleIDContextObject(lpISAMTableDef, lpISAMTableDef->lpISAM);
  3842. *lplpISAMTableDef = lpISAMTableDef;
  3843. return NO_ISAM_ERR;
  3844. }
  3845. IWbemContext* ISAMCreateLocaleIDContextObject(char* lpLocale)
  3846. {
  3847. IWbemContext* pContext = NULL;
  3848. if (!lpLocale)
  3849. return NULL;
  3850. if (!lstrlen(lpLocale))
  3851. return NULL;
  3852. //First get the context interface
  3853. //===============================
  3854. SCODE sc = CoCreateInstance(CLSID_WbemContext, NULL, CLSCTX_INPROC_SERVER , IID_IWbemContext, (void**) ( &pContext ) );
  3855. if ( FAILED(sc) )
  3856. {
  3857. ODBCTRACE("WBEM ODBC DRIVER : Failed to create context object for LocaleId");
  3858. return NULL;
  3859. }
  3860. //Now add the locale value
  3861. _bstr_t myLocaleParm ("LocaleID");
  3862. _variant_t myLocaleVal(lpLocale);
  3863. sc = pContext->SetValue(myLocaleParm, 0, &myLocaleVal);
  3864. if ( FAILED(sc) )
  3865. {
  3866. ODBCTRACE("WBEM ODBC DRIVER : Failed to set LocaleId in context object");
  3867. return NULL;
  3868. }
  3869. return pContext;
  3870. }
  3871. void ISAMAddLocaleIDContextObject(LPISAMTABLEDEF lpISAMTableDef, LPISAM lpISAM)
  3872. {
  3873. //add locale id to context object
  3874. lpISAMTableDef->pContext = ISAMCreateLocaleIDContextObject(lpISAM->m_Locale);
  3875. }
  3876. /***************************************************************************/
  3877. SWORD INTFUNC ISAMRewind(LPISAMTABLEDEF lpISAMTableDef)
  3878. {
  3879. lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
  3880. lpISAMTableDef->fFirstRead = TRUE;
  3881. lpISAMTableDef->iRecord = -1;
  3882. return NO_ISAM_ERR;
  3883. }
  3884. /***************************************************************************/
  3885. SWORD INTFUNC ISAMSort(LPISAMTABLEDEF lpISAMTableDef,
  3886. UWORD count,
  3887. UWORD FAR * icol,
  3888. BOOL FAR * fDescending)
  3889. {
  3890. if (count)
  3891. {
  3892. lpISAMTableDef->lpISAM->errcode = ISAM_NOTSUPPORTED;
  3893. return ISAM_NOTSUPPORTED;
  3894. }
  3895. lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
  3896. return NO_ISAM_ERR;
  3897. }
  3898. /***************************************************************************/
  3899. SWORD INTFUNC ISAMRestrict(LPISAMTABLEDEF lpISAMTableDef,
  3900. UWORD count,
  3901. UWORD FAR * icol,
  3902. UWORD FAR * fOperator,
  3903. SWORD FAR * fCType,
  3904. PTR FAR * rgbValue,
  3905. SDWORD FAR * cbValue)
  3906. {
  3907. /* Note: Indexes are not used in this implementation, so this */
  3908. /* restriction is ignored. */
  3909. lpISAMTableDef->lpISAM->errcode = ISAM_NOTSUPPORTED;
  3910. return ISAM_NOTSUPPORTED;
  3911. }
  3912. // Checked for SetInterfaceSecurityEx on IWbemServices
  3913. void ISAMPatchUpGatewaySecurity(LPISAM lpISAM, IWbemServices* myServicesPtr)
  3914. {
  3915. SCODE sc = GetAuthImp( myServicesPtr, &(lpISAM->dwAuthLevel), &(lpISAM->dwImpLevel));
  3916. if(sc == S_OK)
  3917. {
  3918. if (lpISAM->dwAuthLevel > RPC_C_AUTHN_LEVEL_NONE)
  3919. lpISAM->dwImpLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  3920. // CBString myServerStr;
  3921. // myServerStr.AddString( (LPSTR)lpISAM->szServer, FALSE );
  3922. // CServerLocationCheck myCheck (myServerStr);
  3923. BOOL fIsLocalConnection = lpISAM->fIsLocalConnection;//myCheck.IsLocal();
  3924. sc = ISAMSetCloaking2(myServicesPtr,
  3925. fIsLocalConnection,
  3926. lpISAM->fW2KOrMore,
  3927. lpISAM->dwAuthLevel,
  3928. lpISAM->dwImpLevel,
  3929. lpISAM->gpAuthIdentity);
  3930. /*
  3931. if ( fIsLocalConnection && (lpISAM->fW2KOrMore) )
  3932. {
  3933. sc = WbemSetDynamicCloaking(myServicesPtr, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
  3934. }
  3935. else
  3936. {
  3937. sc = SetInterfaceSecurityEx(myServicesPtr, lpISAM->gpAuthIdentity, gpPrincipal, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
  3938. }
  3939. */
  3940. }
  3941. }
  3942. /***************************************************************************/
  3943. #define WBEMDR32_ELEMENTS_TO_READ 1000
  3944. /* retrieves the next record from the selected table */
  3945. // Checked for SetInterfaceSecurityEx on IWbemServices and IEnumWbemClassObject
  3946. SWORD INTFUNC ISAMNextRecord(LPISAMTABLEDEF lpISAMTableDef, LPSTMT lpstmt)
  3947. {
  3948. ODBCTRACE("\nWBEM ODBC Driver : ISAMNextRecord\n");
  3949. SWORD err = DBASE_ERR_SUCCESS;
  3950. // Move to the next record
  3951. lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
  3952. if (lpISAMTableDef->lpFile != NULL)
  3953. {
  3954. if (lpISAMTableDef->fFirstRead)
  3955. {
  3956. //copy table name
  3957. char pTableName [MAX_TABLE_NAME_LENGTH+1];
  3958. pTableName[0] = 0;
  3959. wcstombs(pTableName, lpISAMTableDef->pBStrTableName->GetString(), MAX_TABLE_NAME_LENGTH);
  3960. pTableName[MAX_TABLE_NAME_LENGTH] = 0;
  3961. //Get enumeration of all instances of current class
  3962. //First check if this table has been RESET
  3963. SCODE sc;
  3964. if (lpISAMTableDef->lpFile->tempEnum->IsValid())
  3965. {
  3966. //Yes, reuse old enumeration
  3967. //Passthrough SQL will always go here !!!
  3968. sc = S_OK;
  3969. }
  3970. else
  3971. {
  3972. //no old enumeration, so create one
  3973. lpISAMTableDef->lpFile->tempEnum->Invalidate();
  3974. //before getting enumeration check if we can perform
  3975. //some optimization by converting to an WBEM Level 1 query
  3976. //base on a single table
  3977. LPSQLNODE lpRootNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
  3978. LPSQLNODE lpSqlNode2 = ToNode(lpstmt->lpSqlStmt, lpRootNode->node.root.sql);
  3979. char* buffer = NULL;
  3980. BOOL fOptimization = FALSE;
  3981. //Check if WBEM Level 1 optimization is enabled
  3982. if (lpISAMTableDef->lpISAM->fOptimization)
  3983. {
  3984. if ( lpSqlNode2->node.select.Predicate != NO_SQLNODE)
  3985. {
  3986. LPSQLNODE lpPredicateNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode2->node.select.Predicate);
  3987. PredicateParser theParser (&lpRootNode, lpISAMTableDef);
  3988. theParser.GeneratePredicateString(lpPredicateNode, &buffer);
  3989. }
  3990. }
  3991. //Sai Wong
  3992. // if (buffer && lstrlen(buffer))
  3993. {
  3994. //Get select list
  3995. char* selectStr = NULL;
  3996. TableColumnInfo selectInfo (&lpRootNode, &lpSqlNode2);
  3997. lpISAMTableDef->passthroughMap = NULL;
  3998. selectInfo.BuildSelectList(lpISAMTableDef, &selectStr, TRUE, &(lpISAMTableDef->passthroughMap));
  3999. if (selectStr)
  4000. {
  4001. fOptimization = TRUE;
  4002. _bstr_t sqltextBSTR = L"SELECT ";
  4003. _bstr_t sqltextBSTR2;
  4004. sqltextBSTR += selectStr;
  4005. sqltextBSTR += L" FROM ";
  4006. sqltextBSTR += pTableName;
  4007. //Is there a WHERE statement ?
  4008. if (buffer && lstrlen(buffer))
  4009. {
  4010. //RAID 29811
  4011. //If this query contains a JOIN do not add in the WHERE predicate
  4012. //so we do the ON and WHERE in the correct order
  4013. //Get the table list first to find out if we are
  4014. //SQL-89 or SQL-92
  4015. char* checkTableList = NULL;
  4016. BOOL fIsSQL89 = TRUE;
  4017. selectInfo.BuildTableList(&checkTableList, fIsSQL89);
  4018. delete checkTableList;
  4019. if (fIsSQL89)
  4020. {
  4021. sqltextBSTR2 = sqltextBSTR; //make copy of this
  4022. sqltextBSTR += L" WHERE ";
  4023. sqltextBSTR += buffer;
  4024. }
  4025. }
  4026. sc = lpISAMTableDef->lpFile->tempEnum->SetInterfacePtr(lpISAMTableDef->lpISAM, WMI_EXEC_QUERY, sqltextBSTR, lpISAMTableDef->pGateway2);
  4027. ODBCTRACE(_T("\nWBEM ODBC Driver : Non-passthrough WQL = "));
  4028. ODBCTRACE(sqltextBSTR);
  4029. ODBCTRACE(_T("\n"));
  4030. CString sMessage;
  4031. sMessage.Format(_T("\nWBEM ODBC Driver : sc = %ld\n"), sc);
  4032. ODBCTRACE(sMessage);
  4033. sMessage.Format(_T("\nWBEM ODBC Driver : LPISAM data : szUser = %s\nszPassword = %s\nszDatabase = %s\nszServer = %s\n"),
  4034. lpISAMTableDef->lpISAM->szUser,
  4035. lpISAMTableDef->lpISAM->szPassword,
  4036. lpISAMTableDef->lpISAM->szDatabase,
  4037. lpISAMTableDef->lpISAM->szServer
  4038. );
  4039. ODBCTRACE(sMessage);
  4040. if (! lpISAMTableDef->pGateway2->IsValid() )
  4041. ODBCTRACE( _T("\nWBEM ODBC Driver :pGateway is NULL\n"));
  4042. //If ExecQuery is not supported or if there is any problems, get all entries as normal
  4043. if ( (sc == WBEM_E_NOT_SUPPORTED) || (sc == WBEM_E_FAILED) || (sc == WBEM_E_INVALID_QUERY) )
  4044. {
  4045. //Try it without the LIKE predicate
  4046. if ( sqltextBSTR2.length() )
  4047. {
  4048. if (lpISAMTableDef->lpISAM->fOptimization)
  4049. {
  4050. if ( lpSqlNode2->node.select.Predicate != NO_SQLNODE)
  4051. {
  4052. if (buffer)
  4053. delete buffer;
  4054. buffer = NULL;
  4055. LPSQLNODE lpPredicateNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode2->node.select.Predicate);
  4056. PredicateParser theParser (&lpRootNode, lpISAMTableDef, FALSE);
  4057. theParser.GeneratePredicateString(lpPredicateNode, &buffer);
  4058. if ( buffer && lstrlen(buffer) )
  4059. {
  4060. sqltextBSTR2 += L" WHERE ";
  4061. sqltextBSTR2 += buffer;
  4062. }
  4063. ODBCTRACE(_T("\nWBEM ODBC Driver : Non-passthrough WQL (attempt 2) = "));
  4064. ODBCTRACE(sqltextBSTR2);
  4065. ODBCTRACE(_T("\n"));
  4066. sc = lpISAMTableDef->lpFile->tempEnum->SetInterfacePtr(lpISAMTableDef->lpISAM, WMI_EXEC_QUERY, sqltextBSTR, lpISAMTableDef->pGateway2);
  4067. //If ExecQuery is not supported or if there is any problems, get all entries as normal
  4068. if ( (sc == WBEM_E_NOT_SUPPORTED) || (sc == WBEM_E_FAILED) || (sc == WBEM_E_INVALID_QUERY) )
  4069. {
  4070. fOptimization = FALSE;
  4071. }
  4072. }
  4073. }
  4074. }
  4075. else
  4076. {
  4077. fOptimization = FALSE;
  4078. }
  4079. }
  4080. delete selectStr;
  4081. }
  4082. }
  4083. if (!fOptimization)
  4084. {
  4085. //no optimization allowed
  4086. ODBCTRACE(_T("\nWBEM ODBC Driver : Non-passthrough WQL failed performing CreateInstanceEnum\n"));
  4087. sc = lpISAMTableDef->lpFile->tempEnum->SetInterfacePtr(lpISAMTableDef->lpISAM, WMI_CREATE_INST_ENUM, lpISAMTableDef->pBStrTableName->GetString(), lpISAMTableDef->pGateway2);
  4088. }
  4089. //Tidy up
  4090. if (buffer)
  4091. delete buffer;
  4092. }
  4093. if ( sc != S_OK )
  4094. {
  4095. err = DBASE_ERR_NODATAFOUND;
  4096. }
  4097. else
  4098. {
  4099. if (lpISAMTableDef->lpFile->tempEnum->IsValid())
  4100. {
  4101. IWbemServicesPtr myServicesPtr = NULL;
  4102. ISAMGetIWbemServices(lpISAMTableDef->lpISAM, *(lpISAMTableDef->pGateway2), myServicesPtr);
  4103. IEnumWbemClassObjectPtr myIEnumWbemClassObject = NULL;
  4104. lpISAMTableDef->lpFile->tempEnum->GetInterfacePtr(myIEnumWbemClassObject);
  4105. // CBString myServerStr;
  4106. // myServerStr.AddString( (LPSTR)lpISAMTableDef->lpISAM->szServer, FALSE );
  4107. // CServerLocationCheck myCheck (myServerStr);
  4108. BOOL fIsLocalConnection = lpISAMTableDef->lpISAM->fIsLocalConnection;//myCheck.IsLocal();
  4109. ISAMSetCloaking2(myIEnumWbemClassObject,
  4110. fIsLocalConnection,
  4111. lpISAMTableDef->lpISAM->fW2KOrMore,
  4112. lpISAMTableDef->lpISAM->dwAuthLevel,
  4113. lpISAMTableDef->lpISAM->dwImpLevel,
  4114. lpISAMTableDef->lpISAM->gpAuthIdentity);
  4115. /*
  4116. if ( fIsLocalConnection && IsW2KOrMore() )
  4117. {
  4118. WbemSetDynamicCloaking(myIEnumWbemClassObject, lpISAMTableDef->lpISAM->dwAuthLevel, lpISAMTableDef->lpISAM->dwImpLevel);
  4119. }
  4120. else
  4121. {
  4122. SetInterfaceSecurityEx(myIEnumWbemClassObject,
  4123. lpISAMTableDef->lpISAM->gpAuthIdentity,
  4124. gpPrincipal,
  4125. lpISAMTableDef->lpISAM->dwAuthLevel,
  4126. lpISAMTableDef->lpISAM->dwImpLevel);
  4127. }
  4128. */
  4129. //Reset to beginning of list
  4130. myIEnumWbemClassObject->Reset();
  4131. //Read in ALL records (if not already read)
  4132. //but only for non-passthrough SQL case
  4133. //if this is passthrough SQL delay retrieval
  4134. if (
  4135. (!lpISAMTableDef->fIsPassthroughSQL) &&
  4136. (lpISAMTableDef->lpFile->pAllRecords->IsEmpty())
  4137. )
  4138. {
  4139. WORD fElements2Read = WBEMDR32_ELEMENTS_TO_READ;
  4140. ULONG puReturned = 0;
  4141. IWbemClassObject* myRecords [WBEMDR32_ELEMENTS_TO_READ];
  4142. //Initialize array
  4143. for (ULONG loop = 0; loop < fElements2Read; loop++)
  4144. {
  4145. myRecords[loop] = NULL; //reset for next instance
  4146. }
  4147. WORD elementNumber = 0;
  4148. while ( myIEnumWbemClassObject->Next(-1, fElements2Read, myRecords, &puReturned) == S_OK )
  4149. {
  4150. for (loop = 0; loop < puReturned; loop++)
  4151. {
  4152. lpISAMTableDef->lpFile->pAllRecords->SetAt(elementNumber++, (void*)myRecords[loop] );
  4153. myRecords[loop] = NULL; //reset for next instance
  4154. }
  4155. puReturned = 0;
  4156. }
  4157. //This could be the last time around the loop
  4158. if (puReturned)
  4159. {
  4160. for (ULONG loop = 0; loop < puReturned; loop++)
  4161. {
  4162. lpISAMTableDef->lpFile->pAllRecords->SetAt(elementNumber++, (void*)myRecords[loop] );
  4163. }
  4164. }
  4165. }
  4166. //Setup bookmark
  4167. lpISAMTableDef->lpFile->currentRecord = 0;
  4168. }
  4169. else
  4170. {
  4171. err = DBASE_ERR_NODATAFOUND;
  4172. }
  4173. }
  4174. }
  4175. if (err != DBASE_ERR_NODATAFOUND)
  4176. {
  4177. //Now fetch the next record
  4178. //Check Virtual Instances
  4179. //they occur if you query for array type columns which map
  4180. //to multiple instances
  4181. BOOL fFetchNextInstance = TRUE;
  4182. if ( lpISAMTableDef->virtualInstances )
  4183. {
  4184. long numInst = lpISAMTableDef->virtualInstances->cNumberOfInstances;
  4185. long currInst = lpISAMTableDef->virtualInstances->currentInstance;
  4186. CString myText;
  4187. myText.Format("\nWBEM ODBC Driver : number of virtual instances = %ld current virtual instance = %ld\n", numInst, currInst);
  4188. ODBCTRACE(myText);
  4189. if ( (numInst != 0) && ( (currInst + 1) < numInst ) )
  4190. {
  4191. //Don't fetch another instance
  4192. //just increment virtual instance
  4193. ODBCTRACE ("\nWBEM ODBC Driver : not fetching another instance, just updating virtual instance number\n");
  4194. fFetchNextInstance = FALSE;
  4195. ++(lpISAMTableDef->virtualInstances->currentInstance);
  4196. }
  4197. }
  4198. if (fFetchNextInstance)
  4199. {
  4200. //In passthrough SQL case you might not have any instances yet
  4201. //or we might have read all the 10 instances and need to load the next batch,
  4202. //therefore we make a check now
  4203. if ( lpISAMTableDef->fIsPassthroughSQL )
  4204. {
  4205. //Do we need to load in the next batch of 10 instances ?
  4206. if (
  4207. (
  4208. lpISAMTableDef->lpFile->pAllRecords->IsEmpty() ||
  4209. lpISAMTableDef->lpFile->currentRecord >= BATCH_NUM_OF_INSTANCES
  4210. )
  4211. && lpISAMTableDef->lpFile->fMoreToCome )
  4212. {
  4213. //Yes, load next batch
  4214. ODBCTRACE ("\nWBEM ODBC Driver : Need to Load next batch of 10 instances\n");
  4215. //First clear out old instances, if applicable
  4216. if (! lpISAMTableDef->lpFile->pAllRecords->IsEmpty() )
  4217. {
  4218. for(POSITION pos = lpISAMTableDef->lpFile->pAllRecords->GetStartPosition(); pos != NULL; )
  4219. {
  4220. WORD key = 0;
  4221. IWbemClassObject* pa = NULL;
  4222. lpISAMTableDef->lpFile->pAllRecords->GetNextAssoc( pos, key, (void*&)pa );
  4223. if (pa)
  4224. {
  4225. pa->Release();
  4226. }
  4227. }
  4228. delete (lpISAMTableDef->lpFile->pAllRecords);
  4229. lpISAMTableDef->lpFile->pAllRecords = new CMapWordToPtr();
  4230. }
  4231. //Load the next 10 instances
  4232. lpISAMTableDef->lpFile->currentRecord = 0;
  4233. WORD fElements2Read = BATCH_NUM_OF_INSTANCES;
  4234. ULONG puReturned = 0;
  4235. IWbemClassObject* myRecords [BATCH_NUM_OF_INSTANCES];
  4236. //Initialize array
  4237. for (ULONG loop = 0; loop < fElements2Read; loop++)
  4238. {
  4239. myRecords[loop] = NULL; //reset for next instance
  4240. }
  4241. WORD elementNumber = 0;
  4242. //Special case. The 1st SQL passthrough instance was
  4243. //already fetched
  4244. BOOL fSpecialCase = FALSE;
  4245. if (lpISAMTableDef->firstPassthrInst)
  4246. {
  4247. fSpecialCase = TRUE;
  4248. lpISAMTableDef->lpFile->pAllRecords->SetAt(elementNumber++, (void*)lpISAMTableDef->firstPassthrInst);
  4249. lpISAMTableDef->firstPassthrInst = NULL; //mark as used
  4250. }
  4251. ODBCTRACE("\nWBEM ODBC Driver : Calling Next(...)\n");
  4252. IEnumWbemClassObjectPtr myIEnumWbemClassObject = NULL;
  4253. lpISAMTableDef->lpFile->tempEnum->GetInterfacePtr(myIEnumWbemClassObject); // Note: don't need to call SetInterfaceSecurityEx because it has already been called for this ptr
  4254. // CBString myServerStr;
  4255. // myServerStr.AddString( (LPSTR)lpISAMTableDef->lpISAM->szServer, FALSE );
  4256. // CServerLocationCheck myCheck (myServerStr);
  4257. BOOL fIsLocalConnection = lpISAMTableDef->lpISAM->fIsLocalConnection;//myCheck.IsLocal();
  4258. if ( fIsLocalConnection && (lpISAMTableDef->lpISAM->fW2KOrMore) )
  4259. {
  4260. WbemSetDynamicCloaking(myIEnumWbemClassObject, lpISAMTableDef->lpISAM->dwAuthLevel, lpISAMTableDef->lpISAM->dwImpLevel);
  4261. }
  4262. if (SUCCEEDED(myIEnumWbemClassObject->Next(-1, fElements2Read-(fSpecialCase?1:0), myRecords, &puReturned)))
  4263. {
  4264. CString myText;
  4265. myText.Format("\nWBEM ODBC Driver : We got back a batch of %ld instances\n", puReturned);
  4266. ODBCTRACE(myText);
  4267. int i = 0;
  4268. loop = 0;
  4269. for (; i < puReturned; i++)
  4270. {
  4271. lpISAMTableDef->lpFile->pAllRecords->SetAt(elementNumber++, (void*)myRecords[i] );
  4272. loop++;
  4273. }
  4274. puReturned+=((fSpecialCase?1:0));
  4275. //Did we get 10 instances back or less
  4276. BOOL fGotFullSetofInstances = TRUE;
  4277. fGotFullSetofInstances = (puReturned == BATCH_NUM_OF_INSTANCES) ? TRUE : FALSE;
  4278. if ( !fGotFullSetofInstances )
  4279. {
  4280. //This is the last set of 10 instances
  4281. lpISAMTableDef->lpFile->fMoreToCome = FALSE;
  4282. }
  4283. }
  4284. }
  4285. }
  4286. lpISAMTableDef->lpFile->record = NULL;
  4287. ODBCTRACE ("\nWBEM ODBC Driver : Fetching next instance from CMapWordToPtr\n");
  4288. BOOL fStatus = lpISAMTableDef->lpFile->pAllRecords->Lookup
  4289. ((WORD)lpISAMTableDef->lpFile->currentRecord, (void* &)lpISAMTableDef->lpFile->record);
  4290. //Check that a record was returned
  4291. if (fStatus && lpISAMTableDef->lpFile->record)
  4292. {
  4293. //Increment bookmark
  4294. ++(lpISAMTableDef->lpFile->currentRecord);
  4295. //Remove previous virtual instance map (if there was one)
  4296. delete (lpISAMTableDef->virtualInstances);
  4297. lpISAMTableDef->virtualInstances = new VirtualInstanceManager();
  4298. lpISAMTableDef->virtualInstances->Load(lpISAMTableDef->passthroughMap, lpISAMTableDef->lpFile->record);
  4299. }
  4300. else
  4301. {
  4302. err = DBASE_ERR_NODATAFOUND;
  4303. }
  4304. }
  4305. }
  4306. }
  4307. else
  4308. {
  4309. if (lpISAMTableDef->iRecord != 1)
  4310. err = DBASE_ERR_SUCCESS;
  4311. else
  4312. err = DBASE_ERR_NODATAFOUND;
  4313. }
  4314. // Error if end of file?
  4315. if (err == DBASE_ERR_NODATAFOUND)
  4316. {
  4317. lpISAMTableDef->lpISAM->errcode = ISAM_EOF;
  4318. return ISAM_EOF;
  4319. }
  4320. else if (err != DBASE_ERR_SUCCESS)
  4321. {
  4322. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4323. return ISAM_ERROR;
  4324. }
  4325. lpISAMTableDef->fFirstRead = FALSE;
  4326. return NO_ISAM_ERR;
  4327. }
  4328. /***************************************************************************/
  4329. /* Provides default value for selected column */
  4330. SWORD ISAMProvideDefaultValue(SWORD fCType,
  4331. PTR rgbValue,
  4332. SDWORD cbValueMax,
  4333. SDWORD FAR *pcbValue)
  4334. {
  4335. SWORD err = NO_ISAM_ERR;
  4336. switch (fCType)
  4337. {
  4338. case SQL_C_DOUBLE:
  4339. {
  4340. //Check that you have enough buffer to store value
  4341. *pcbValue = sizeof(double);
  4342. if (cbValueMax >= *pcbValue)
  4343. {
  4344. *((double *)rgbValue) = (double)0;
  4345. }
  4346. else
  4347. {
  4348. *pcbValue = 0;
  4349. err = ISAM_ERROR;
  4350. }
  4351. }
  4352. break;
  4353. case SQL_C_DATE:
  4354. {
  4355. *pcbValue = sizeof (DATE_STRUCT);
  4356. DATE_STRUCT FAR* pDateStruct = (DATE_STRUCT FAR*)rgbValue;
  4357. if ( cbValueMax >= (*pcbValue) )
  4358. {
  4359. pDateStruct->year = (SWORD)0;
  4360. pDateStruct->month = (UWORD)0;
  4361. pDateStruct->day = (UWORD)0;
  4362. }
  4363. else
  4364. {
  4365. *pcbValue = 0;
  4366. err = ISAM_ERROR;
  4367. }
  4368. }
  4369. break;
  4370. case SQL_C_TIME:
  4371. {
  4372. //Check that you have enough buffer to store value
  4373. *pcbValue = sizeof (TIME_STRUCT);
  4374. TIME_STRUCT FAR* pTimeStruct = (TIME_STRUCT FAR*)rgbValue;
  4375. if ( cbValueMax >= (*pcbValue) )
  4376. {
  4377. pTimeStruct->hour = (UWORD)0;
  4378. pTimeStruct->minute = (UWORD)0;
  4379. pTimeStruct->second = (UWORD)0;
  4380. }
  4381. else
  4382. {
  4383. *pcbValue = 0;
  4384. err = ISAM_ERROR;
  4385. }
  4386. }
  4387. break;
  4388. case SQL_C_TIMESTAMP:
  4389. {
  4390. //Check that you have enough buffer to store value
  4391. *pcbValue = sizeof (TIMESTAMP_STRUCT);
  4392. TIMESTAMP_STRUCT FAR* pTimeStampStruct = (TIMESTAMP_STRUCT FAR*)rgbValue;
  4393. if ( cbValueMax >= (*pcbValue) )
  4394. {
  4395. pTimeStampStruct->year = (SWORD)0;
  4396. pTimeStampStruct->month = (UWORD)0;
  4397. pTimeStampStruct->day = (UWORD)0;
  4398. pTimeStampStruct->hour = (UWORD)0;
  4399. pTimeStampStruct->minute = (UWORD)0;
  4400. pTimeStampStruct->second = (UWORD)0;
  4401. pTimeStampStruct->fraction = 0;
  4402. }
  4403. else
  4404. {
  4405. *pcbValue = 0;
  4406. err = ISAM_ERROR;
  4407. }
  4408. }
  4409. break;
  4410. case SQL_C_CHAR:
  4411. case SQL_C_BINARY:
  4412. default:
  4413. {
  4414. *pcbValue = SQL_NULL_DATA;
  4415. }
  4416. break;
  4417. }
  4418. return err;
  4419. }
  4420. /***************************************************************************/
  4421. /* Gets the data value for the selected column */
  4422. SWORD INTFUNC ISAMGetData(LPISAMTABLEDEF lpISAMTableDef,
  4423. UWORD icol,
  4424. SDWORD cbOffset,
  4425. SWORD fCType,
  4426. PTR rgbValue,
  4427. SDWORD cbValueMax,
  4428. SDWORD FAR *pcbValue)
  4429. {
  4430. //This manages the thread locale id
  4431. ThreadLocaleIdManager myThreadStuff(lpISAMTableDef->lpISAM);
  4432. lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
  4433. if ((fCType != SQL_CHAR) && (lpISAMTableDef->lpFile == NULL))
  4434. {
  4435. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4436. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 1\n");
  4437. return ISAM_ERROR;
  4438. }
  4439. if (cbValueMax == SQL_NTS)
  4440. cbValueMax = s_lstrlen (rgbValue);
  4441. //create SAFEARRAY to store BSTR's
  4442. SAFEARRAY FAR* rgSafeArray = NULL;
  4443. //Create a store for column name
  4444. BSTR lpbString;
  4445. CBString temppbString;
  4446. //Stores table alias
  4447. CBString cbTableAlias;
  4448. //Check if you have a __Generic class
  4449. BOOL fIs__Generic = lpISAMTableDef->fIs__Generic;
  4450. //Points to the current instance for the property
  4451. IWbemClassObjectPtr theRecord = NULL;
  4452. //Points to the current class definition
  4453. IWbemClassObjectPtr theClassDefinition = NULL;
  4454. if (!fIs__Generic)
  4455. {
  4456. //Setup the record pointer
  4457. theRecord = lpISAMTableDef->lpFile->record;
  4458. //Setup the class definition pointer
  4459. theClassDefinition = lpISAMTableDef->pSingleTable;
  4460. //Fetch name of column "icol"
  4461. //Remeber with abstract and derived classes the properities in the class definition
  4462. //may be different to the properties in the instances.
  4463. //The "icol" maps to a class property,so we get the names from the class
  4464. lpISAMTableDef->pSingleTable->GetNames(NULL, 0, NULL, &rgSafeArray);
  4465. SafeArrayLock(rgSafeArray);
  4466. LONG iColumnNum = (LONG)icol;
  4467. if ( FAILED(SafeArrayGetElement(rgSafeArray, &iColumnNum, &lpbString)) )
  4468. {
  4469. //To be more resilient we specify a default value
  4470. //NULL for SQL_C_CHAR and zero for numeric values
  4471. SWORD fErr = ISAMProvideDefaultValue(fCType, rgbValue, cbValueMax, pcbValue);
  4472. if (fErr != NO_ISAM_ERR)
  4473. {
  4474. lpISAMTableDef->lpISAM->errcode = fErr;
  4475. SafeArrayUnlock(rgSafeArray);
  4476. SafeArrayDestroy(rgSafeArray); //SAI ADDED
  4477. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 2\n");
  4478. return fErr;
  4479. }
  4480. SafeArrayUnlock(rgSafeArray);
  4481. SafeArrayDestroy(rgSafeArray); //SAI ADDED
  4482. return NO_ISAM_ERR;
  4483. }
  4484. #ifdef TESTING
  4485. //copy column name
  4486. char pColumnName [MAX_COLUMN_NAME_LENGTH+1];
  4487. pColumnName[0] = 0;
  4488. wcstombs(pColumnName, lpbString, MAX_COLUMN_NAME_LENGTH);
  4489. pColumnName[MAX_COLUMN_NAME_LENGTH] = 0;
  4490. #endif
  4491. }
  4492. else
  4493. {
  4494. //Get the icol from passthrough map
  4495. PassthroughLookupTable* passthroughElement = NULL;
  4496. WORD myIndex = (WORD)icol;
  4497. BOOL status = lpISAMTableDef->passthroughMap->Lookup(myIndex, (void*&)passthroughElement);
  4498. if (status)
  4499. {
  4500. temppbString.AddString(passthroughElement->GetColumnName(), FALSE);
  4501. char* lpTableAlias = passthroughElement->GetTableAlias();
  4502. cbTableAlias.AddString(lpTableAlias, FALSE);
  4503. //Get the embedded object (keyed on table alias)
  4504. VARIANT vEmbedded;
  4505. if ( SUCCEEDED(lpISAMTableDef->lpFile->record->Get(cbTableAlias.GetString(), 0, &vEmbedded, NULL, NULL)) )
  4506. {
  4507. IUnknown* myUnk = vEmbedded.punkVal;
  4508. myUnk->QueryInterface(IID_IWbemClassObject, (void**)&theRecord);
  4509. VariantClear(&vEmbedded);
  4510. }
  4511. else
  4512. {
  4513. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4514. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 3\n");
  4515. return ISAM_ERROR;
  4516. }
  4517. //Do the same for class definition
  4518. VARIANT vClassEmbedded;
  4519. if ( SUCCEEDED(lpISAMTableDef->lpFile->record->Get(cbTableAlias.GetString(), 0, &vClassEmbedded, NULL, NULL)) )
  4520. {
  4521. IUnknown* myUnk = vClassEmbedded.punkVal;
  4522. myUnk->QueryInterface(IID_IWbemClassObject, (void**)&theClassDefinition);
  4523. VariantClear(&vClassEmbedded);
  4524. }
  4525. else
  4526. {
  4527. //(9) Should we release theRecord
  4528. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4529. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 4\n");
  4530. return ISAM_ERROR;
  4531. }
  4532. }
  4533. else
  4534. {
  4535. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4536. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 5\n");
  4537. return ISAM_ERROR;
  4538. }
  4539. }
  4540. //Get the value of the column
  4541. CIMTYPE wbemType = 0;
  4542. SWORD wbemVariantType = 0;
  4543. VARIANT vVariantVal;
  4544. if ( FAILED(theRecord->Get(fIs__Generic ? temppbString.GetString() : lpbString, 0, &vVariantVal, &wbemType, NULL)) )
  4545. {
  4546. //To be more resilient we specify a default value
  4547. //NULL for SQL_C_CHAR and zero for numeric values
  4548. SWORD fErr = ISAMProvideDefaultValue(fCType, rgbValue, cbValueMax, pcbValue);
  4549. //Tidy up
  4550. if (rgSafeArray)
  4551. {
  4552. SafeArrayUnlock(rgSafeArray);
  4553. SafeArrayDestroy(rgSafeArray);
  4554. }
  4555. if (fErr != NO_ISAM_ERR)
  4556. {
  4557. //(9) Should we release theRecord and theClassDefinition
  4558. //if __generic ?
  4559. lpISAMTableDef->lpISAM->errcode = fErr;
  4560. if (!fIs__Generic)
  4561. SysFreeString(lpbString);
  4562. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 6\n");
  4563. return fErr;
  4564. }
  4565. //(9) Should we release theRecord and theClassDefinition
  4566. //if __generic ?
  4567. if (!fIs__Generic)
  4568. SysFreeString(lpbString);
  4569. return NO_ISAM_ERR;
  4570. }
  4571. //New
  4572. //Get attributes for chosen column
  4573. IWbemQualifierSetPtr pQualifierSet = NULL;
  4574. if ( S_OK != (theClassDefinition->GetPropertyQualifierSet(fIs__Generic ? temppbString.GetString() : lpbString, &pQualifierSet)) )
  4575. {
  4576. pQualifierSet = NULL;
  4577. }
  4578. //Tidy up
  4579. if (rgSafeArray)
  4580. {
  4581. SafeArrayUnlock(rgSafeArray);
  4582. SafeArrayDestroy(rgSafeArray);
  4583. }
  4584. //Get CIMTYPE String
  4585. VARIANT pVal2;
  4586. BSTR syntaxStr = NULL;
  4587. BOOL fClearpVal2 = FALSE;
  4588. if (pQualifierSet)
  4589. {
  4590. BSTR cimtypeBSTR = SysAllocString(WBEMDR32_L_CIMTYPE);
  4591. SCODE result = pQualifierSet->Get(cimtypeBSTR, 0, &pVal2, 0);
  4592. SysFreeString(cimtypeBSTR);
  4593. if ( S_OK == result )
  4594. {
  4595. if (pVal2.bstrVal)
  4596. syntaxStr = pVal2.bstrVal;
  4597. fClearpVal2 = TRUE;
  4598. }
  4599. }
  4600. //Get MAXLEN Value
  4601. VARIANT pVal3;
  4602. SDWORD maxLenVal = 0;
  4603. if (pQualifierSet)
  4604. {
  4605. BSTR maxBSTR = SysAllocString(WBEMDR32_L_MAX);
  4606. SCODE result = pQualifierSet->Get(maxBSTR, 0, &pVal3, 0);
  4607. SysFreeString(maxBSTR);
  4608. if ( S_OK == result )
  4609. {
  4610. maxLenVal = pVal3.iVal;
  4611. VariantClear(&pVal3);
  4612. }
  4613. }
  4614. //Get value from variant
  4615. ISAMGetWbemVariantType(wbemType, wbemVariantType);
  4616. //get the index for this column
  4617. long index = -1;
  4618. _bstr_t theTableAlias = cbTableAlias.GetString();
  4619. _bstr_t theColumnName = fIs__Generic ? temppbString.GetString() : lpbString;
  4620. if (lpISAMTableDef->virtualInstances)
  4621. {
  4622. long theInstance = lpISAMTableDef->virtualInstances->currentInstance;
  4623. //Remove previous virtual instance map (if there was one)
  4624. delete (lpISAMTableDef->virtualInstances);
  4625. lpISAMTableDef->virtualInstances = new VirtualInstanceManager();
  4626. lpISAMTableDef->virtualInstances->Load(lpISAMTableDef->passthroughMap, lpISAMTableDef->lpFile->record);
  4627. //Restore current instance
  4628. lpISAMTableDef->virtualInstances->currentInstance = theInstance;
  4629. index = lpISAMTableDef->virtualInstances->GetArrayIndex(theTableAlias, theColumnName, theInstance);
  4630. }
  4631. if (!fIs__Generic)
  4632. SysFreeString(lpbString);
  4633. SWORD err = ISAMGetValueFromVariant(vVariantVal, fCType,
  4634. rgbValue, cbValueMax, pcbValue, wbemVariantType, syntaxStr, maxLenVal, index);
  4635. if (fClearpVal2)
  4636. VariantClear(&pVal2);
  4637. if (err != NO_ISAM_ERR)
  4638. {
  4639. lpISAMTableDef->lpISAM->errcode = err;
  4640. ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 7\n");
  4641. return err;
  4642. }
  4643. VariantClear(&vVariantVal);
  4644. return NO_ISAM_ERR;
  4645. }
  4646. /***************************************************************************/
  4647. SWORD INTFUNC ISAMPutData(LPISAMTABLEDEF lpISAMTableDef,
  4648. UWORD icol,
  4649. SWORD fCType,
  4650. PTR rgbValue,
  4651. SDWORD cbValue)
  4652. {
  4653. /* Not allowed for the passthrough table */
  4654. lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
  4655. if (lpISAMTableDef->lpFile == NULL) {
  4656. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4657. return ISAM_ERROR;
  4658. }
  4659. /* Null? */
  4660. if (cbValue == SQL_NULL_DATA) {
  4661. /* Yes. Set value to NULL */
  4662. if (dBaseSetColumnNull(lpISAMTableDef->lpFile, (UWORD) (icol+1)) !=
  4663. DBASE_ERR_SUCCESS) {
  4664. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4665. return ISAM_ERROR;
  4666. }
  4667. }
  4668. else {
  4669. /* No. Set the value */
  4670. switch (fCType) {
  4671. case SQL_C_DOUBLE:
  4672. {
  4673. UCHAR string[20];
  4674. if (DoubleToChar(*((double far *)rgbValue), TRUE, (LPUSTR)string,
  4675. sizeof(string)))
  4676. string[sizeof(string)-1] = '\0';
  4677. if (dBaseSetColumnCharVal(lpISAMTableDef->lpFile, (UWORD) (icol+1),
  4678. string, lstrlen((char*)string)) != DBASE_ERR_SUCCESS) {
  4679. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4680. return ISAM_ERROR;
  4681. }
  4682. }
  4683. break;
  4684. case SQL_C_CHAR:
  4685. if (cbValue == SQL_NTS)
  4686. cbValue = lstrlen((char*)rgbValue);
  4687. if (dBaseSetColumnCharVal(lpISAMTableDef->lpFile, (UWORD) (icol+1),
  4688. (UCHAR FAR*)rgbValue, cbValue) != DBASE_ERR_SUCCESS) {
  4689. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4690. return ISAM_ERROR;
  4691. }
  4692. break;
  4693. case SQL_C_DATE:
  4694. {
  4695. UCHAR string[11];
  4696. DateToChar((DATE_STRUCT far *) rgbValue, (LPUSTR)string);
  4697. if (dBaseSetColumnCharVal(lpISAMTableDef->lpFile, (UWORD) (icol+1),
  4698. string, lstrlen((char*)string)) != DBASE_ERR_SUCCESS) {
  4699. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4700. return ISAM_ERROR;
  4701. }
  4702. }
  4703. break;
  4704. default:
  4705. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4706. return ISAM_ERROR;
  4707. }
  4708. }
  4709. return NO_ISAM_ERR;
  4710. }
  4711. /***************************************************************************/
  4712. SWORD INTFUNC ISAMInsertRecord(LPISAMTABLEDEF lpISAMTableDef)
  4713. {
  4714. lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
  4715. if (lpISAMTableDef->lpFile == NULL) {
  4716. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4717. return ISAM_ERROR;
  4718. }
  4719. if (dBaseAddRecord(lpISAMTableDef->lpFile) != DBASE_ERR_SUCCESS) {
  4720. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4721. return ISAM_ERROR;
  4722. }
  4723. return NO_ISAM_ERR;
  4724. }
  4725. /***************************************************************************/
  4726. SWORD INTFUNC ISAMUpdateRecord(LPISAMTABLEDEF lpISAMTableDef)
  4727. {
  4728. lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
  4729. if (lpISAMTableDef->lpFile == NULL) {
  4730. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4731. return ISAM_ERROR;
  4732. }
  4733. return NO_ISAM_ERR;
  4734. }
  4735. /***************************************************************************/
  4736. SWORD INTFUNC ISAMDeleteRecord(LPISAMTABLEDEF lpISAMTableDef)
  4737. {
  4738. lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
  4739. if (lpISAMTableDef->lpFile == NULL) {
  4740. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4741. return ISAM_ERROR;
  4742. }
  4743. if (dBaseDeleteRecord(lpISAMTableDef->lpFile) != DBASE_ERR_SUCCESS) {
  4744. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4745. return ISAM_ERROR;
  4746. }
  4747. return NO_ISAM_ERR;
  4748. }
  4749. /***************************************************************************/
  4750. SWORD INTFUNC ISAMGetBookmark(LPISAMTABLEDEF lpISAMTableDef,
  4751. LPISAMBOOKMARK lpISAMBookmark)
  4752. {
  4753. lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
  4754. if (lpISAMTableDef->lpFile != NULL)
  4755. {
  4756. lpISAMBookmark->currentRecord = lpISAMTableDef->lpFile->currentRecord;
  4757. }
  4758. else
  4759. {
  4760. lpISAMBookmark->currentRecord = lpISAMTableDef->iRecord;
  4761. }
  4762. if (lpISAMTableDef->virtualInstances)
  4763. {
  4764. lpISAMBookmark->currentInstance = lpISAMTableDef->virtualInstances->currentInstance;
  4765. }
  4766. return NO_ISAM_ERR;
  4767. }
  4768. /***************************************************************************/
  4769. SWORD INTFUNC ISAMPosition(LPISAMTABLEDEF lpISAMTableDef,
  4770. LPISAMBOOKMARK ISAMBookmark)
  4771. {
  4772. lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
  4773. if ( lpISAMTableDef->lpFile && lpISAMTableDef->lpFile->tempEnum->IsValid())
  4774. {
  4775. BOOL fStatus = lpISAMTableDef->lpFile->pAllRecords->Lookup
  4776. ( (WORD)(ISAMBookmark->currentRecord - 1), (void* &)lpISAMTableDef->lpFile->record);
  4777. if (fStatus && lpISAMTableDef->lpFile->record)
  4778. {
  4779. //Update bookmark to next entry
  4780. lpISAMTableDef->lpFile->currentRecord = ISAMBookmark->currentRecord;// + 1;
  4781. }
  4782. else
  4783. {
  4784. lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
  4785. return ISAM_ERROR;
  4786. }
  4787. }
  4788. else
  4789. {
  4790. lpISAMTableDef->iRecord = (SDWORD) ISAMBookmark->currentRecord;
  4791. }
  4792. if (lpISAMTableDef->virtualInstances)
  4793. {
  4794. lpISAMTableDef->virtualInstances->currentInstance = ISAMBookmark->currentInstance;
  4795. }
  4796. return NO_ISAM_ERR;
  4797. }
  4798. /***************************************************************************/
  4799. /* Closes a specific table and deallocates the table definition */
  4800. SWORD INTFUNC ISAMCloseTable(LPISAMTABLEDEF lpISAMTableDef)
  4801. {
  4802. //Check if lpISAMTableDef exists
  4803. if (! lpISAMTableDef)
  4804. return NO_ISAM_ERR;
  4805. /* Close the dBASE file */
  4806. lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
  4807. if (lpISAMTableDef->lpFile != NULL)
  4808. {
  4809. //Release interface pointers if applicable
  4810. //Empty out all instances
  4811. if (lpISAMTableDef->lpFile->pAllRecords)
  4812. {
  4813. for(POSITION pos = lpISAMTableDef->lpFile->pAllRecords->GetStartPosition(); pos != NULL; )
  4814. {
  4815. WORD key = 0;
  4816. IWbemClassObject* pa = NULL;
  4817. lpISAMTableDef->lpFile->pAllRecords->GetNextAssoc( pos, key, (void*&)pa );
  4818. if (pa)
  4819. {
  4820. pa->Release();
  4821. }
  4822. }
  4823. delete (lpISAMTableDef->lpFile->pAllRecords);
  4824. lpISAMTableDef->lpFile->pAllRecords = NULL;
  4825. }
  4826. if (lpISAMTableDef->lpFile->tempEnum)
  4827. {
  4828. delete (lpISAMTableDef->lpFile->tempEnum);
  4829. lpISAMTableDef->lpFile->tempEnum = NULL;
  4830. }
  4831. }
  4832. if (lpISAMTableDef->pBStrTableName)
  4833. {
  4834. delete (lpISAMTableDef->pBStrTableName);
  4835. lpISAMTableDef->pBStrTableName = NULL;
  4836. }
  4837. if (lpISAMTableDef->pSingleTable)
  4838. {
  4839. lpISAMTableDef->pSingleTable->Release();
  4840. lpISAMTableDef->pSingleTable = NULL;
  4841. }
  4842. TidyupPassthroughMap(lpISAMTableDef->passthroughMap);
  4843. lpISAMTableDef->passthroughMap = NULL;
  4844. if (lpISAMTableDef->pGateway2)
  4845. {
  4846. delete lpISAMTableDef->pGateway2;
  4847. lpISAMTableDef->pGateway2 = NULL;
  4848. }
  4849. if (lpISAMTableDef->pColumnInfo)
  4850. {
  4851. delete (lpISAMTableDef->pColumnInfo);
  4852. lpISAMTableDef->pColumnInfo = NULL;
  4853. }
  4854. if (lpISAMTableDef->pContext)
  4855. {
  4856. lpISAMTableDef->pContext->Release();
  4857. lpISAMTableDef->pContext = NULL;
  4858. }
  4859. if (lpISAMTableDef->lpFile)
  4860. {
  4861. GlobalUnlock(GlobalPtrHandle(lpISAMTableDef->lpFile));
  4862. GlobalFree(GlobalPtrHandle(lpISAMTableDef->lpFile));
  4863. lpISAMTableDef->lpFile = NULL;
  4864. }
  4865. delete lpISAMTableDef->virtualInstances;
  4866. lpISAMTableDef->virtualInstances = NULL;
  4867. GlobalUnlock(GlobalPtrHandle(lpISAMTableDef));
  4868. GlobalFree(GlobalPtrHandle(lpISAMTableDef));
  4869. lpISAMTableDef = NULL;
  4870. return NO_ISAM_ERR;
  4871. }
  4872. /***************************************************************************/
  4873. SWORD INTFUNC ISAMDeleteTable(LPISAM lpISAM, LPUSTR lpszTableName)
  4874. {
  4875. return ISAM_NOTSUPPORTED;
  4876. /*
  4877. UCHAR szFilename[MAX_DATABASE_NAME_LENGTH+MAX_TABLE_NAME_LENGTH+6];
  4878. // Create the filename
  4879. lpISAM->errcode = NO_ISAM_ERR;
  4880. lstrcpy((char*)szFilename, (char*)lpISAM->szDatabase);
  4881. lstrcat((char*)szFilename, "\\");
  4882. lstrcat((char*)szFilename, lpszTableName);
  4883. lstrcat((char*)szFilename, ".DBF");
  4884. // Delete the file
  4885. dBaseDestroy((char*)szFilename);
  4886. return NO_ISAM_ERR;
  4887. */
  4888. }
  4889. /***************************************************************************/
  4890. // Checked for SetInterfaceSecurityEx on IWbemServices and IEnumWbemClassObject
  4891. SWORD INTFUNC ISAMPrepare(LPISAM lpISAM, UCHAR FAR *szSqlStr, SDWORD cbSqlStr,
  4892. LPISAMSTATEMENT FAR *lplpISAMStatement,
  4893. LPUSTR lpszTablename, UWORD FAR *lpParameterCount
  4894. #ifdef IMPLTMT_PASSTHROUGH
  4895. , LPSTMT lpstmt
  4896. #endif
  4897. )
  4898. {
  4899. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare\n"));
  4900. //For now disable Passthrough SQL
  4901. // lpISAM->errcode = ISAM_NOTSUPPORTED;
  4902. // return ISAM_NOTSUPPORTED;
  4903. /*
  4904. //Test
  4905. CBString s1;
  4906. CBString s2;
  4907. CBString s3;
  4908. CBString s4;
  4909. CBString s5;
  4910. s1.AddString("", FALSE);
  4911. s2.AddString(NULL, FALSE);
  4912. s3.AddString("\\\\.", FALSE);
  4913. s4.AddString("\\\\SaiWong4", FALSE);
  4914. s5.AddString("\\\\SaiWong2", FALSE);
  4915. CServerLocationCheck one(s1);
  4916. CServerLocationCheck two(s2);
  4917. CServerLocationCheck three(s3);
  4918. CServerLocationCheck four(s4);
  4919. CServerLocationCheck five(s5);
  4920. */
  4921. HGLOBAL h;
  4922. LPISAMSTATEMENT lpISAMStatement;
  4923. lpISAM->errcode = NO_ISAM_ERR;
  4924. h = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (ISAMSTATEMENT));
  4925. if (h == NULL || (lpISAMStatement = (LPISAMSTATEMENT) GlobalLock (h)) == NULL) {
  4926. if (h)
  4927. GlobalFree(h);
  4928. lpISAM->errcode = ISAM_ERROR;
  4929. return ISAM_ERROR;
  4930. }
  4931. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 1\n"));
  4932. //Initialize passthrough parameters
  4933. lpISAMStatement->pProv = NULL;
  4934. lpISAMStatement->currentRecord = 0;
  4935. lpISAMStatement->tempEnum = new CSafeIEnumWbemClassObject();
  4936. lpISAMStatement->firstPassthrInst = NULL;
  4937. lpISAMStatement->classDef = NULL;
  4938. lpISAMStatement->tempEnum2 = new CSafeIEnumWbemClassObject();
  4939. if ((cbSqlStr == 15) && (!_fmemicmp(szSqlStr, "MessageBox(?,?)", 15))) {
  4940. s_lstrcpy(lpszTablename, "");
  4941. *lpParameterCount = 2;
  4942. lpISAMStatement->lpISAM = lpISAM;
  4943. lpISAMStatement->resultSet = FALSE;
  4944. lpISAMStatement->lpszParam1 = NULL;
  4945. lpISAMStatement->cbParam1 = SQL_NULL_DATA;
  4946. lpISAMStatement->lpszParam2 = NULL;
  4947. lpISAMStatement->cbParam2 = SQL_NULL_DATA;
  4948. }
  4949. #ifdef IMPLTMT_PASSTHROUGH
  4950. else if (TRUE)
  4951. {
  4952. //Try passthrough
  4953. *lpParameterCount = 0;
  4954. lpISAMStatement->lpISAM = lpISAM;
  4955. lpISAMStatement->resultSet = TRUE;
  4956. lpISAMStatement->lpszParam1 = NULL;
  4957. lpISAMStatement->cbParam1 = SQL_NULL_DATA;
  4958. lpISAMStatement->lpszParam2 = NULL;
  4959. lpISAMStatement->cbParam2 = SQL_NULL_DATA;
  4960. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 2\n"));
  4961. /* No. Create a PASSTHROUGH parse tree */
  4962. SCODE sc = Parse(lpstmt, lpISAM, (LPUSTR) szSqlStr,
  4963. cbSqlStr, &(lpstmt->lpSqlStmt));
  4964. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 3\n"));
  4965. if (sc != SQL_SUCCESS) {
  4966. FreeTree(lpstmt->lpSqlStmt);
  4967. lpstmt->lpSqlStmt = NULL;
  4968. delete lpISAMStatement->tempEnum;
  4969. delete lpISAMStatement->tempEnum2;
  4970. GlobalUnlock(h);
  4971. GlobalFree(h);
  4972. lpISAM->errcode = ISAM_NOTSUPPORTED;
  4973. return ISAM_NOTSUPPORTED;
  4974. }
  4975. //Need to do a semantic check so that any
  4976. //Table.* will get expanded
  4977. sc = SemanticCheck(lpstmt, &(lpstmt->lpSqlStmt),
  4978. ROOT_SQLNODE, FALSE, ISAMCaseSensitive(lpstmt->lpdbc->lpISAM),
  4979. NO_SQLNODE, NO_SQLNODE);
  4980. if (sc != SQL_SUCCESS) {
  4981. FreeTree(lpstmt->lpSqlStmt);
  4982. lpstmt->lpSqlStmt = NULL;
  4983. delete lpISAMStatement->tempEnum;
  4984. delete lpISAMStatement->tempEnum2;
  4985. GlobalUnlock(h);
  4986. GlobalFree(h);
  4987. lpISAM->errcode = ISAM_NOTSUPPORTED;
  4988. return ISAM_NOTSUPPORTED;
  4989. }
  4990. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 3b\n"));
  4991. //Generate WQL statement using parse tree
  4992. LPSQLNODE lpRootNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
  4993. LPSQLNODE lpSqlNode2 = ToNode(lpstmt->lpSqlStmt, lpRootNode->node.root.sql);
  4994. char* fullWQL = NULL;
  4995. BOOL fHasAggregateFunctions = FALSE;
  4996. TableColumnInfo selectInfo (&lpRootNode, &lpSqlNode2, WQL_MULTI_TABLE);
  4997. CMapWordToPtr* passthroughMap;
  4998. selectInfo.BuildFullWQL(&fullWQL, &passthroughMap);
  4999. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 3c\n"));
  5000. //Extra check for aggregate functions what WQL does not support
  5001. //so we must fail SQL passthrough
  5002. if ( selectInfo.HasAggregateFunctions() )
  5003. {
  5004. fHasAggregateFunctions = TRUE;
  5005. }
  5006. //At this point we can check for 'SELECT * FROM .....'
  5007. //If this is so we need to work out the full column list
  5008. //and re-parse and try again (only for single tables)
  5009. if ( selectInfo.IsSelectStar() && selectInfo.IsZeroOrOneList() )
  5010. {
  5011. //get new query string
  5012. char* lpWQLStr = NULL;
  5013. char* lpWQLSelectStarList = NULL;
  5014. BOOL fIsThisDistinct = selectInfo.IsDistinct();
  5015. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 4\n"));
  5016. ISAMGetSelectStarList(&lpWQLSelectStarList, &selectInfo, lpISAM);
  5017. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 5\n"));
  5018. //clean up parse tree
  5019. FreeTree(lpstmt->lpSqlStmt);
  5020. lpstmt->lpSqlStmt = NULL;
  5021. //clean up passthrough map
  5022. TidyupPassthroughMap(passthroughMap);
  5023. passthroughMap = NULL;
  5024. ISAMStringConcat(&lpWQLStr, "SELECT ");
  5025. //Add tail end of previous string
  5026. char* oldString = fullWQL;
  5027. oldString += 7; //skip over SELECT
  5028. if ( fIsThisDistinct )
  5029. {
  5030. ISAMStringConcat(&lpWQLStr, "distinct ");
  5031. oldString += 9; //skip over DISTINCT
  5032. }
  5033. if (lpWQLSelectStarList)
  5034. {
  5035. ISAMStringConcat(&lpWQLStr, lpWQLSelectStarList);
  5036. }
  5037. ISAMStringConcat(&lpWQLStr, oldString);
  5038. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 6\n"));
  5039. CString sMessage;
  5040. sMessage.Format("\nWBEM ODBC Driver : detected select * : reparsing query :\n%s\n", lpWQLStr);
  5041. ODBCTRACE(sMessage);
  5042. // No. Create a PASSTHROUGH parse tree
  5043. sc = Parse(lpstmt, lpISAM, (LPUSTR) lpWQLStr,
  5044. lstrlen(lpWQLStr), &(lpstmt->lpSqlStmt));
  5045. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 7\n"));
  5046. if (lpWQLStr)
  5047. delete lpWQLStr;
  5048. if (sc != SQL_SUCCESS) {
  5049. FreeTree(lpstmt->lpSqlStmt);
  5050. lpstmt->lpSqlStmt = NULL;
  5051. delete lpISAMStatement->tempEnum;
  5052. delete lpISAMStatement->tempEnum2;
  5053. GlobalUnlock(h);
  5054. GlobalFree(h);
  5055. lpISAM->errcode = ISAM_NOTSUPPORTED;
  5056. return ISAM_NOTSUPPORTED;
  5057. }
  5058. //Generate WQL statement using parse tree
  5059. lpRootNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
  5060. lpSqlNode2 = ToNode(lpstmt->lpSqlStmt, lpRootNode->node.root.sql);
  5061. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 8\n"));
  5062. delete fullWQL;
  5063. fullWQL = NULL;
  5064. TableColumnInfo selectInfo2 (&lpRootNode, &lpSqlNode2, WQL_MULTI_TABLE);
  5065. selectInfo2.BuildFullWQL(&fullWQL, &passthroughMap);
  5066. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 9\n"));
  5067. //Extra check for aggregate functions what WQL does not support
  5068. //so we must fail SQL passthrough
  5069. if ( selectInfo2.HasAggregateFunctions() )
  5070. {
  5071. fHasAggregateFunctions = TRUE;
  5072. }
  5073. }
  5074. _bstr_t sqltextBSTR = fullWQL;
  5075. delete fullWQL;
  5076. CString wqlTextDebug(_T("\nWBEM ODBC Driver : WQL query : "));
  5077. wqlTextDebug += (LPCTSTR)sqltextBSTR;
  5078. wqlTextDebug += _T("\n");
  5079. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 7b\n"));
  5080. //Get instances by executing query
  5081. sc = WBEM_E_FAILED;
  5082. char* lpTblQualifier = NULL;
  5083. // if (idxQual != NO_STRING)
  5084. // {
  5085. // lpTblQualifier = (LPSTR) ToString(lpRootNode, idxQual);
  5086. // }
  5087. // else
  5088. {
  5089. lpTblQualifier = lpstmt->lpdbc->lpISAM->szDatabase;
  5090. }
  5091. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 7c\n"));
  5092. lpISAMStatement->pProv = new CSafeWbemServices();
  5093. lpISAMStatement->pProv->SetInterfacePtr(lpstmt->lpdbc->lpISAM, (LPUSTR) lpTblQualifier, (SWORD) lstrlen(lpTblQualifier));
  5094. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 7d\n"));
  5095. lpISAMStatement->passthroughMap = passthroughMap;
  5096. //Get prototype 'class' definition
  5097. if (lpISAMStatement->pProv->IsValid())
  5098. {
  5099. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 10\n"));
  5100. sc = lpISAMStatement->tempEnum2->SetInterfacePtr(lpstmt->lpdbc->lpISAM, WMI_PROTOTYPE, sqltextBSTR, lpISAMStatement->pProv);
  5101. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 11\n"));
  5102. //Extra check for aggregate functions what WQL does not support
  5103. //so we must fail SQL passthrough
  5104. if ( fHasAggregateFunctions )
  5105. {
  5106. sc = WBEM_E_NOT_SUPPORTED;
  5107. }
  5108. }
  5109. else
  5110. {
  5111. sc = WBEM_E_NOT_SUPPORTED;
  5112. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 7e\n"));
  5113. }
  5114. if ( (sc == WBEM_E_NOT_SUPPORTED) || (sc == WBEM_E_FAILED) || (sc == WBEM_E_INVALID_QUERY) || (sc == WBEM_E_NOT_FOUND) || (sc == WBEM_E_ACCESS_DENIED) )
  5115. {
  5116. if ( fHasAggregateFunctions )
  5117. {
  5118. ODBCTRACE(_T("\nWBEM ODBC Driver : Failing SQL passthrough as original SQL query has aggregate functions which WQL does not support\n"));
  5119. }
  5120. else
  5121. {
  5122. ODBCTRACE(_T("\nWBEM ODBC Driver : Getting prototype failed\n"));
  5123. }
  5124. //ExecQuery failed
  5125. delete lpISAMStatement->pProv;
  5126. lpISAMStatement->pProv = NULL;
  5127. TidyupPassthroughMap(lpISAMStatement->passthroughMap);
  5128. lpISAMStatement->passthroughMap = NULL;
  5129. FreeTree(lpstmt->lpSqlStmt);
  5130. lpstmt->lpSqlStmt = NULL;
  5131. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 12\n"));
  5132. delete lpISAMStatement->tempEnum;
  5133. delete lpISAMStatement->tempEnum2;
  5134. GlobalUnlock(h);
  5135. GlobalFree(h);
  5136. lpISAM->errcode = ISAM_NOTSUPPORTED;
  5137. return ISAM_NOTSUPPORTED;
  5138. }
  5139. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 12\n"));
  5140. IWbemServicesPtr myServicesPtr = NULL;
  5141. ISAMGetIWbemServices(lpISAM, *(lpISAMStatement->pProv), myServicesPtr);
  5142. IEnumWbemClassObjectPtr myIEnumWbemClassObject = NULL;
  5143. lpISAMStatement->tempEnum2->GetInterfacePtr(myIEnumWbemClassObject);
  5144. // CBString myServerStr;
  5145. // myServerStr.AddString( (LPSTR)lpISAM->szServer, FALSE );
  5146. // CServerLocationCheck myCheck (myServerStr);
  5147. BOOL fIsLocalConnection = lpISAM->fIsLocalConnection;//myCheck.IsLocal();
  5148. ISAMSetCloaking2(myIEnumWbemClassObject,
  5149. fIsLocalConnection,
  5150. lpISAM->fW2KOrMore,
  5151. lpISAM->dwAuthLevel,
  5152. lpISAM->dwImpLevel,
  5153. lpISAM->gpAuthIdentity);
  5154. /*
  5155. if ( fIsLocalConnection && IsW2KOrMore() )
  5156. {
  5157. WbemSetDynamicCloaking(myIEnumWbemClassObject, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
  5158. }
  5159. else
  5160. {
  5161. SetInterfaceSecurityEx(myIEnumWbemClassObject,
  5162. lpISAM->gpAuthIdentity,
  5163. gpPrincipal,
  5164. lpISAM->dwAuthLevel,
  5165. lpISAM->dwImpLevel);
  5166. }
  5167. */
  5168. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 13\n"));
  5169. //There should be only 1 instance which is the class definition
  5170. ULONG puReturned = 0;
  5171. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 14\n"));
  5172. myIEnumWbemClassObject->Reset();
  5173. if (myIEnumWbemClassObject->Next(-1, 1, &(lpISAMStatement->classDef), &puReturned) != S_OK)
  5174. {
  5175. ODBCTRACE(_T("\nWBEM ODBC Driver : Getting Prototype instance failed\n"));
  5176. delete lpISAMStatement->pProv;
  5177. lpISAMStatement->pProv = NULL;
  5178. TidyupPassthroughMap(lpISAMStatement->passthroughMap);
  5179. lpISAMStatement->passthroughMap = NULL;
  5180. FreeTree(lpstmt->lpSqlStmt);
  5181. lpstmt->lpSqlStmt = NULL;
  5182. delete lpISAMStatement->tempEnum;
  5183. delete lpISAMStatement->tempEnum2;
  5184. GlobalUnlock(h);
  5185. GlobalFree(h);
  5186. lpISAM->errcode = ISAM_NOTSUPPORTED;
  5187. return ISAM_NOTSUPPORTED;
  5188. }
  5189. //Now execute the real query
  5190. if (lpISAMStatement->pProv->IsValid())
  5191. {
  5192. sc = lpISAMStatement->tempEnum->SetInterfacePtr(lpISAM, WMI_EXEC_FWD_ONLY, sqltextBSTR, lpISAMStatement->pProv);
  5193. ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 15\n"));
  5194. //As semi-synchronous does not indicate if any error occurs
  5195. //we need to get the first record back now
  5196. if ( SUCCEEDED(sc) )
  5197. {
  5198. IEnumWbemClassObjectPtr myIEnumWbemClassObj1 = NULL;
  5199. lpISAMStatement->tempEnum->GetInterfacePtr(myIEnumWbemClassObj1);
  5200. ISAMSetCloaking2(myIEnumWbemClassObj1,
  5201. fIsLocalConnection,
  5202. lpISAM->fW2KOrMore,
  5203. lpISAM->dwAuthLevel,
  5204. lpISAM->dwImpLevel,
  5205. lpISAM->gpAuthIdentity);
  5206. /*
  5207. if ( fIsLocalConnection && IsW2KOrMore() )
  5208. {
  5209. WbemSetDynamicCloaking(myIEnumWbemClassObj1, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
  5210. }
  5211. else
  5212. {
  5213. SetInterfaceSecurityEx(myIEnumWbemClassObj1,
  5214. lpISAM->gpAuthIdentity,
  5215. gpPrincipal,
  5216. lpISAM->dwAuthLevel,
  5217. lpISAM->dwImpLevel);
  5218. }
  5219. */
  5220. ULONG numReturned = 0;
  5221. sc = myIEnumWbemClassObj1->Next(-1, 1, &(lpISAMStatement->firstPassthrInst), &numReturned);
  5222. }
  5223. }
  5224. else
  5225. {
  5226. sc = WBEM_E_NOT_SUPPORTED;
  5227. }
  5228. CString sSCODE;
  5229. sSCODE.Format("\nMAGIC NUMBER = 0x%X\n", sc);
  5230. ODBCTRACE(sSCODE);
  5231. if ( sc != WBEM_S_NO_ERROR )
  5232. {
  5233. ODBCTRACE(_T("\nWBEM ODBC Driver : Passthrough SQL Failed or Not Supported\n"));
  5234. //ExecQuery failed
  5235. lpISAM->errcode = ERR_PASSTGHONLY_NOTSUPP;
  5236. //default error string
  5237. ((char*)lpstmt->szISAMError)[0] = 0;
  5238. CString sDefaultError;
  5239. sDefaultError.LoadString(STR_EXECQUERY);
  5240. sprintf((char*)lpstmt->szError, "%s 0x%X", sDefaultError, sc);
  5241. lpISAM->errcode = ERR_WBEM_SPECIFIC;
  5242. //Test here
  5243. //need to get the WBEM specific error
  5244. IErrorInfo* pEI = NULL;
  5245. IWbemClassObject *pErrorObject = NULL;
  5246. if(GetErrorInfo(0, &pEI) == S_OK)
  5247. {
  5248. pEI->QueryInterface(IID_IWbemClassObject, (void**)&pErrorObject);
  5249. pEI->Release();
  5250. }
  5251. if (pErrorObject)
  5252. {
  5253. VARIANT varString;
  5254. if (pErrorObject->InheritsFrom(L"__NotifyStatus") != WBEM_NO_ERROR)
  5255. {
  5256. // fprintf(stdout, "Unrecognized Error Object type\n");
  5257. }
  5258. else if (pErrorObject->InheritsFrom(L"__ExtendedStatus") == WBEM_NO_ERROR)
  5259. {
  5260. sc = pErrorObject->Get(L"Description", 0L, &varString, NULL, NULL);
  5261. if ( (sc == S_OK) && (varString.vt == VT_BSTR) )
  5262. {
  5263. lstrcpy((char*)lpstmt->szISAMError, "");
  5264. wcstombs((char*)lpstmt->szError,varString.bstrVal ? varString.bstrVal : L" ", MAX_ERROR_LENGTH);
  5265. lpISAM->errcode = ERR_WBEM_SPECIFIC;
  5266. VariantClear(&varString);
  5267. }
  5268. }
  5269. pErrorObject->Release();
  5270. }
  5271. delete lpISAMStatement->pProv;
  5272. lpISAMStatement->pProv = NULL;
  5273. lpISAMStatement->classDef->Release();
  5274. TidyupPassthroughMap(lpISAMStatement->passthroughMap);
  5275. lpISAMStatement->passthroughMap = NULL;
  5276. SWORD savedErrorCode = lpISAM->errcode;
  5277. FreeTree(lpstmt->lpSqlStmt);
  5278. lpstmt->lpSqlStmt = NULL;
  5279. delete lpISAMStatement->tempEnum;
  5280. delete lpISAMStatement->tempEnum2;
  5281. GlobalUnlock(h);
  5282. GlobalFree(h);
  5283. lpISAM->errcode = savedErrorCode;
  5284. return ISAM_NOTSUPPORTED;
  5285. }
  5286. //ExecQuery succeeded
  5287. myServicesPtr = NULL;
  5288. ISAMGetIWbemServices(lpISAM, *(lpISAMStatement->pProv), myServicesPtr);
  5289. //free up enumeration before resetting to NULL
  5290. IEnumWbemClassObject* tempEnum = myIEnumWbemClassObject.Detach();
  5291. if (tempEnum)
  5292. tempEnum->Release();
  5293. myIEnumWbemClassObject = NULL;
  5294. lpISAMStatement->tempEnum->GetInterfacePtr(myIEnumWbemClassObject);
  5295. ISAMSetCloaking2(myIEnumWbemClassObject,
  5296. fIsLocalConnection,
  5297. lpISAM->fW2KOrMore,
  5298. lpISAM->dwAuthLevel,
  5299. lpISAM->dwImpLevel,
  5300. lpISAM->gpAuthIdentity);
  5301. /*
  5302. if ( fIsLocalConnection && IsW2KOrMore() )
  5303. {
  5304. WbemSetDynamicCloaking(myIEnumWbemClassObject, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
  5305. }
  5306. else
  5307. {
  5308. SetInterfaceSecurityEx(myIEnumWbemClassObject,
  5309. lpISAM->gpAuthIdentity,
  5310. gpPrincipal,
  5311. lpISAM->dwAuthLevel,
  5312. lpISAM->dwImpLevel);
  5313. }
  5314. */
  5315. ODBCTRACE(_T("\nWBEM ODBC Driver : Passthrough SQL succeeded, getting instances\n"));
  5316. //Copy table name
  5317. lpszTablename[0] = 0;
  5318. wchar_t* virTbl = WBEMDR32_VIRTUAL_TABLE;
  5319. wcstombs((char*)lpszTablename, virTbl, MAX_TABLE_NAME_LENGTH);
  5320. lpszTablename[MAX_TABLE_NAME_LENGTH] = 0;
  5321. //Free the Parse tree.
  5322. //A new Parse tree will be created for
  5323. //SELECT * FROM WBEMDR32VirtualTable
  5324. FreeTree(lpstmt->lpSqlStmt);
  5325. lpstmt->lpSqlStmt = NULL;
  5326. }
  5327. #else
  5328. else if ((cbSqlStr == 3) && (!_fmemicmp(szSqlStr, "SQL", 3))) {
  5329. s_lstrcpy(lpszTablename, "SQL");
  5330. *lpParameterCount = 0;
  5331. lpISAMStatement->lpISAM = lpISAM;
  5332. lpISAMStatement->resultSet = TRUE;
  5333. lpISAMStatement->lpszParam1 = NULL;
  5334. lpISAMStatement->cbParam1 = SQL_NULL_DATA;
  5335. lpISAMStatement->lpszParam2 = NULL;
  5336. lpISAMStatement->cbParam2 = SQL_NULL_DATA;
  5337. }
  5338. else {
  5339. test if we reach here
  5340. delete lpISAMStatement->tempEnum;
  5341. delete lpISAMStatement->tempEnum2;
  5342. GlobalUnlock(h);
  5343. GlobalFree(h);
  5344. lpISAM->errcode = ISAM_NOTSUPPORTED;
  5345. return ISAM_NOTSUPPORTED;
  5346. }
  5347. #endif
  5348. *lplpISAMStatement = lpISAMStatement;
  5349. return NO_ISAM_ERR;
  5350. }
  5351. // Checked for SetInterfaceSecurityEx on IWbemServices
  5352. void INTFUNC ISAMGetSelectStarList(char** lpWQLSelectStarList, TableColumnInfo* pSelectInfo, LPISAM lpISAM)
  5353. {
  5354. //First check you have one table in the select list
  5355. char* mytable = NULL;
  5356. BOOL fDummyValue = FALSE;
  5357. pSelectInfo->BuildTableList(&mytable, fDummyValue);
  5358. if ( mytable && lstrlen (mytable) )
  5359. {
  5360. //got the table, now fetch the column names
  5361. CBString pBStrTableName;
  5362. pBStrTableName.AddString((LPSTR)mytable, FALSE);
  5363. IWbemContext* pContext = ISAMCreateLocaleIDContextObject(lpISAM->m_Locale);
  5364. //Get class object based on table name
  5365. IWbemClassObjectPtr pSingleTable = NULL;
  5366. IWbemServicesPtr pGateway = NULL;
  5367. ISAMGetGatewayServer(pGateway, lpISAM, (LPUSTR)lpISAM->szDatabase, (SWORD) lstrlen(lpISAM->szDatabase));
  5368. if ( FAILED(pGateway->GetObject(pBStrTableName.GetString(), 0, pContext, &pSingleTable, NULL)))
  5369. {
  5370. if (pContext)
  5371. pContext->Release();
  5372. if (mytable)
  5373. delete mytable;
  5374. return;
  5375. }
  5376. if (pContext)
  5377. pContext->Release();
  5378. //Get the names of all the properties/columns
  5379. SAFEARRAY FAR* rgSafeArray = NULL;
  5380. SCODE scT = pSingleTable->GetNames ( NULL, 0, NULL, &rgSafeArray );
  5381. //Work out number of properties/columns
  5382. LONG iLBound = 0;
  5383. LONG iUBound = 0;
  5384. SafeArrayGetLBound(rgSafeArray, 1, &iLBound );
  5385. SafeArrayGetUBound(rgSafeArray, 1, &iUBound );
  5386. //Loop through column names
  5387. char pColumnName [MAX_COLUMN_NAME_LENGTH+1];
  5388. BOOL fFirstTime = TRUE;
  5389. for (LONG loop = iLBound; loop <= iUBound; loop++)
  5390. {
  5391. BSTR lpbString;
  5392. if ( FAILED(SafeArrayGetElement(rgSafeArray, &loop, &lpbString)) )
  5393. {
  5394. if (mytable)
  5395. delete mytable;
  5396. SafeArrayUnlock(rgSafeArray); //SAI ADDED
  5397. SafeArrayDestroy(rgSafeArray);//SAI ADDED
  5398. //(11) Should we also release pSingleTable
  5399. return;
  5400. }
  5401. //copy column name
  5402. pColumnName[0] = 0;
  5403. wcstombs(pColumnName, lpbString, MAX_COLUMN_NAME_LENGTH);
  5404. pColumnName[MAX_COLUMN_NAME_LENGTH] = 0;
  5405. //filters - check for system properties
  5406. BOOL fAddToList = TRUE;
  5407. if (! lpISAM->fSysProps && !_strnicmp("__", pColumnName, 2))
  5408. {
  5409. fAddToList = FALSE;
  5410. }
  5411. //filters - check for lazy properties
  5412. if (fAddToList)
  5413. {
  5414. BOOL fIsLazyProperty = FALSE;
  5415. //Now get the qualifiers (if available)
  5416. IWbemQualifierSet* pQualifierSet = NULL;
  5417. if ( S_OK == (pSingleTable->GetPropertyQualifierSet
  5418. (lpbString, &pQualifierSet)) )
  5419. {
  5420. //Get the lazy qualifer (if applicable)
  5421. VARIANT pValLazy;
  5422. BSTR lazyStr = SysAllocString(WBEMDR32_L_LAZY);
  5423. if ( S_OK == (pQualifierSet->Get(lazyStr, 0, &pValLazy, NULL)) )
  5424. {
  5425. fAddToList = FALSE;
  5426. VariantClear(&pValLazy);
  5427. }
  5428. SysFreeString(lazyStr);
  5429. //Tidy up
  5430. if (pQualifierSet)
  5431. pQualifierSet->Release();
  5432. }
  5433. }
  5434. //add to select list
  5435. if (fAddToList)
  5436. {
  5437. if (!fFirstTime)
  5438. {
  5439. ISAMStringConcat(lpWQLSelectStarList, ", ");
  5440. }
  5441. ISAMStringConcat(lpWQLSelectStarList, pColumnName);
  5442. fFirstTime = FALSE;
  5443. }
  5444. SysFreeString(lpbString);
  5445. }
  5446. }
  5447. }
  5448. /***************************************************************************/
  5449. SWORD INTFUNC ISAMParameter(LPISAMSTATEMENT lpISAMStatement, UWORD ipar,
  5450. SWORD fCType, PTR rgbValue, SDWORD cbValue)
  5451. {
  5452. lpISAMStatement->lpISAM->errcode = NO_ISAM_ERR;
  5453. if (fCType != SQL_C_CHAR) {
  5454. lpISAMStatement->lpISAM->errcode = ISAM_ERROR;
  5455. return ISAM_ERROR;
  5456. }
  5457. if (cbValue > MAX_CHAR_LITERAL_LENGTH) {
  5458. lpISAMStatement->lpISAM->errcode = ISAM_ERROR;
  5459. return ISAM_ERROR;
  5460. }
  5461. if (cbValue == SQL_NULL_DATA)
  5462. cbValue = 0;
  5463. if (ipar == 1) {
  5464. lpISAMStatement->lpszParam1 = (LPSTR)rgbValue;
  5465. lpISAMStatement->cbParam1 = cbValue;
  5466. }
  5467. else if (ipar == 2) {
  5468. lpISAMStatement->lpszParam2 = (LPSTR)rgbValue;
  5469. lpISAMStatement->cbParam2 = cbValue;
  5470. }
  5471. else {
  5472. lpISAMStatement->lpISAM->errcode = ISAM_ERROR;
  5473. return ISAM_ERROR;
  5474. }
  5475. return NO_ISAM_ERR;
  5476. }
  5477. /***************************************************************************/
  5478. SWORD INTFUNC ISAMExecute(LPISAMSTATEMENT lpISAMStatement,
  5479. SDWORD FAR *lpcRowCount)
  5480. {
  5481. lpISAMStatement->lpISAM->errcode = NO_ISAM_ERR;
  5482. if (lpISAMStatement->resultSet)
  5483. {
  5484. // *lpcRowCount = 2;
  5485. //Return number of READ instances
  5486. //we never know the total number of instances returned
  5487. //via passthrough SQL (we get them in batches of 10)
  5488. //*lpcRowCount = lpISAMStatement->pAllRecords->GetCount();
  5489. *lpcRowCount = 0;
  5490. }
  5491. else
  5492. {
  5493. MessageBox(NULL, lpISAMStatement->lpszParam1,
  5494. lpISAMStatement->lpszParam2, 0);
  5495. *lpcRowCount = 0;
  5496. }
  5497. return NO_ISAM_ERR;
  5498. }
  5499. /***************************************************************************/
  5500. SWORD INTFUNC ISAMFreeStatement(LPISAMSTATEMENT lpISAMStatement)
  5501. {
  5502. lpISAMStatement->lpISAM->errcode = NO_ISAM_ERR;
  5503. //Free 1st SQL passthrough instance (if not already freed)
  5504. if (lpISAMStatement->firstPassthrInst)
  5505. {
  5506. lpISAMStatement->firstPassthrInst->Release();
  5507. lpISAMStatement->firstPassthrInst = NULL;
  5508. }
  5509. //Free Enumeration of Class definitions
  5510. if (lpISAMStatement->tempEnum)
  5511. {
  5512. delete lpISAMStatement->tempEnum;
  5513. lpISAMStatement->tempEnum = NULL;
  5514. }
  5515. if (lpISAMStatement->tempEnum2)
  5516. {
  5517. delete lpISAMStatement->tempEnum2;
  5518. lpISAMStatement->tempEnum2 = NULL;
  5519. }
  5520. if (lpISAMStatement->pProv)
  5521. {
  5522. delete lpISAMStatement->pProv;
  5523. lpISAMStatement->pProv = NULL;
  5524. }
  5525. if (lpISAMStatement->passthroughMap)
  5526. {
  5527. TidyupPassthroughMap(lpISAMStatement->passthroughMap);
  5528. lpISAMStatement->passthroughMap = NULL;
  5529. }
  5530. GlobalUnlock(GlobalPtrHandle(lpISAMStatement));
  5531. GlobalFree(GlobalPtrHandle(lpISAMStatement));
  5532. return NO_ISAM_ERR;
  5533. }
  5534. /***************************************************************************/
  5535. SWORD INTFUNC ISAMSetTxnIsolation(LPISAM lpISAM, UDWORD fTxnIsolationLevel)
  5536. {
  5537. /* Select one of the isolation modes from TxnIsolationOption */
  5538. if (!(fTxnIsolationLevel & lpISAM->fTxnIsolationOption)) {
  5539. lpISAM->errcode = ISAM_NOTSUPPORTED;
  5540. return ISAM_NOTSUPPORTED;
  5541. }
  5542. lpISAM->errcode = NO_ISAM_ERR;
  5543. return NO_ISAM_ERR;
  5544. }
  5545. /***************************************************************************/
  5546. SWORD INTFUNC ISAMCommitTxn(LPISAM lpISAM)
  5547. {
  5548. lpISAM->errcode = NO_ISAM_ERR;
  5549. return NO_ISAM_ERR;
  5550. }
  5551. /***************************************************************************/
  5552. SWORD INTFUNC ISAMRollbackTxn(LPISAM lpISAM)
  5553. {
  5554. lpISAM->errcode = NO_ISAM_ERR;
  5555. return NO_ISAM_ERR;
  5556. }
  5557. /***************************************************************************/
  5558. SWORD INTFUNC ISAMClose(LPISAM lpISAM)
  5559. {
  5560. lpISAM->errcode = NO_ISAM_ERR;
  5561. if (lpISAM->pNamespaceMap)
  5562. {
  5563. if (lpISAM->pNamespaceMap->GetCount ())
  5564. {
  5565. CString key;
  5566. CNamespace *pNamespace;
  5567. for (POSITION pos = lpISAM->pNamespaceMap->GetStartPosition (); pos != NULL; )
  5568. {
  5569. if (pos)
  5570. {
  5571. lpISAM->pNamespaceMap->GetNextAssoc (pos, key, (CObject*&)pNamespace);
  5572. delete pNamespace;
  5573. }
  5574. }
  5575. }
  5576. delete lpISAM->pNamespaceMap;
  5577. }
  5578. if (lpISAM->m_Locale)
  5579. {
  5580. delete (lpISAM->m_Locale);
  5581. lpISAM->m_Locale = NULL;
  5582. }
  5583. if (lpISAM->m_Authority)
  5584. {
  5585. delete (lpISAM->m_Authority);
  5586. lpISAM->m_Authority = NULL;
  5587. }
  5588. if (lpISAM->gpAuthIdentity)
  5589. {
  5590. WbemFreeAuthIdentity( lpISAM->gpAuthIdentity );
  5591. lpISAM->gpAuthIdentity = NULL;
  5592. }
  5593. if (lpISAM->Impersonate)
  5594. {
  5595. delete (lpISAM->Impersonate);
  5596. lpISAM->Impersonate = NULL;
  5597. }
  5598. if (lpISAM->hKernelApi)
  5599. {
  5600. BOOL status = FreeLibrary(lpISAM->hKernelApi);
  5601. lpISAM->hKernelApi = NULL;
  5602. if (! status)
  5603. {
  5604. DWORD err = GetLastError();
  5605. CString message ("\n\n***** FreeLibrary(2) KERNEL32 failed : %ld*****\n\n", err);
  5606. ODBCTRACE(message);
  5607. }
  5608. }
  5609. GlobalUnlock(GlobalPtrHandle(lpISAM));
  5610. GlobalFree(GlobalPtrHandle(lpISAM));
  5611. return NO_ISAM_ERR;
  5612. }
  5613. /***************************************************************************/
  5614. void INTFUNC ISAMGetErrorMessage(LPISAM lpISAM, LPUSTR lpszErrorMessage)
  5615. {
  5616. LoadString(s_hModule, lpISAM->errcode, (LPSTR)lpszErrorMessage,
  5617. MAX_ERROR_LENGTH+1);
  5618. }
  5619. /***************************************************************************/
  5620. LPSQLTYPE INTFUNC ISAMGetColumnType(
  5621. LPISAMTABLEDEF lpISAMTableDef,
  5622. UWORD icol)
  5623. {
  5624. /* There may be more than one entry in SQLTypes[] for any given SQL_x type, */
  5625. /* therefore we need to compare on the type name string */
  5626. ClassColumnInfoBase* cInfoBase = lpISAMTableDef->pColumnInfo;
  5627. if ( !cInfoBase->IsValid() )
  5628. {
  5629. return NULL;
  5630. }
  5631. UWORD cNumberOfCols = cInfoBase->GetNumberOfColumns();
  5632. if (icol >= cNumberOfCols)
  5633. return NULL;
  5634. UCHAR* puTypeName = NULL;
  5635. if ( !cInfoBase->GetTypeName(icol, puTypeName) )
  5636. {
  5637. return NULL;
  5638. }
  5639. UCHAR szTypeName[MAX_COLUMN_NAME_LENGTH+1];
  5640. LONG cLength = strlen ((char*)puTypeName);
  5641. memcpy(szTypeName, (char*)puTypeName, cLength);
  5642. szTypeName[cLength] = 0;
  5643. return GetType2(szTypeName);
  5644. }
  5645. /***************************************************************************/
  5646. BOOL INTFUNC ISAMCaseSensitive(LPISAM lpISAM)
  5647. {
  5648. return FALSE;
  5649. }
  5650. /***************************************************************************/
  5651. LPUSTR INTFUNC ISAMName(LPISAM lpISAM)
  5652. {
  5653. char* pName = new char [3 + 1];
  5654. pName[0] = 0;
  5655. sprintf (pName, "%s", "WMI");
  5656. return (LPUSTR)pName;
  5657. /*
  5658. char* lpRootDb = (char*)lpISAM->szRootDb;
  5659. IWbemServices* pProv = ISAMGetGatewayServer(lpISAM, (LPUSTR)lpRootDb, lstrlen(lpRootDb));
  5660. if (!pProv)
  5661. {
  5662. return NULL;
  5663. }
  5664. IWbemClassObject * pClassObj = NULL;
  5665. char* pName = NULL;
  5666. BSTR hmomIdBSTR = SysAllocString(WBEMDR32_L_CIMOMIDENTIFICATION);
  5667. IWbemContext* pContext = ISAMCreateLocaleIDContextObject(lpISAM->m_Locale);
  5668. SCODE sc = pProv->GetObject(hmomIdBSTR, 0, pContext, &pClassObj, NULL);
  5669. if (pContext)
  5670. pContext->Release();
  5671. SysFreeString(hmomIdBSTR);
  5672. if (sc == S_OK)
  5673. {
  5674. VARIANTARG var;
  5675. VariantInit(&var);
  5676. BSTR serverBSTR = SysAllocString(WBEMDR32_L_SERVER);
  5677. pClassObj->Get(serverBSTR,0,&var, NULL, NULL);
  5678. SysFreeString(serverBSTR);
  5679. LONG lLength = wcslen(var.bstrVal);
  5680. char* pTemp = new char [lLength + 1];
  5681. pTemp[0] = 0;
  5682. wcstombs(pTemp, var.bstrVal, lLength);
  5683. pTemp[lLength] = 0;
  5684. pName = new char [lLength + 10];
  5685. pName[0] = 0;
  5686. lstrcpy(pName, "MOServer@");
  5687. lstrcat(pName, pTemp);
  5688. delete pTemp;
  5689. VariantClear(&var);
  5690. pClassObj->Release();
  5691. }
  5692. if (pProv)
  5693. pProv->Release();
  5694. return (LPUSTR)pName;
  5695. */
  5696. }
  5697. /***************************************************************************/
  5698. // Checked for SetInterfaceSecurityEx on IWbemServices
  5699. LPUSTR INTFUNC ISAMServer(LPISAM lpISAM)
  5700. {
  5701. ODBCTRACE("\nWBEM ODBC Driver : ISAMServer\n");
  5702. char* lpRootDb = (char*)lpISAM->szRootDb;
  5703. IWbemServicesPtr pProv = NULL;
  5704. ISAMGetGatewayServer(pProv, lpISAM, (LPUSTR)lpRootDb, (SWORD) lstrlen(lpRootDb));
  5705. if (pProv == NULL)
  5706. {
  5707. return NULL;
  5708. }
  5709. IWbemClassObject * pClassObj = NULL;
  5710. char* pName = NULL;
  5711. BSTR hmomIdBSTR = SysAllocString(WBEMDR32_L_CIMOMIDENTIFICATION);
  5712. IWbemContext* pContext = ISAMCreateLocaleIDContextObject(lpISAM->m_Locale);
  5713. SCODE sc = pProv->GetObject(hmomIdBSTR, 0, pContext, &pClassObj, NULL);
  5714. if (pContext)
  5715. pContext->Release();
  5716. SysFreeString(hmomIdBSTR);
  5717. if (sc == S_OK)
  5718. {
  5719. VARIANTARG var;
  5720. BSTR serverBSTR = SysAllocString(WBEMDR32_L_SERVER);
  5721. pClassObj->Get(serverBSTR,0,&var, NULL, NULL);
  5722. SysFreeString(serverBSTR);
  5723. LONG lLength = wcslen(var.bstrVal);
  5724. pName = new char [lLength + 1];
  5725. pName[0] = 0;
  5726. wcstombs(pName, var.bstrVal, lLength);
  5727. pName[lLength] = 0;
  5728. VariantClear(&var);
  5729. long rc = pClassObj->Release();
  5730. }
  5731. return (LPUSTR)pName;
  5732. }
  5733. /***************************************************************************/
  5734. LPUSTR INTFUNC ISAMVersion(LPISAM lpISAM)
  5735. {
  5736. char* pVersion = new char [10 + 1];
  5737. pVersion[0] = 0;
  5738. sprintf (pVersion, "%s", "01.00.0000");
  5739. return (LPUSTR)pVersion;
  5740. }
  5741. /***************************************************************************/
  5742. LPCUSTR INTFUNC ISAMDriver(LPISAM lpISAM)
  5743. {
  5744. return (LPCUSTR) "WBEMDR32.DLL";
  5745. }
  5746. /***************************************************************************/
  5747. SWORD INTFUNC ISAMMaxTableNameLength(LPISAM lpISAM)
  5748. {
  5749. return MAX_TABLE_NAME_LENGTH;//i.e.128
  5750. }
  5751. /***************************************************************************/
  5752. SWORD INTFUNC ISAMMaxColumnNameLength(LPISAM lpISAM)
  5753. {
  5754. return MAX_COLUMN_NAME_LENGTH;//i.e.128
  5755. }
  5756. /***************************************************************************/
  5757. LPUSTR INTFUNC ISAMUser(LPISAM lpISAM)
  5758. {
  5759. return (LPUSTR) lpISAM->szUser;
  5760. }
  5761. /***************************************************************************/
  5762. LPUSTR INTFUNC ISAMDatabase(LPISAM lpISAM)
  5763. {
  5764. return (LPUSTR) lpISAM->szDatabase;
  5765. }
  5766. /***************************************************************************/
  5767. int INTFUNC ISAMSetDatabase (LPISAM lpISAM, LPUSTR database)
  5768. {
  5769. if (database && s_lstrlen(database) < MAX_DATABASE_NAME_LENGTH)
  5770. {
  5771. s_lstrcpy (lpISAM->szDatabase, database);
  5772. return TRUE;
  5773. }
  5774. else
  5775. return FALSE;
  5776. }
  5777. /***************************************************************************/
  5778. LPUSTR INTFUNC ISAMRoot (LPISAM lpISAM)
  5779. {
  5780. return (LPUSTR) lpISAM->szRootDb;
  5781. }
  5782. /***************************************************************************/
  5783. /* This code was copied from the original Dr DeeBee code and moved to */
  5784. /* this separate function for our uses */
  5785. static SWORD ISAMGetDoubleFromString(BSTR &pString, SDWORD cbValueMax, double &d, BOOL & isNull, BOOL &foundDecimalPoint)
  5786. {
  5787. isNull = TRUE;
  5788. BOOL neg = TRUE;
  5789. char* pTemp = new char [cbValueMax + 1];
  5790. pTemp[0] = 0;
  5791. SDWORD cbLen = wcstombs( pTemp, pString, cbValueMax);
  5792. pTemp[cbValueMax] = 0;
  5793. for (SDWORD i=0; i < cbLen; i++)
  5794. {
  5795. if (*pTemp != ' ')
  5796. break;
  5797. pTemp++;
  5798. }
  5799. neg = FALSE;
  5800. if (i < cbLen)
  5801. {
  5802. if (*pTemp == '-')
  5803. {
  5804. neg = TRUE;
  5805. pTemp++;
  5806. i++;
  5807. }
  5808. }
  5809. d = 0.0;
  5810. short scale = 0;
  5811. BOOL negexp = FALSE;
  5812. foundDecimalPoint = FALSE;
  5813. for (;i < cbLen; i++)
  5814. {
  5815. if (!foundDecimalPoint && (*pTemp == '.'))
  5816. foundDecimalPoint = TRUE;
  5817. else
  5818. {
  5819. if ((*pTemp == 'E') || (*pTemp == 'e'))
  5820. {
  5821. pTemp++;
  5822. i++;
  5823. if (i < cbLen)
  5824. {
  5825. if (*pTemp == '-')
  5826. {
  5827. negexp = TRUE;
  5828. pTemp++;
  5829. i++;
  5830. }
  5831. else if (*pTemp == '+')
  5832. {
  5833. negexp = FALSE;
  5834. pTemp++;
  5835. i++;
  5836. }
  5837. else
  5838. negexp = FALSE;
  5839. }
  5840. else
  5841. negexp = FALSE;
  5842. short exp = 0;
  5843. for (;i < cbLen; i++)
  5844. {
  5845. if ((*pTemp < '0') || (*pTemp > '9'))
  5846. {
  5847. delete pTemp;
  5848. return DBASE_ERR_CONVERSIONERROR;
  5849. }
  5850. exp = (exp * 10) + (*pTemp - '0');
  5851. pTemp++;
  5852. }
  5853. if (negexp)
  5854. scale = scale + exp;
  5855. else
  5856. scale = scale - exp;
  5857. break;
  5858. }
  5859. if ((*pTemp < '0') || (*pTemp > '9'))
  5860. {
  5861. delete pTemp;
  5862. return DBASE_ERR_CONVERSIONERROR;
  5863. }
  5864. d = (d * 10) + (*pTemp - '0');
  5865. isNull = FALSE;
  5866. if (foundDecimalPoint)
  5867. scale++;
  5868. }
  5869. pTemp++;
  5870. }
  5871. for (; (0 < scale); scale--)
  5872. d /= 10;
  5873. for (; (0 > scale); scale++)
  5874. d *= 10;
  5875. if (neg)
  5876. d = -d;
  5877. delete pTemp;
  5878. return DBASE_ERR_SUCCESS;
  5879. }
  5880. /***************************************************************************/
  5881. /* Template class to decode array variant value */
  5882. /* */
  5883. /* The fIsBinaryOutput parameter indicates if you */
  5884. /* want the output value a binary data or a string */
  5885. template <class T> SWORD ISAMGetArrayInfo (VARIANT &vVariantVal, T theValue,
  5886. PTR rgbValue, SDWORD cbValueMax, SDWORD FAR* pcbValue,
  5887. BOOL fIsBinaryOutput, SWORD wDSDT, UDWORD cbPrecision, long myVirIndex = -1)
  5888. {
  5889. //Check if we want all elements of the array or just one element
  5890. BOOL fAllElements = TRUE;
  5891. if (myVirIndex != -1)
  5892. {
  5893. fAllElements = FALSE;
  5894. }
  5895. //Get the value
  5896. SAFEARRAY FAR* pArray = vVariantVal.parray;
  5897. SafeArrayLock(pArray);
  5898. //Find out the bounds of the array
  5899. //Get the upper and lower bounds
  5900. long lLowerBound;
  5901. SafeArrayGetLBound(pArray, 1, &lLowerBound);
  5902. long lUpperBound;
  5903. SafeArrayGetUBound(pArray, 1, &lUpperBound);
  5904. *pcbValue = 0;
  5905. if (cbValueMax)
  5906. ((char*)rgbValue)[0] = 0;
  5907. //Initialize
  5908. long cCount = 0;
  5909. SWORD wElemSize = sizeof (T);
  5910. //Setup the filter for the data
  5911. char filter [20];
  5912. filter[0] = 0;
  5913. //Character string length use to represent each element of array
  5914. SWORD wFullCharSize = 0;
  5915. if (!fIsBinaryOutput)
  5916. {
  5917. //Also setup the filter for the data
  5918. filter[0] = 0;
  5919. if ( wDSDT == WBEM_DSDT_REAL_ARRAY )
  5920. {
  5921. if (fAllElements)
  5922. {
  5923. //For character string output the format will be [precision.6f]
  5924. //Thus, we need room for the [ ] and the 'precision.6'
  5925. wFullCharSize = 9 + REAL_PRECISION;
  5926. sprintf (filter, "%s%d%s", "[%", REAL_PRECISION, ".6g]");
  5927. }
  5928. else
  5929. {
  5930. //For character string output the format will be precision.6f
  5931. //Thus, we need room for the 'precision.6'
  5932. wFullCharSize = 7 + REAL_PRECISION;
  5933. sprintf (filter, "%s%d%s", "%", REAL_PRECISION, ".6g");
  5934. }
  5935. }
  5936. else if ( wDSDT == WBEM_DSDT_DOUBLE_ARRAY )
  5937. {
  5938. if (fAllElements)
  5939. {
  5940. //For character string output the format will be [precision.6f]
  5941. //Thus, we need room for the [ ] and the 'precision.6'
  5942. wFullCharSize = 9 + DOUBLE_PRECISION;
  5943. sprintf (filter, "%s%d%s", "[%", DOUBLE_PRECISION, ".6g]");
  5944. }
  5945. else
  5946. {
  5947. //For character string output the format will be precision.6f
  5948. //Thus, we need room for the 'precision.6'
  5949. wFullCharSize = 7 + DOUBLE_PRECISION;
  5950. sprintf (filter, "%s%d%s", "%", DOUBLE_PRECISION, ".6g");
  5951. }
  5952. }
  5953. else
  5954. {
  5955. //For character string output the format will be [precision]
  5956. //We add 1 to the precision if the type is signed
  5957. //Thus, we need room for the [ ] and the
  5958. //ie 2 extra characters for unsigned and 3 for signed
  5959. //Integer type
  5960. //Check if signed
  5961. switch (wDSDT)
  5962. {
  5963. case WBEM_DSDT_SINT8_ARRAY:
  5964. case WBEM_DSDT_SINT16_ARRAY:
  5965. case WBEM_DSDT_SINT32_ARRAY:
  5966. {
  5967. //Signed
  5968. ++cbPrecision;
  5969. if (fAllElements)
  5970. {
  5971. wFullCharSize = (SWORD) (cbPrecision + 2);
  5972. strcpy (filter, "[%ld]");
  5973. }
  5974. else
  5975. {
  5976. wFullCharSize = (SWORD) cbPrecision;
  5977. strcpy (filter, "%ld");
  5978. }
  5979. }
  5980. break;
  5981. case WBEM_DSDT_BOOL_ARRAY:
  5982. {
  5983. if (fAllElements)
  5984. {
  5985. wFullCharSize = (SWORD) (cbPrecision + 2);
  5986. strcpy (filter, "[%s]");
  5987. }
  5988. else
  5989. {
  5990. wFullCharSize = (SWORD) cbPrecision;
  5991. strcpy (filter, "%s");
  5992. }
  5993. }
  5994. break;
  5995. default:
  5996. {
  5997. if (fAllElements)
  5998. {
  5999. //Unsigned
  6000. wFullCharSize = (SWORD) (cbPrecision + 2);
  6001. strcpy (filter, "[%lu]");
  6002. }
  6003. else
  6004. {
  6005. //Unsigned
  6006. wFullCharSize = (SWORD) (cbPrecision);
  6007. strcpy (filter, "%lu");
  6008. }
  6009. }
  6010. break;
  6011. }
  6012. }
  6013. }
  6014. char* tempBuff = new char [wFullCharSize + 1];
  6015. //Loop through each entry to fetch the array data
  6016. BOOL fDoweHaveEnoughBufferSpace = FALSE;
  6017. long loop = 0;
  6018. for (long cIndex = lLowerBound; cIndex <= lUpperBound; cIndex++)
  6019. {
  6020. //Check we have enough buffer space
  6021. if (fIsBinaryOutput)
  6022. {
  6023. fDoweHaveEnoughBufferSpace = ((wElemSize + (*pcbValue)) <= cbValueMax) ? TRUE : FALSE;
  6024. }
  6025. else
  6026. {
  6027. fDoweHaveEnoughBufferSpace = ((wFullCharSize + (*pcbValue)) <= cbValueMax) ? TRUE : FALSE;
  6028. }
  6029. if ( fDoweHaveEnoughBufferSpace)
  6030. {
  6031. if ( SUCCEEDED(SafeArrayGetElement(pArray, &cIndex, &theValue)) )
  6032. {
  6033. //Check if we want to use this value
  6034. BOOL fUseThisValue = FALSE;
  6035. if (fAllElements)
  6036. {
  6037. fUseThisValue = TRUE;
  6038. }
  6039. else
  6040. {
  6041. if (loop == myVirIndex)
  6042. fUseThisValue = TRUE;
  6043. }
  6044. if (fUseThisValue)
  6045. {
  6046. if (fIsBinaryOutput)
  6047. {
  6048. //Copy
  6049. T* pTemp = (T*)rgbValue;
  6050. pTemp[cCount++] = theValue;
  6051. //Increment counter of number of bytes copied
  6052. (*pcbValue) += wElemSize;
  6053. }
  6054. else
  6055. {
  6056. tempBuff[0] = 0;
  6057. if (wDSDT == WBEM_DSDT_BOOL_ARRAY)
  6058. {
  6059. sprintf (tempBuff, filter, (theValue ? "T" : "F"));
  6060. }
  6061. else
  6062. {
  6063. sprintf (tempBuff, filter, (T) theValue);
  6064. }
  6065. lstrcat( (char*)rgbValue, tempBuff);
  6066. //Increment counter of number of bytes copied
  6067. (*pcbValue) += lstrlen (tempBuff);
  6068. }
  6069. }
  6070. }
  6071. else
  6072. {
  6073. //error !!!
  6074. //Tidy Up
  6075. delete tempBuff;
  6076. SafeArrayUnlock(pArray);
  6077. return ISAM_ERROR;
  6078. }
  6079. }
  6080. else
  6081. {
  6082. //No we don't so quit
  6083. //Tidy Up
  6084. delete tempBuff;
  6085. SafeArrayUnlock(pArray);
  6086. return ISAM_TRUNCATION;
  6087. }
  6088. loop++;
  6089. }
  6090. //Tidy Up
  6091. delete tempBuff;
  6092. SafeArrayUnlock(pArray);
  6093. return NO_ISAM_ERR;
  6094. }
  6095. /**************************************************************************/
  6096. SWORD INTFUNC ISAMGetArrayStringInfo (VARIANT &vVariantVal, BSTR syntaxStr,
  6097. PTR rgbValue, SDWORD cbValueMax, SDWORD FAR* pcbValue, BOOL fIsBinaryOutput, long myVirIndex)
  6098. {
  6099. //Check if we want all elements of the array or just one element
  6100. BOOL fAllElements = TRUE;
  6101. if (myVirIndex != -1)
  6102. {
  6103. fAllElements = FALSE;
  6104. }
  6105. //Get the value
  6106. SAFEARRAY FAR* pArray = vVariantVal.parray;
  6107. SafeArrayLock(pArray);
  6108. //Find out the bounds of the array
  6109. //Get the upper and lower bounds
  6110. long lLowerBound;
  6111. SafeArrayGetLBound(pArray, 1, &lLowerBound);
  6112. long lUpperBound;
  6113. SafeArrayGetUBound(pArray, 1, &lUpperBound);
  6114. *pcbValue = 0;
  6115. //Initialize
  6116. long cCount = 0;
  6117. BSTR theValue;
  6118. ((char*)rgbValue)[0] = 0;
  6119. BOOL fOutOfBufferSpace = FALSE;
  6120. long loop = 0;
  6121. for (long cIndex = lLowerBound; (!fOutOfBufferSpace) && (cIndex <= lUpperBound); cIndex++)
  6122. {
  6123. //Check if we want to use this value
  6124. BOOL fUseThisValue = FALSE;
  6125. if (fAllElements)
  6126. {
  6127. fUseThisValue = TRUE;
  6128. }
  6129. else
  6130. {
  6131. if (loop == myVirIndex)
  6132. fUseThisValue = TRUE;
  6133. }
  6134. if (fUseThisValue)
  6135. {
  6136. if ( SUCCEEDED(SafeArrayGetElement(pArray, &cIndex, &theValue)) )
  6137. {
  6138. //Now we must add in string value in the format [string]
  6139. //However, if the string contains either [ or ] we must double
  6140. //this character in the string sequence
  6141. ULONG cLength = 0;
  6142. char* theValueStr = NULL;
  6143. if (theValue)
  6144. {
  6145. cLength = wcslen(theValue);
  6146. theValueStr = new char [cLength + 1];
  6147. theValueStr[0] = 0;
  6148. wcstombs(theValueStr, theValue, cLength);
  6149. theValueStr[cLength] = 0;
  6150. }
  6151. SWORD err = NO_ISAM_ERR;
  6152. if (!syntaxStr)
  6153. syntaxStr = L" ";
  6154. //Check if this is a string, timestamp, interval, time or date
  6155. BOOL foundMatch = FALSE;
  6156. // if ( (_wcsicmp(syntaxStr, WBEM_WSYNTAX_DATETIME) == 0) ||
  6157. // (_wcsicmp(syntaxStr, WBEM_WSYNTAX_INTERVAL) == 0))
  6158. if (_wcsicmp(syntaxStr, WBEM_WSYNTAX_DATETIME) == 0)
  6159. {
  6160. //A timestamp
  6161. DateTimeParser parser(theValue);
  6162. // if ( parser.IsValid() && parser.IsTimestamp() )
  6163. {
  6164. foundMatch = TRUE;
  6165. if (fIsBinaryOutput)
  6166. {
  6167. if (cbValueMax >= (SDWORD)((*pcbValue) + sizeof (TIMESTAMP_STRUCT)) )
  6168. {
  6169. TIMESTAMP_STRUCT FAR* pTimeStampStruct = (TIMESTAMP_STRUCT FAR*)((char*)rgbValue + (*pcbValue));
  6170. pTimeStampStruct->year = (SWORD)parser.GetYear();
  6171. pTimeStampStruct->month = (UWORD)parser.GetMonth();
  6172. pTimeStampStruct->day = (UWORD)parser.GetDay();
  6173. pTimeStampStruct->hour = (UWORD)parser.GetHour();
  6174. pTimeStampStruct->minute = (UWORD)parser.GetMin();
  6175. pTimeStampStruct->second = (UWORD)parser.GetSec();
  6176. pTimeStampStruct->fraction = 1000 * parser.GetMicroSec();
  6177. *pcbValue += sizeof (TIMESTAMP_STRUCT);
  6178. }
  6179. else
  6180. {
  6181. //not enough space
  6182. err = ISAM_TRUNCATION;
  6183. }
  6184. }
  6185. else
  6186. {
  6187. TIMESTAMP_STRUCT pTimeStampStruct;
  6188. pTimeStampStruct.year = (SWORD)parser.GetYear();
  6189. pTimeStampStruct.month = (UWORD)parser.GetMonth();
  6190. pTimeStampStruct.day = (UWORD)parser.GetDay();
  6191. pTimeStampStruct.hour = (UWORD)parser.GetHour();
  6192. pTimeStampStruct.minute = (UWORD)parser.GetMin();
  6193. pTimeStampStruct.second = (UWORD)parser.GetSec();
  6194. pTimeStampStruct.fraction = 1000 * parser.GetMicroSec();
  6195. if (fAllElements)
  6196. {
  6197. if (cbValueMax >= ( (*pcbValue) + 23+TIMESTAMP_SCALE) )
  6198. {
  6199. char szBuffer[20+TIMESTAMP_SCALE+1];
  6200. TimestampToChar(&pTimeStampStruct, (LPUSTR)szBuffer);
  6201. char* ptrToStr = ((char*)rgbValue + (*pcbValue));
  6202. sprintf (ptrToStr, "[%s]", szBuffer);
  6203. *pcbValue += (22+TIMESTAMP_SCALE); //ignore null
  6204. }
  6205. else
  6206. {
  6207. //not enough space
  6208. err = ISAM_TRUNCATION;
  6209. }
  6210. }
  6211. else
  6212. {
  6213. if (cbValueMax >= ( (*pcbValue) + 21+TIMESTAMP_SCALE) )
  6214. {
  6215. char szBuffer[20+TIMESTAMP_SCALE+1];
  6216. TimestampToChar(&pTimeStampStruct, (LPUSTR)szBuffer);
  6217. char* ptrToStr = ((char*)rgbValue + (*pcbValue));
  6218. sprintf (ptrToStr, "%s", szBuffer);
  6219. *pcbValue += (20+TIMESTAMP_SCALE); //ignore null
  6220. }
  6221. else
  6222. {
  6223. //not enough space
  6224. err = ISAM_TRUNCATION;
  6225. }
  6226. }
  6227. }
  6228. }
  6229. }
  6230. /*
  6231. else if (_wcsicmp(syntaxStr, WBEM_WSYNTAX_DATE) == 0)
  6232. {
  6233. //A date
  6234. DateTimeParser parser(theValue);
  6235. // if ( parser.IsValid() && parser.IsDate() )
  6236. {
  6237. foundMatch = TRUE;
  6238. if (fIsBinaryOutput)
  6239. {
  6240. if (cbValueMax >= (SDWORD)((*pcbValue) + sizeof (DATE_STRUCT)) )
  6241. {
  6242. DATE_STRUCT FAR* pDateStruct = (DATE_STRUCT FAR*)((char*)rgbValue + (*pcbValue));
  6243. pDateStruct->year = (SWORD)parser.GetYear();
  6244. pDateStruct->month = (UWORD)parser.GetMonth();
  6245. pDateStruct->day = (UWORD)parser.GetDay();
  6246. *pcbValue += sizeof (DATE_STRUCT);
  6247. }
  6248. else
  6249. {
  6250. //not enough space
  6251. err = ISAM_TRUNCATION;
  6252. }
  6253. }
  6254. else
  6255. {
  6256. DATE_STRUCT pDateStruct;
  6257. pDateStruct.year = (SWORD)parser.GetYear();
  6258. pDateStruct.month = (UWORD)parser.GetMonth();
  6259. pDateStruct.day = (UWORD)parser.GetDay();
  6260. if (cbValueMax >= ( (*pcbValue) + 3 + DATE_PRECISION) )
  6261. {
  6262. char szBuffer[DATE_PRECISION + 1];
  6263. DateToChar(&pDateStruct, szBuffer);
  6264. char* ptrToStr = ((char*)rgbValue + (*pcbValue));
  6265. sprintf (ptrToStr, "[%s]", szBuffer);
  6266. *pcbValue += (2 + DATE_PRECISION);// ignore null
  6267. }
  6268. else
  6269. {
  6270. //not enough space
  6271. err = ISAM_TRUNCATION;
  6272. }
  6273. }
  6274. }
  6275. }
  6276. else if (_wcsicmp(syntaxStr, WBEM_WSYNTAX_TIME) == 0)
  6277. {
  6278. //A time
  6279. DateTimeParser parser(theValue);
  6280. // if ( parser.IsValid() && parser.IsTime() )
  6281. {
  6282. foundMatch = TRUE;
  6283. if (fIsBinaryOutput)
  6284. {
  6285. if (cbValueMax >= (SDWORD)((*pcbValue) + sizeof (TIME_STRUCT)) )
  6286. {
  6287. TIME_STRUCT FAR* pTimeStruct = (TIME_STRUCT FAR*)((char*)rgbValue + (*pcbValue));
  6288. pTimeStruct->hour = (UWORD)parser.GetHour();
  6289. pTimeStruct->minute = (UWORD)parser.GetMin();
  6290. pTimeStruct->second = (UWORD)parser.GetSec();
  6291. *pcbValue += sizeof (TIME_STRUCT);
  6292. }
  6293. else
  6294. {
  6295. //not enough space
  6296. err = ISAM_TRUNCATION;
  6297. }
  6298. }
  6299. else
  6300. {
  6301. TIME_STRUCT pTimeStruct;
  6302. pTimeStruct.hour = (UWORD)parser.GetHour();
  6303. pTimeStruct.minute = (UWORD)parser.GetMin();
  6304. pTimeStruct.second = (UWORD)parser.GetSec();
  6305. if (cbValueMax >= ( (*pcbValue) + 3 + TIME_PRECISION) )
  6306. {
  6307. char szBuffer[TIME_PRECISION + 1];
  6308. TimeToChar(&pTimeStruct, szBuffer);
  6309. char* ptrToStr = ((char*)rgbValue + (*pcbValue));
  6310. sprintf (ptrToStr, "[%s]", szBuffer);
  6311. *pcbValue += (2 + TIME_PRECISION);//ignore null
  6312. }
  6313. else
  6314. {
  6315. //not enough space
  6316. err = ISAM_TRUNCATION;
  6317. }
  6318. }
  6319. }
  6320. }
  6321. */
  6322. if (!foundMatch)
  6323. {
  6324. //Check if string or 64bit integer
  6325. SDWORD fInt64Check = 0;
  6326. if ( (_wcsicmp(syntaxStr, WBEM_WSYNTAX_SINT64) == 0) )
  6327. fInt64Check = WBEM_DSDT_SINT64;
  6328. if ( (_wcsicmp(syntaxStr, WBEM_WSYNTAX_UINT64) == 0) )
  6329. fInt64Check = WBEM_DSDT_UINT64;
  6330. err = ISAMFormatCharParm (theValueStr, fOutOfBufferSpace,
  6331. (char*)rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, fInt64Check, fAllElements);
  6332. }
  6333. if (theValue)
  6334. delete theValueStr;
  6335. //SAI MOVED
  6336. SysFreeString(theValue);
  6337. if (err != NO_ISAM_ERR)
  6338. {
  6339. SafeArrayUnlock(pArray);
  6340. return err;
  6341. }
  6342. }
  6343. else
  6344. {
  6345. //error !!!
  6346. SafeArrayUnlock(pArray);
  6347. return ISAM_ERROR;
  6348. }
  6349. }
  6350. loop++;
  6351. }
  6352. //Tidy Up
  6353. // SysFreeString(theValue);
  6354. SafeArrayUnlock(pArray);
  6355. return NO_ISAM_ERR;
  6356. }
  6357. /*
  6358. SWORD ISAMGetPropertyArrayInfo(BSTR & arrayVal,
  6359. SWORD fCType,
  6360. PTR rgbValue,
  6361. SDWORD cbValueMax,
  6362. SDWORD FAR *pcbValue,
  6363. SWORD wbemVariantType,
  6364. BSTR syntaxStr,
  6365. BSTR maxStr)
  6366. {
  6367. SWORD err = NO_ISAM_ERR;
  6368. SWORD wDSDT = 0;
  6369. SWORD dummy1 = 0;
  6370. UDWORD cbPrecision = 0;
  6371. //Get the value
  6372. BSTR pString = arrayVal;
  6373. //If no WBEM variant type specified use default
  6374. if (!wbemVariantType)
  6375. wbemVariantType = WBEM_VARIANT_VT_ARRAY_BSTR;
  6376. //How do we want the value returned
  6377. switch (fCType)
  6378. {
  6379. case SQL_C_DOUBLE:
  6380. {
  6381. double dVal;
  6382. BOOL foundDecimalPoint;
  6383. BOOL isNull;
  6384. *pcbValue = sizeof(double);
  6385. if ((cbValueMax >= *pcbValue) &&
  6386. (DBASE_ERR_SUCCESS == ISAMGetDoubleFromString(pString, cbValueMax, dVal, isNull, foundDecimalPoint)) )
  6387. {
  6388. if (isNull)
  6389. {
  6390. *pcbValue = SQL_NULL_DATA;
  6391. }
  6392. else
  6393. {
  6394. *((double *)rgbValue) = dVal;
  6395. }
  6396. }
  6397. else
  6398. {
  6399. *pcbValue = 0;
  6400. return ERR_NOTCONVERTABLE;
  6401. }
  6402. }
  6403. break;
  6404. case SQL_C_CHAR:
  6405. {
  6406. char* pTemp = (char*) rgbValue;
  6407. pTemp[0] = 0;
  6408. *pcbValue = wcstombs( pTemp, pString, cbValueMax);
  6409. //Make an extra check here if you are requesting 64bit integers
  6410. ISAMGetDataSourceDependantTypeInfo
  6411. ((SWORD)wbemVariantType, syntaxStr, maxStr, wDSDT, dummy1, cbPrecision);
  6412. //Check for numeric string
  6413. if ( (wDSDT == WBEM_DSDT_SINT64_ARRAY) )
  6414. {
  6415. for (SDWORD ii = 0; ii < (*pcbValue); ii++)
  6416. {
  6417. switch (pTemp[ii])
  6418. {
  6419. case '0':
  6420. case '1':
  6421. case '2':
  6422. case '3':
  6423. case '4':
  6424. case '5':
  6425. case '6':
  6426. case '7':
  6427. case '8':
  6428. case '9':
  6429. case '+':
  6430. case '-':
  6431. //OK
  6432. break;
  6433. default:
  6434. return ERR_INVALID_INTEGER;
  6435. break;
  6436. }
  6437. }
  6438. }
  6439. if ( (wDSDT == WBEM_DSDT_UINT64_ARRAY) )
  6440. {
  6441. for (SDWORD ii = 0; ii < (*pcbValue); ii++)
  6442. {
  6443. switch (pTemp[ii])
  6444. {
  6445. case '0':
  6446. case '1':
  6447. case '2':
  6448. case '3':
  6449. case '4':
  6450. case '5':
  6451. case '6':
  6452. case '7':
  6453. case '8':
  6454. case '9':
  6455. //OK
  6456. break;
  6457. default:
  6458. return ERR_INVALID_INTEGER;
  6459. break;
  6460. }
  6461. }
  6462. }
  6463. }
  6464. break;
  6465. case SQL_C_TIMESTAMP:
  6466. {
  6467. //Check that you have enough buffer to store value
  6468. *pcbValue = sizeof (TIMESTAMP_STRUCT);
  6469. TIMESTAMP_STRUCT FAR* pTimeStampStruct = (TIMESTAMP_STRUCT FAR*)rgbValue;
  6470. if ( cbValueMax >= (*pcbValue) )
  6471. {
  6472. DateTimeParser parser(pString);
  6473. // if ( parser.IsValid() && parser.IsTimestamp() )
  6474. {
  6475. pTimeStampStruct->year = (SWORD)parser.GetYear();
  6476. pTimeStampStruct->month = (UWORD)parser.GetMonth();
  6477. pTimeStampStruct->day = (UWORD)parser.GetDay();
  6478. pTimeStampStruct->hour = (UWORD)parser.GetHour();
  6479. pTimeStampStruct->minute = (UWORD)parser.GetMin();
  6480. pTimeStampStruct->second = (UWORD)parser.GetSec();
  6481. pTimeStampStruct->fraction = 1000 * parser.GetMicroSec();
  6482. }
  6483. }
  6484. else
  6485. {
  6486. *pcbValue = 0;
  6487. return ERR_INSUFF_BUFFER;
  6488. }
  6489. }
  6490. break;
  6491. case SQL_C_BINARY:
  6492. default:
  6493. {
  6494. //No convertion available
  6495. return ERR_NOTCONVERTABLE;
  6496. }
  6497. break;
  6498. }
  6499. return err;
  6500. }
  6501. */
  6502. /***************************************************************************/
  6503. /* Retrieves the value from a variant */
  6504. SWORD ISAMGet_VT_I2(short iShortVal,
  6505. SWORD fCType,
  6506. PTR rgbValue,
  6507. SDWORD cbValueMax,
  6508. SDWORD FAR *pcbValue,
  6509. SWORD wbemVariantType,
  6510. BSTR syntaxStr,
  6511. SDWORD maxLenVal)
  6512. {
  6513. SWORD err = NO_ISAM_ERR;
  6514. SWORD wDSDT = 0;
  6515. SWORD dummy1 = 0;
  6516. UDWORD cbPrecision = 0;
  6517. //If no WBEM variant type specified use default
  6518. if (!wbemVariantType)
  6519. wbemVariantType = WBEM_VARIANT_VT_I2;
  6520. //How do we want the value returned
  6521. switch (fCType)
  6522. {
  6523. case SQL_C_DOUBLE:
  6524. {
  6525. //Check that you have enough buffer to store value
  6526. ISAMGetDataSourceDependantTypeInfo
  6527. ((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
  6528. if ( (wDSDT == WBEM_DSDT_SINT8) || (wDSDT == WBEM_DSDT_SINT8_ARRAY) )
  6529. {
  6530. //Signed 8 bit value
  6531. //Check that you have enough buffer to store value
  6532. *pcbValue = sizeof(signed char);
  6533. if (cbValueMax >= *pcbValue)
  6534. {
  6535. signed char iCharVal = (signed char) iShortVal;
  6536. *((double *)rgbValue) = (double)iCharVal;
  6537. }
  6538. else
  6539. {
  6540. *pcbValue = 0;
  6541. return ERR_INSUFF_BUFFER;
  6542. }
  6543. }
  6544. else
  6545. {
  6546. //Signed 16 bit value
  6547. //Check that you have enough buffer to store value
  6548. *pcbValue = sizeof(double);
  6549. if (cbValueMax >= *pcbValue)
  6550. {
  6551. *((double *)rgbValue) = (double)iShortVal;
  6552. }
  6553. else
  6554. {
  6555. *pcbValue = 0;
  6556. return ERR_INSUFF_BUFFER;
  6557. }
  6558. }
  6559. }
  6560. break;
  6561. case SQL_C_CHAR:
  6562. {
  6563. ISAMGetDataSourceDependantTypeInfo
  6564. ((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
  6565. if ( (wDSDT == WBEM_DSDT_SINT8) || (wDSDT == WBEM_DSDT_SINT8_ARRAY) )
  6566. {
  6567. //Signed 8 bit value
  6568. //Check that there is enough buffer space for largest value
  6569. if (cbValueMax >= STINYINT_PRECISION)
  6570. {
  6571. char ttt = (char) iShortVal;
  6572. char* pTemp = (char*)rgbValue;
  6573. pTemp[0] = 0;
  6574. sprintf ((char*)rgbValue, "%d", (short)ttt);
  6575. *pcbValue = lstrlen(pTemp);
  6576. }
  6577. else
  6578. {
  6579. *pcbValue = 0;
  6580. return ERR_INSUFF_BUFFER;
  6581. }
  6582. }
  6583. else
  6584. {
  6585. //Signed 16 bit value
  6586. //Check that there is enough buffer space for largest value
  6587. if (cbValueMax >= SSHORT_PRECISION)
  6588. {
  6589. char* pTemp = (char*)rgbValue;
  6590. pTemp[0] = 0;
  6591. sprintf ((char*)rgbValue, "%ld", iShortVal);
  6592. *pcbValue = lstrlen(pTemp);
  6593. }
  6594. else
  6595. {
  6596. *pcbValue = 0;
  6597. return ERR_INSUFF_BUFFER;
  6598. }
  6599. }
  6600. }
  6601. break;
  6602. case SQL_C_DATE:
  6603. case SQL_C_TIME:
  6604. case SQL_C_TIMESTAMP:
  6605. case SQL_C_BINARY:
  6606. default:
  6607. {
  6608. //No convertion available
  6609. return ISAM_ERROR;
  6610. }
  6611. break;
  6612. }
  6613. return err;
  6614. }
  6615. SWORD ISAMGet_VT_UI1(UCHAR iUcharVal,
  6616. SWORD fCType,
  6617. PTR rgbValue,
  6618. SDWORD cbValueMax,
  6619. SDWORD FAR *pcbValue,
  6620. SWORD wbemVariantType,
  6621. BSTR syntaxStr,
  6622. SDWORD maxLenVal)
  6623. {
  6624. SWORD err = NO_ISAM_ERR;
  6625. SWORD wDSDT = 0;
  6626. SWORD dummy1 = 0;
  6627. UDWORD cbPrecision = 0;
  6628. //If no WBEM variant type specified use default
  6629. if (!wbemVariantType)
  6630. wbemVariantType = WBEM_VARIANT_VT_UI1;
  6631. //How do we want the value returned
  6632. switch (fCType)
  6633. {
  6634. case SQL_C_DOUBLE:
  6635. {
  6636. *pcbValue = sizeof(double);
  6637. //Check that you have enough buffer to store value
  6638. if (cbValueMax >= *pcbValue)
  6639. {
  6640. ISAMGetDataSourceDependantTypeInfo
  6641. ((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
  6642. {
  6643. //Unsigned 8 bit value
  6644. *((double *)rgbValue) = (double)iUcharVal;
  6645. }
  6646. }
  6647. else
  6648. {
  6649. *pcbValue = 0;
  6650. return ERR_INSUFF_BUFFER;
  6651. }
  6652. }
  6653. break;
  6654. case SQL_C_CHAR:
  6655. {
  6656. ISAMGetDataSourceDependantTypeInfo
  6657. ((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
  6658. if (cbValueMax >= UTINYINT_PRECISION)
  6659. {
  6660. //Unsigned 8 bit value
  6661. //Check that there is enough buffer space for largest value
  6662. char* pTemp = (char*)rgbValue;
  6663. pTemp[0] = 0;
  6664. _itoa(iUcharVal, pTemp, 10);
  6665. *pcbValue = lstrlen(pTemp);
  6666. }
  6667. else
  6668. {
  6669. *pcbValue = 0;
  6670. return ERR_INSUFF_BUFFER;
  6671. }
  6672. }
  6673. break;
  6674. case SQL_C_DATE:
  6675. case SQL_C_TIME:
  6676. case SQL_C_TIMESTAMP:
  6677. case SQL_C_BINARY:
  6678. default:
  6679. {
  6680. //No convertion available
  6681. return ERR_NOTCONVERTABLE;
  6682. }
  6683. break;
  6684. }
  6685. return err;
  6686. }
  6687. SWORD ISAMGet_VT_I4(long iValue,
  6688. SWORD fCType,
  6689. PTR rgbValue,
  6690. SDWORD cbValueMax,
  6691. SDWORD FAR *pcbValue,
  6692. SWORD wbemVariantType,
  6693. BSTR syntaxStr,
  6694. SDWORD maxLenVal)
  6695. {
  6696. SWORD err = NO_ISAM_ERR;
  6697. SWORD wDSDT = 0;
  6698. SWORD dummy1 = 0;
  6699. UDWORD cbPrecision = 0;
  6700. //If no WBEM variant type specified use default
  6701. if (!wbemVariantType)
  6702. wbemVariantType = WBEM_VARIANT_VT_I4;
  6703. //How do we want the value returned
  6704. switch (fCType)
  6705. {
  6706. case SQL_C_DOUBLE:
  6707. {
  6708. ISAMGetDataSourceDependantTypeInfo
  6709. ((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
  6710. *pcbValue = sizeof (double);
  6711. if ( (wDSDT == WBEM_DSDT_UINT16) || (wDSDT == WBEM_DSDT_UINT16_ARRAY) )
  6712. {
  6713. //Unsigned 16 bit value
  6714. //Check that there is enough buffer space for largest value
  6715. if (cbValueMax >= *pcbValue)
  6716. {
  6717. double dd = (unsigned short) iValue;
  6718. *((double *)rgbValue) = dd;
  6719. }
  6720. else
  6721. {
  6722. *pcbValue = 0;
  6723. return ERR_INSUFF_BUFFER;
  6724. }
  6725. }
  6726. else if ( (wDSDT == WBEM_DSDT_UINT32) || (wDSDT == WBEM_DSDT_UINT32_ARRAY) )
  6727. {
  6728. //Unsigned 32 bit value
  6729. //Check that you have enough buffer to store value
  6730. *pcbValue = sizeof (double);
  6731. if (cbValueMax >= *pcbValue)
  6732. {
  6733. double dd = (unsigned long) iValue;
  6734. *((double *)rgbValue) = dd;
  6735. }
  6736. else
  6737. {
  6738. *pcbValue = 0;
  6739. return ERR_INSUFF_BUFFER;
  6740. }
  6741. }
  6742. else
  6743. {
  6744. //Signed 32 bit value
  6745. //Check that you have enough buffer to store value
  6746. if (cbValueMax >= *pcbValue)
  6747. {
  6748. *((double *)rgbValue) = (double)iValue;
  6749. }
  6750. else
  6751. {
  6752. *pcbValue = 0;
  6753. return ERR_INSUFF_BUFFER;
  6754. }
  6755. }
  6756. }
  6757. break;
  6758. case SQL_C_CHAR:
  6759. {
  6760. ISAMGetDataSourceDependantTypeInfo
  6761. ((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
  6762. if ( (wDSDT == WBEM_DSDT_UINT16) || (wDSDT == WBEM_DSDT_UINT16_ARRAY) )
  6763. {
  6764. //Unsigned 16 bit value
  6765. //Check that there is enough buffer space for largest value
  6766. if (cbValueMax >= USHORT_PRECISION)
  6767. {
  6768. unsigned short iushort = (unsigned short) iValue;
  6769. char* pTemp = (char*)rgbValue;
  6770. pTemp[0] = 0;
  6771. sprintf ((char*)rgbValue, "%lu", iushort);
  6772. *pcbValue = lstrlen(pTemp);
  6773. }
  6774. else
  6775. {
  6776. *pcbValue = 0;
  6777. return ERR_INSUFF_BUFFER;
  6778. }
  6779. }
  6780. else if ( (wDSDT == WBEM_DSDT_UINT32) || (wDSDT == WBEM_DSDT_UINT32_ARRAY) )
  6781. {
  6782. //Unsigned 32 bit value
  6783. //Check that there is enough buffer space for largest value
  6784. if (cbValueMax >= ULONG_PRECISION)
  6785. {
  6786. unsigned long iulong = (unsigned long) iValue;
  6787. char* pTemp = (char*)rgbValue;
  6788. pTemp[0] = 0;
  6789. sprintf ((char*)rgbValue, "%lu", iulong);
  6790. *pcbValue = lstrlen(pTemp);
  6791. }
  6792. else
  6793. {
  6794. *pcbValue = 0;
  6795. return ERR_INSUFF_BUFFER;
  6796. }
  6797. }
  6798. else
  6799. {
  6800. //Signed 32 bit value
  6801. //Check that there is enough buffer space for largest value
  6802. if (cbValueMax >= SLONG_PRECISION)
  6803. {
  6804. char* pTemp = (char*)rgbValue;
  6805. pTemp[0] = 0;
  6806. sprintf ((char*)rgbValue, "%ld", iValue);
  6807. *pcbValue = lstrlen(pTemp);
  6808. }
  6809. else
  6810. {
  6811. *pcbValue = 0;
  6812. return ERR_INSUFF_BUFFER;
  6813. }
  6814. }
  6815. }
  6816. break;
  6817. case SQL_C_DATE:
  6818. case SQL_C_TIME:
  6819. case SQL_C_TIMESTAMP:
  6820. case SQL_C_BINARY:
  6821. default:
  6822. {
  6823. //No convertion available
  6824. return ERR_NOTCONVERTABLE;
  6825. }
  6826. break;
  6827. }
  6828. return err;
  6829. }
  6830. SWORD ISAMGet_VT_BOOL(VARIANT_BOOL fBool,
  6831. SWORD fCType,
  6832. PTR rgbValue,
  6833. SDWORD cbValueMax,
  6834. SDWORD FAR *pcbValue,
  6835. SWORD wbemVariantType,
  6836. BSTR syntaxStr,
  6837. SDWORD maxLenVal)
  6838. {
  6839. SWORD err = NO_ISAM_ERR;
  6840. SWORD wDSDT = 0;
  6841. SWORD dummy1 = 0;
  6842. UDWORD cbPrecision = 0;
  6843. //How do we want the value returned
  6844. switch (fCType)
  6845. {
  6846. case SQL_C_DOUBLE:
  6847. {
  6848. *pcbValue = sizeof(double);
  6849. //Check that you have enough buffer to store value
  6850. if (cbValueMax >= *pcbValue)
  6851. {
  6852. if (fBool)
  6853. *((double *)rgbValue) = 1.0;
  6854. else
  6855. *((double *)rgbValue) = 0.0;
  6856. }
  6857. else
  6858. {
  6859. *pcbValue = 0;
  6860. return ERR_INSUFF_BUFFER;
  6861. }
  6862. }
  6863. break;
  6864. case SQL_C_CHAR:
  6865. {
  6866. if (cbValueMax)
  6867. {
  6868. char* pTemp = (char*)rgbValue;
  6869. pTemp[0] = 0;
  6870. if (fBool)
  6871. lstrcpy(pTemp, "T");
  6872. else
  6873. lstrcpy(pTemp, "F");
  6874. *pcbValue = 1;
  6875. }
  6876. }
  6877. break;
  6878. case SQL_C_DATE:
  6879. case SQL_C_TIME:
  6880. case SQL_C_TIMESTAMP:
  6881. case SQL_C_BINARY:
  6882. default:
  6883. {
  6884. //No convertion available
  6885. return ERR_NOTCONVERTABLE;
  6886. }
  6887. break;
  6888. }
  6889. return err;
  6890. }
  6891. SWORD ISAMGet_VT_R4(float fltVal,
  6892. SWORD fCType,
  6893. PTR rgbValue,
  6894. SDWORD cbValueMax,
  6895. SDWORD FAR *pcbValue,
  6896. SWORD wbemVariantType,
  6897. BSTR syntaxStr,
  6898. SDWORD maxLenVal)
  6899. {
  6900. SWORD err = NO_ISAM_ERR;
  6901. SWORD wDSDT = 0;
  6902. SWORD dummy1 = 0;
  6903. UDWORD cbPrecision = 0;
  6904. //How do we want the value returned
  6905. switch (fCType)
  6906. {
  6907. case SQL_C_DOUBLE:
  6908. {
  6909. *pcbValue = sizeof(double);
  6910. //Check that you have enough buffer to store value
  6911. if (cbValueMax >= *pcbValue)
  6912. {
  6913. *((double *)rgbValue) = (double)fltVal;
  6914. }
  6915. else
  6916. {
  6917. *pcbValue = 0;
  6918. return ERR_INSUFF_BUFFER;
  6919. }
  6920. }
  6921. break;
  6922. case SQL_C_CHAR:
  6923. {
  6924. int decimal, sign;
  6925. double dblVal = fltVal;
  6926. char* buffer = _ecvt(dblVal, cbValueMax - 2, &decimal, &sign);
  6927. char* pTemp = (char*) rgbValue;
  6928. pTemp[0] = 0;
  6929. //We need a buffer to store at least "-.3"
  6930. if (cbValueMax < 3)
  6931. {
  6932. *pcbValue = 0;
  6933. return ERR_INSUFF_BUFFER;
  6934. }
  6935. //Check if value is negative
  6936. if (sign)
  6937. {
  6938. strcpy(pTemp, "-");
  6939. }
  6940. //Now copy digits BEFORE the decimal point
  6941. if (cbValueMax && decimal)
  6942. {
  6943. strncat(pTemp, buffer, decimal);
  6944. }
  6945. char* pt = buffer + decimal;
  6946. if (cbValueMax && strlen (pt) )
  6947. {
  6948. //Add the decimal point
  6949. strcat (pTemp, ".");
  6950. //Copy digits AFTER decimal point
  6951. strcat(pTemp, pt);
  6952. }
  6953. *pcbValue = strlen (pTemp);
  6954. }
  6955. break;
  6956. case SQL_C_DATE:
  6957. case SQL_C_TIME:
  6958. case SQL_C_TIMESTAMP:
  6959. case SQL_C_BINARY:
  6960. default:
  6961. {
  6962. //No convertion available
  6963. return ERR_NOTCONVERTABLE;
  6964. }
  6965. break;
  6966. }
  6967. return err;
  6968. }
  6969. SWORD ISAMGet_VT_R8(double dblVal,
  6970. SWORD fCType,
  6971. PTR rgbValue,
  6972. SDWORD cbValueMax,
  6973. SDWORD FAR *pcbValue,
  6974. SWORD wbemVariantType,
  6975. BSTR syntaxStr,
  6976. SDWORD maxLenVal)
  6977. {
  6978. SWORD err = NO_ISAM_ERR;
  6979. SWORD wDSDT = 0;
  6980. SWORD dummy1 = 0;
  6981. UDWORD cbPrecision = 0;
  6982. //How do we want the value returned
  6983. switch (fCType)
  6984. {
  6985. case SQL_C_DOUBLE:
  6986. case SQL_C_DEFAULT:
  6987. {
  6988. *pcbValue = sizeof(double);
  6989. //Check that you have enough buffer to store value
  6990. if (cbValueMax >= *pcbValue)
  6991. {
  6992. *((double *)rgbValue) = (double)dblVal;
  6993. }
  6994. else
  6995. {
  6996. *pcbValue = 0;
  6997. return ERR_INSUFF_BUFFER;
  6998. }
  6999. }
  7000. break;
  7001. case SQL_C_CHAR:
  7002. {
  7003. int decimal, sign;
  7004. char* buffer = _ecvt(dblVal, cbValueMax - 2, &decimal, &sign);
  7005. char* pTemp = (char*) rgbValue;
  7006. pTemp[0] = 0;
  7007. //We need a buffer to store at least "-.3"
  7008. if (cbValueMax < 3)
  7009. {
  7010. *pcbValue = 0;
  7011. return ERR_INSUFF_BUFFER;
  7012. }
  7013. //Check if value is negative
  7014. if (sign)
  7015. {
  7016. strcpy(pTemp, "-");
  7017. }
  7018. //Now copy digits BEFORE the decimal point
  7019. if (cbValueMax && decimal)
  7020. {
  7021. strncat(pTemp, buffer, decimal);
  7022. }
  7023. char* pt = buffer + decimal;
  7024. if (cbValueMax && strlen (pt) )
  7025. {
  7026. //Add the decimal point
  7027. strcat (pTemp, ".");
  7028. //Copy digits AFTER decimal point
  7029. strcat(pTemp, pt);
  7030. }
  7031. *pcbValue = strlen (pTemp);
  7032. }
  7033. break;
  7034. case SQL_C_DATE:
  7035. case SQL_C_TIME:
  7036. case SQL_C_TIMESTAMP:
  7037. case SQL_C_BINARY:
  7038. default:
  7039. {
  7040. //No convertion available
  7041. return ERR_NOTCONVERTABLE;
  7042. }
  7043. break;
  7044. }
  7045. return err;
  7046. }
  7047. SWORD ISAMGet_VT_BSTR(BSTR pString,
  7048. SWORD fCType,
  7049. PTR rgbValue,
  7050. SDWORD cbValueMax,
  7051. SDWORD FAR *pcbValue,
  7052. SWORD wbemVariantType,
  7053. BSTR syntaxStr,
  7054. SDWORD maxLenVal)
  7055. {
  7056. SWORD err = NO_ISAM_ERR;
  7057. SWORD wDSDT = 0;
  7058. SWORD dummy1 = 0;
  7059. UDWORD cbPrecision = 0;
  7060. //If no WBEM variant type specified use default
  7061. if (!wbemVariantType)
  7062. wbemVariantType = WBEM_VARIANT_VT_BSTR;
  7063. //How do we want the value returned
  7064. switch (fCType)
  7065. {
  7066. case SQL_C_DOUBLE:
  7067. {
  7068. double dVal;
  7069. BOOL foundDecimalPoint;
  7070. BOOL isNull;
  7071. *pcbValue = sizeof(double);
  7072. if ((cbValueMax >= *pcbValue) &&
  7073. (DBASE_ERR_SUCCESS == ISAMGetDoubleFromString(pString, cbValueMax, dVal, isNull, foundDecimalPoint)) )
  7074. {
  7075. if (isNull)
  7076. {
  7077. *pcbValue = SQL_NULL_DATA;
  7078. }
  7079. else
  7080. {
  7081. *((double *)rgbValue) = dVal;
  7082. }
  7083. }
  7084. else
  7085. {
  7086. *pcbValue = 0;
  7087. return ERR_NOTCONVERTABLE;
  7088. }
  7089. }
  7090. break;
  7091. case SQL_C_CHAR:
  7092. {
  7093. char* pTemp = (char*) rgbValue;
  7094. _bstr_t myValue((BSTR)pString);
  7095. *pcbValue = Utility_WideCharToDBCS(myValue, &pTemp, cbValueMax);
  7096. //Make an extra check here if you are requesting 64bit integers
  7097. ISAMGetDataSourceDependantTypeInfo
  7098. ((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
  7099. //Check for numeric string
  7100. if ( (wDSDT == WBEM_DSDT_SINT64) )
  7101. {
  7102. for (SDWORD ii = 0; ii < (*pcbValue); ii++)
  7103. {
  7104. switch (pTemp[ii])
  7105. {
  7106. case '0':
  7107. case '1':
  7108. case '2':
  7109. case '3':
  7110. case '4':
  7111. case '5':
  7112. case '6':
  7113. case '7':
  7114. case '8':
  7115. case '9':
  7116. case '+':
  7117. case '-':
  7118. //OK
  7119. break;
  7120. default:
  7121. return ERR_INVALID_INTEGER;
  7122. break;
  7123. }
  7124. }
  7125. }
  7126. if ( (wDSDT == WBEM_DSDT_UINT64) )
  7127. {
  7128. for (SDWORD ii = 0; ii < (*pcbValue); ii++)
  7129. {
  7130. switch (pTemp[ii])
  7131. {
  7132. case '0':
  7133. case '1':
  7134. case '2':
  7135. case '3':
  7136. case '4':
  7137. case '5':
  7138. case '6':
  7139. case '7':
  7140. case '8':
  7141. case '9':
  7142. //OK
  7143. break;
  7144. default:
  7145. return ERR_INVALID_INTEGER;
  7146. break;
  7147. }
  7148. }
  7149. }
  7150. }
  7151. break;
  7152. /*
  7153. case SQL_C_DATE:
  7154. {
  7155. //Check that you have enough buffer to store value
  7156. *pcbValue = sizeof (DATE_STRUCT);
  7157. DATE_STRUCT FAR* pDateStruct = (DATE_STRUCT FAR*)rgbValue;
  7158. if ( cbValueMax >= (*pcbValue) )
  7159. {
  7160. DateTimeParser parser(pString);
  7161. // if ( parser.IsValid() && parser.IsDate() )
  7162. {
  7163. pDateStruct->year = (SWORD)parser.GetYear();
  7164. pDateStruct->month = (UWORD)parser.GetMonth();
  7165. pDateStruct->day = (UWORD)parser.GetDay();
  7166. }
  7167. // else
  7168. // {
  7169. // *pcbValue = 0;
  7170. // return ERR_INVALID_DATE;
  7171. // }
  7172. }
  7173. else
  7174. {
  7175. *pcbValue = 0;
  7176. return ERR_INSUFF_BUFFER;
  7177. }
  7178. }
  7179. break;
  7180. case SQL_C_TIME:
  7181. {
  7182. //Check that you have enough buffer to store value
  7183. *pcbValue = sizeof (TIME_STRUCT);
  7184. TIME_STRUCT FAR* pTimeStruct = (TIME_STRUCT FAR*)rgbValue;
  7185. if ( cbValueMax >= (*pcbValue) )
  7186. {
  7187. DateTimeParser parser(pString);
  7188. // if ( parser.IsValid() && parser.IsTime() )
  7189. {
  7190. pTimeStruct->hour = (UWORD)parser.GetHour();
  7191. pTimeStruct->minute = (UWORD)parser.GetMin();
  7192. pTimeStruct->second = (UWORD)parser.GetSec();
  7193. }
  7194. // else
  7195. // {
  7196. // *pcbValue = 0;
  7197. // return ERR_INVALID_TIME;
  7198. // }
  7199. }
  7200. else
  7201. {
  7202. *pcbValue = 0;
  7203. return ERR_INSUFF_BUFFER;
  7204. }
  7205. }
  7206. break;
  7207. */
  7208. case SQL_C_TIMESTAMP:
  7209. {
  7210. //Check that you have enough buffer to store value
  7211. *pcbValue = sizeof (TIMESTAMP_STRUCT);
  7212. TIMESTAMP_STRUCT FAR* pTimeStampStruct = (TIMESTAMP_STRUCT FAR*)rgbValue;
  7213. if ( cbValueMax >= (*pcbValue) )
  7214. {
  7215. DateTimeParser parser(pString);
  7216. // if ( parser.IsValid() && parser.IsTimestamp() )
  7217. {
  7218. pTimeStampStruct->year = (SWORD)parser.GetYear();
  7219. pTimeStampStruct->month = (UWORD)parser.GetMonth();
  7220. pTimeStampStruct->day = (UWORD)parser.GetDay();
  7221. pTimeStampStruct->hour = (UWORD)parser.GetHour();
  7222. pTimeStampStruct->minute = (UWORD)parser.GetMin();
  7223. pTimeStampStruct->second = (UWORD)parser.GetSec();
  7224. pTimeStampStruct->fraction = 1000 * parser.GetMicroSec();
  7225. }
  7226. // else
  7227. // {
  7228. // *pcbValue = 0;
  7229. // return ERR_INVALID_TIMESTAMP;
  7230. // }
  7231. }
  7232. else
  7233. {
  7234. *pcbValue = 0;
  7235. return ERR_INSUFF_BUFFER;
  7236. }
  7237. }
  7238. break;
  7239. case SQL_C_BINARY:
  7240. default:
  7241. {
  7242. //No convertion available
  7243. return ERR_NOTCONVERTABLE;
  7244. }
  7245. break;
  7246. }
  7247. return err;
  7248. }
  7249. SWORD ISAMGetValueFromVariant(VARIANT &vVariantVal,
  7250. SWORD fCType,
  7251. PTR rgbValue,
  7252. SDWORD cbValueMax,
  7253. SDWORD FAR *pcbValue,
  7254. SWORD wbemVariantType,
  7255. BSTR syntaxStr,
  7256. SDWORD maxLenVal,
  7257. long myVirIndex)
  7258. {
  7259. SWORD err = NO_ISAM_ERR;
  7260. SWORD wDSDT = 0;
  7261. SWORD dummy1 = 0;
  7262. UDWORD cbPrecision = 0;
  7263. VARTYPE varType1 = V_VT(&vVariantVal);
  7264. switch( varType1 )
  7265. {
  7266. case VT_NULL:
  7267. {
  7268. *pcbValue = SQL_NULL_DATA;
  7269. }
  7270. break;
  7271. case VT_I2:
  7272. {
  7273. //Get the value
  7274. short iShortVal = vVariantVal.iVal;
  7275. err = ISAMGet_VT_I2(iShortVal,
  7276. fCType,
  7277. rgbValue,
  7278. cbValueMax,
  7279. pcbValue,
  7280. wbemVariantType,
  7281. syntaxStr,
  7282. maxLenVal
  7283. );
  7284. }
  7285. break;
  7286. case VT_I4:
  7287. {
  7288. //Get the value
  7289. long iValue = vVariantVal.lVal;
  7290. err = ISAMGet_VT_I4(iValue,
  7291. fCType,
  7292. rgbValue,
  7293. cbValueMax,
  7294. pcbValue,
  7295. wbemVariantType,
  7296. syntaxStr,
  7297. maxLenVal
  7298. );
  7299. }
  7300. break;
  7301. case VT_UI1:
  7302. {
  7303. //Get the value
  7304. UCHAR iUcharVal = vVariantVal.bVal;
  7305. err = ISAMGet_VT_UI1(iUcharVal,
  7306. fCType,
  7307. rgbValue,
  7308. cbValueMax,
  7309. pcbValue,
  7310. wbemVariantType,
  7311. syntaxStr,
  7312. maxLenVal
  7313. );
  7314. }
  7315. break;
  7316. case VT_BSTR:
  7317. {
  7318. //Get the value
  7319. BSTR pString = vVariantVal.bstrVal;
  7320. err = ISAMGet_VT_BSTR(pString,
  7321. fCType,
  7322. rgbValue,
  7323. cbValueMax,
  7324. pcbValue,
  7325. wbemVariantType,
  7326. syntaxStr,
  7327. maxLenVal
  7328. );
  7329. //Null terminate this string
  7330. if (cbValueMax > *pcbValue)
  7331. {
  7332. ((char*)rgbValue)[*pcbValue] = '\0';
  7333. // ODBCTRACE (_T("Null terminating this string"));
  7334. }
  7335. else
  7336. {
  7337. // ODBCTRACE (_T("Not Null terminating this string"));
  7338. }
  7339. }
  7340. break;
  7341. case VT_R8:
  7342. {
  7343. //Get the value
  7344. double dblVal = vVariantVal.dblVal;
  7345. err = ISAMGet_VT_R8(dblVal,
  7346. fCType,
  7347. rgbValue,
  7348. cbValueMax,
  7349. pcbValue,
  7350. wbemVariantType,
  7351. syntaxStr,
  7352. maxLenVal
  7353. );
  7354. }
  7355. break;
  7356. case VT_R4:
  7357. {
  7358. //Get the value
  7359. float fltVal = vVariantVal.fltVal;
  7360. err = ISAMGet_VT_R4(fltVal,
  7361. fCType,
  7362. rgbValue,
  7363. cbValueMax,
  7364. pcbValue,
  7365. wbemVariantType,
  7366. syntaxStr,
  7367. maxLenVal
  7368. );
  7369. }
  7370. break;
  7371. case VT_BOOL:
  7372. {
  7373. //Get the value
  7374. VARIANT_BOOL fBool = vVariantVal.boolVal;
  7375. err = ISAMGet_VT_BOOL(fBool,
  7376. fCType,
  7377. rgbValue,
  7378. cbValueMax,
  7379. pcbValue,
  7380. wbemVariantType,
  7381. syntaxStr,
  7382. maxLenVal
  7383. );
  7384. }
  7385. break;
  7386. default:
  7387. {
  7388. //Before we quit, check whether it is a VT_ARRAY
  7389. BOOL fIsVT_ARRAY = FALSE;
  7390. SWORD wStatus = ISAM_ERROR;
  7391. BOOL fIsBinaryOutput = (fCType == SQL_C_BINARY);
  7392. if ( varType1 == (VT_ARRAY|VT_UI1 ))
  7393. {
  7394. //If no WBEM variant type specified use default
  7395. if (!wbemVariantType)
  7396. wbemVariantType = WBEM_VARIANT_VT_ARRAY_UI1;
  7397. ISAMGetDataSourceDependantTypeInfo
  7398. ((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
  7399. //Get the precision for a single item in array
  7400. {
  7401. UCHAR ubVal = 0;
  7402. cbPrecision = UTINYINT_PRECISION;
  7403. if (myVirIndex == -1)
  7404. {
  7405. //String display for all elements
  7406. wStatus = ISAMGetArrayInfo (vVariantVal, ubVal,
  7407. rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
  7408. }
  7409. else
  7410. {
  7411. //others
  7412. SAFEARRAY FAR* pArray = vVariantVal.parray;
  7413. if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &ubVal)) )
  7414. {
  7415. err = ISAMGet_VT_UI1(ubVal,
  7416. fCType,
  7417. rgbValue,
  7418. cbValueMax,
  7419. pcbValue,
  7420. wbemVariantType,
  7421. syntaxStr,
  7422. maxLenVal
  7423. );
  7424. wStatus = NO_ISAM_ERR;
  7425. if (err == ERR_INSUFF_BUFFER)
  7426. wStatus = ISAM_TRUNCATION;
  7427. if (err == ISAM_ERROR)
  7428. wStatus = ISAM_ERROR;
  7429. }
  7430. }
  7431. }
  7432. }
  7433. else if (( varType1 == (VT_ARRAY|VT_I4)))
  7434. {
  7435. //If no WBEM variant type specified use default
  7436. if (!wbemVariantType)
  7437. wbemVariantType = WBEM_VARIANT_VT_ARRAY_I4;
  7438. ISAMGetDataSourceDependantTypeInfo
  7439. ((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
  7440. //Get the precision for a single item in array
  7441. if (wDSDT == WBEM_DSDT_UINT16_ARRAY)
  7442. {
  7443. USHORT wVal = 0;
  7444. cbPrecision = SMALLINT_PRECISION;
  7445. if (myVirIndex == -1)
  7446. {
  7447. //String display for all elements
  7448. wStatus = ISAMGetArrayInfo (vVariantVal, wVal,
  7449. rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
  7450. }
  7451. else
  7452. {
  7453. //others
  7454. SAFEARRAY FAR* pArray = vVariantVal.parray;
  7455. if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &wVal)) )
  7456. {
  7457. err = ISAMGet_VT_I4(wVal,
  7458. fCType,
  7459. rgbValue,
  7460. cbValueMax,
  7461. pcbValue,
  7462. wbemVariantType,
  7463. syntaxStr,
  7464. maxLenVal
  7465. );
  7466. wStatus = NO_ISAM_ERR;
  7467. if (err == ERR_INSUFF_BUFFER)
  7468. wStatus = ISAM_TRUNCATION;
  7469. if (err == ISAM_ERROR)
  7470. wStatus = ISAM_ERROR;
  7471. }
  7472. }
  7473. }
  7474. else if (wDSDT == WBEM_DSDT_UINT32_ARRAY)
  7475. {
  7476. ULONG lValue = 0;
  7477. cbPrecision = ULONG_PRECISION;
  7478. if (myVirIndex == -1)
  7479. {
  7480. //String display for all elements
  7481. wStatus = ISAMGetArrayInfo (vVariantVal, lValue,
  7482. rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
  7483. }
  7484. else
  7485. {
  7486. //others
  7487. SAFEARRAY FAR* pArray = vVariantVal.parray;
  7488. if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &lValue)) )
  7489. {
  7490. err = ISAMGet_VT_I4(lValue,
  7491. fCType,
  7492. rgbValue,
  7493. cbValueMax,
  7494. pcbValue,
  7495. wbemVariantType,
  7496. syntaxStr,
  7497. maxLenVal
  7498. );
  7499. wStatus = NO_ISAM_ERR;
  7500. if (err == ERR_INSUFF_BUFFER)
  7501. wStatus = ISAM_TRUNCATION;
  7502. if (err == ISAM_ERROR)
  7503. wStatus = ISAM_ERROR;
  7504. }
  7505. }
  7506. }
  7507. else
  7508. {
  7509. //SINT32
  7510. long lValue = 0;
  7511. cbPrecision = ULONG_PRECISION + 1;
  7512. if (myVirIndex == -1)
  7513. {
  7514. //String display for all elements
  7515. wStatus = ISAMGetArrayInfo (vVariantVal, lValue,
  7516. rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
  7517. }
  7518. else
  7519. {
  7520. //others
  7521. SAFEARRAY FAR* pArray = vVariantVal.parray;
  7522. if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &lValue)) )
  7523. {
  7524. err = ISAMGet_VT_I4(lValue,
  7525. fCType,
  7526. rgbValue,
  7527. cbValueMax,
  7528. pcbValue,
  7529. wbemVariantType,
  7530. syntaxStr,
  7531. maxLenVal
  7532. );
  7533. wStatus = NO_ISAM_ERR;
  7534. if (err == ERR_INSUFF_BUFFER)
  7535. wStatus = ISAM_TRUNCATION;
  7536. if (err == ISAM_ERROR)
  7537. wStatus = ISAM_ERROR;
  7538. }
  7539. }
  7540. }
  7541. }
  7542. else if ((varType1 == (VT_ARRAY|VT_BOOL)))
  7543. {
  7544. BOOL fBoolVal = TRUE;
  7545. wDSDT = WBEM_DSDT_BOOL_ARRAY;
  7546. cbPrecision = 1;
  7547. if (myVirIndex == -1)
  7548. {
  7549. //String display for all elements
  7550. wStatus = ISAMGetArrayInfo (vVariantVal, fBoolVal,
  7551. rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
  7552. }
  7553. else
  7554. {
  7555. //others
  7556. SAFEARRAY FAR* pArray = vVariantVal.parray;
  7557. if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &fBoolVal)) )
  7558. {
  7559. err = ISAMGet_VT_BOOL((VARIANT_BOOL) fBoolVal,
  7560. fCType,
  7561. rgbValue,
  7562. cbValueMax,
  7563. pcbValue,
  7564. wbemVariantType,
  7565. syntaxStr,
  7566. maxLenVal
  7567. );
  7568. wStatus = NO_ISAM_ERR;
  7569. if (err == ERR_INSUFF_BUFFER)
  7570. wStatus = ISAM_TRUNCATION;
  7571. if (err == ISAM_ERROR)
  7572. wStatus = ISAM_ERROR;
  7573. }
  7574. }
  7575. }
  7576. else if ((varType1 == (VT_ARRAY|VT_I2)))
  7577. {
  7578. short wVal = 0;
  7579. //If no WBEM variant type specified use default
  7580. if (!wbemVariantType)
  7581. wbemVariantType = WBEM_VARIANT_VT_ARRAY_I2;
  7582. ISAMGetDataSourceDependantTypeInfo
  7583. ((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
  7584. //Get the precision for a single item in array
  7585. if (wDSDT == WBEM_DSDT_SINT8_ARRAY)
  7586. {
  7587. //char bVal = 0;
  7588. short bVal = 0;
  7589. cbPrecision = UTINYINT_PRECISION + 1;
  7590. if (myVirIndex == -1)
  7591. {
  7592. //String display for all elements
  7593. wStatus = ISAMGetArrayInfo (vVariantVal, bVal,
  7594. rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
  7595. }
  7596. else
  7597. {
  7598. //others
  7599. SAFEARRAY FAR* pArray = vVariantVal.parray;
  7600. if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &bVal)) )
  7601. {
  7602. err = ISAMGet_VT_I2(bVal,
  7603. fCType,
  7604. rgbValue,
  7605. cbValueMax,
  7606. pcbValue,
  7607. wbemVariantType,
  7608. syntaxStr,
  7609. maxLenVal
  7610. );
  7611. wStatus = NO_ISAM_ERR;
  7612. if (err == ERR_INSUFF_BUFFER)
  7613. wStatus = ISAM_TRUNCATION;
  7614. if (err == ISAM_ERROR)
  7615. wStatus = ISAM_ERROR;
  7616. }
  7617. }
  7618. }
  7619. else if (wDSDT == WBEM_DSDT_SINT16_ARRAY)
  7620. {
  7621. short wVal = 0;
  7622. cbPrecision = SMALLINT_PRECISION + 1;
  7623. if (myVirIndex == -1)
  7624. {
  7625. //String display for all elements
  7626. wStatus = ISAMGetArrayInfo (vVariantVal, wVal,
  7627. rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
  7628. }
  7629. else
  7630. {
  7631. //others
  7632. SAFEARRAY FAR* pArray = vVariantVal.parray;
  7633. if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &wVal)) )
  7634. {
  7635. err = ISAMGet_VT_I2(wVal,
  7636. fCType,
  7637. rgbValue,
  7638. cbValueMax,
  7639. pcbValue,
  7640. wbemVariantType,
  7641. syntaxStr,
  7642. maxLenVal
  7643. );
  7644. wStatus = NO_ISAM_ERR;
  7645. if (err == ERR_INSUFF_BUFFER)
  7646. wStatus = ISAM_TRUNCATION;
  7647. if (err == ISAM_ERROR)
  7648. wStatus = ISAM_ERROR;
  7649. }
  7650. }
  7651. }
  7652. }
  7653. else if ((varType1 == (VT_ARRAY|VT_R4)))
  7654. {
  7655. float fltVal = (float)0.0;
  7656. //If no WBEM variant type specified use default
  7657. if (!wbemVariantType)
  7658. wbemVariantType = WBEM_VARIANT_VT_ARRAY_R4;
  7659. ISAMGetDataSourceDependantTypeInfo
  7660. ((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
  7661. if (myVirIndex == -1)
  7662. {
  7663. //String display for all elements
  7664. wStatus = ISAMGetArrayInfo (vVariantVal, fltVal,
  7665. rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
  7666. }
  7667. else
  7668. {
  7669. //others
  7670. SAFEARRAY FAR* pArray = vVariantVal.parray;
  7671. if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &fltVal)) )
  7672. {
  7673. err = ISAMGet_VT_R4(fltVal,
  7674. fCType,
  7675. rgbValue,
  7676. cbValueMax,
  7677. pcbValue,
  7678. wbemVariantType,
  7679. syntaxStr,
  7680. maxLenVal
  7681. );
  7682. wStatus = NO_ISAM_ERR;
  7683. if (err == ERR_INSUFF_BUFFER)
  7684. wStatus = ISAM_TRUNCATION;
  7685. if (err == ISAM_ERROR)
  7686. wStatus = ISAM_ERROR;
  7687. }
  7688. }
  7689. }
  7690. else if ((varType1 == (VT_ARRAY|VT_R8)))
  7691. {
  7692. double dblVal = 0;
  7693. //If no WBEM variant type specified use default
  7694. if (!wbemVariantType)
  7695. wbemVariantType = WBEM_VARIANT_VT_ARRAY_R8;
  7696. ISAMGetDataSourceDependantTypeInfo
  7697. ((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
  7698. if (myVirIndex == -1)
  7699. {
  7700. //String display for all elements
  7701. wStatus = ISAMGetArrayInfo (vVariantVal, dblVal,
  7702. rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
  7703. }
  7704. else
  7705. {
  7706. //others
  7707. SAFEARRAY FAR* pArray = vVariantVal.parray;
  7708. if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &dblVal)) )
  7709. {
  7710. err = ISAMGet_VT_R8(dblVal,
  7711. fCType,
  7712. rgbValue,
  7713. cbValueMax,
  7714. pcbValue,
  7715. wbemVariantType,
  7716. syntaxStr,
  7717. maxLenVal
  7718. );
  7719. wStatus = NO_ISAM_ERR;
  7720. if (err == ERR_INSUFF_BUFFER)
  7721. wStatus = ISAM_TRUNCATION;
  7722. if (err == ISAM_ERROR)
  7723. wStatus = ISAM_ERROR;
  7724. }
  7725. }
  7726. }
  7727. else if ((varType1 == (VT_ARRAY|VT_BSTR)))
  7728. {
  7729. if (myVirIndex == -1)
  7730. {
  7731. //String display for all elements
  7732. wStatus = ISAMGetArrayStringInfo (vVariantVal, syntaxStr,
  7733. rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, myVirIndex);
  7734. }
  7735. else
  7736. {
  7737. //others
  7738. BSTR pString = NULL;
  7739. SAFEARRAY FAR* pArray = vVariantVal.parray;
  7740. if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &pString)) )
  7741. {
  7742. err = ISAMGet_VT_BSTR(pString,
  7743. fCType,
  7744. rgbValue,
  7745. cbValueMax,
  7746. pcbValue,
  7747. wbemVariantType,
  7748. syntaxStr,
  7749. maxLenVal
  7750. );
  7751. wStatus = NO_ISAM_ERR;
  7752. if (err == ERR_INSUFF_BUFFER)
  7753. wStatus = ISAM_TRUNCATION;
  7754. if (err == ISAM_ERROR)
  7755. wStatus = ISAM_ERROR;
  7756. //SAI ADDED
  7757. SysFreeString(pString);
  7758. }
  7759. }
  7760. if (wStatus == NO_ISAM_ERR)
  7761. {
  7762. //Null terminate this string
  7763. if (cbValueMax > *pcbValue)
  7764. {
  7765. ((char*)rgbValue)[*pcbValue] = '\0';
  7766. // ODBCTRACE (_T("Null terminating this string"));
  7767. }
  7768. else
  7769. {
  7770. // ODBCTRACE (_T("Not Null terminating this string"));
  7771. }
  7772. }
  7773. }
  7774. if (wStatus == ISAM_TRUNCATION)
  7775. {
  7776. //Truncated data
  7777. return ISAM_TRUNCATION;
  7778. }
  7779. else if (wStatus != NO_ISAM_ERR)
  7780. {
  7781. //No convertion available
  7782. return wStatus;
  7783. }
  7784. }
  7785. break;
  7786. }
  7787. return err;
  7788. }
  7789. /***************************************************************************/
  7790. // Checked for SetInterfaceSecurityEx on IWbemServices and IEnumWbemClassObject
  7791. IMPLEMENT_SERIAL (CNamespace, CObject, 1)
  7792. SWORD INTFUNC ISAMGetNestedNamespaces (char *parentName, char *namespaceName,
  7793. IWbemServices *pGatewayIn,
  7794. DWORD dwAuthLevelIn, DWORD dwImpLevelIn,
  7795. char *servername,
  7796. // WBEM_LOGIN_AUTHENTICATION loginMethod,
  7797. char *username, char *password, BOOL fIntpretEmptPwdAsBlank,
  7798. char* locale, char* authority,
  7799. CMapStringToOb* map, BOOL bDeep)
  7800. {
  7801. // Always want to return absolute names here
  7802. char *absName = NULL;
  7803. IWbemServicesPtr pGateway;
  7804. DWORD dwAuthLevel = 0;
  7805. DWORD dwImpLevel = 0;
  7806. COAUTHIDENTITY* pAuthIdent = NULL;
  7807. if (NULL == pGatewayIn)
  7808. {
  7809. pGateway = NULL;
  7810. ISAMGetGatewayServer (pGateway,
  7811. (LPUSTR)servername,
  7812. // loginMethod,
  7813. (LPUSTR)namespaceName, (LPUSTR)username, (LPUSTR)password, (LPUSTR)locale, (LPUSTR)authority,
  7814. dwAuthLevel, dwImpLevel, fIntpretEmptPwdAsBlank , &pAuthIdent);
  7815. if (pGateway == NULL)
  7816. return ISAM_ERROR;
  7817. // the passed in name is absolute
  7818. absName = new char [strlen (namespaceName) +1];
  7819. absName[0] = 0;
  7820. strcpy (absName, namespaceName);
  7821. map->SetAt (absName, new CNamespace (absName)); // add self
  7822. }
  7823. else
  7824. {
  7825. pGateway = pGatewayIn;
  7826. pGateway->AddRef ();
  7827. dwAuthLevel = dwAuthLevelIn;
  7828. dwImpLevel = dwImpLevelIn;
  7829. // the passed in name is relative - so build absolute - and add to map
  7830. absName = new char [strlen (parentName) + strlen(namespaceName) + 2
  7831. + 1 /* for separator */];
  7832. absName[0] = 0;
  7833. strcpy (absName, parentName);
  7834. strcat (absName, "\\"); // add separator
  7835. strcat (absName, namespaceName);
  7836. map->SetAt (absName, new CNamespace (absName));
  7837. }
  7838. if (!bDeep)
  7839. {
  7840. delete absName;
  7841. return NO_ISAM_ERR;
  7842. }
  7843. //cloaking
  7844. BOOL fIsLocalConnection = IsLocalServer(servername);
  7845. if ( fIsLocalConnection && IsW2KOrMore() )
  7846. {
  7847. WbemSetDynamicCloaking(pGateway, dwAuthLevel, dwImpLevel);
  7848. }
  7849. //Enumerate children and recurse
  7850. IEnumWbemClassObject* pNamespaceEnum = NULL;
  7851. BSTR nspaceBSTR = SysAllocString(WBEMDR32_L_NAMESPACE);
  7852. IWbemContext* pContext = ISAMCreateLocaleIDContextObject(locale);
  7853. if ( FAILED(pGateway->CreateInstanceEnum(nspaceBSTR, 0, pContext, &pNamespaceEnum)) )
  7854. {
  7855. delete absName;
  7856. SysFreeString(nspaceBSTR);
  7857. if (pContext)
  7858. pContext->Release();
  7859. //Should be not also Release pGateway ?
  7860. return NO_ISAM_ERR;
  7861. }
  7862. else
  7863. {
  7864. ISAMSetCloaking2(pNamespaceEnum,
  7865. fIsLocalConnection,
  7866. IsW2KOrMore(),
  7867. dwAuthLevel,
  7868. dwImpLevel,
  7869. pAuthIdent);
  7870. /*
  7871. if ( fIsLocalConnection && IsW2KOrMore() )
  7872. {
  7873. WbemSetDynamicCloaking(pNamespaceEnum, dwAuthLevel, dwImpLevel);
  7874. }
  7875. else
  7876. {
  7877. //Set Dcom blanket
  7878. SetInterfaceSecurityEx(pNamespaceEnum, pAuthIdent, gpPrincipal, dwAuthLevel, dwImpLevel);
  7879. }
  7880. */
  7881. SysFreeString(nspaceBSTR);
  7882. if (pContext)
  7883. pContext->Release();
  7884. if (!pNamespaceEnum)
  7885. {
  7886. delete absName;
  7887. return NO_ISAM_ERR;
  7888. }
  7889. ULONG uRet = 0;
  7890. IWbemClassObject* pNewInst = NULL;
  7891. pNamespaceEnum->Reset();
  7892. while ( S_OK == pNamespaceEnum->Next(-1, 1, &pNewInst, &uRet) )
  7893. {
  7894. VARIANTARG var;
  7895. //SAI ADDED no need to init VariantInit (&var);
  7896. BSTR nameBSTR = SysAllocString(WBEMDR32_L_NAME);
  7897. pNewInst->Get(nameBSTR, 0, &var, NULL, NULL);
  7898. SysFreeString(nameBSTR);
  7899. IWbemServicesPtr pNewGateway = NULL;
  7900. COAUTHIDENTITY* pNewAuthIdent = NULL;
  7901. //Get user and password fields
  7902. #ifdef USING_ABSPATH
  7903. char testBuff [MAX_QUALIFIER_NAME_LENGTH + 1];
  7904. testBuff[0] = 0;
  7905. wcstombs(testBuff, var.bstrVal, MAX_QUALIFIER_NAME_LENGTH);
  7906. testBuff[MAX_QUALIFIER_NAME_LENGTH] = 0;
  7907. char* cTemp2 = new char [strlen (absName) + strlen(testBuff) + 2];
  7908. cTemp2[0] = 0;
  7909. lstrcpy(cTemp2,absName);
  7910. lstrcat(cTemp2, "\\");
  7911. lstrcat(cTemp2,testBuff);
  7912. ISAMGetGatewayServer (pNewGateway, servername,
  7913. // loginMethod,
  7914. cTemp2, username, password, locale, authority, &pNewAuthIdent);
  7915. delete cTemp2;
  7916. if (pNewGateway)
  7917. #else
  7918. BSTR myRelativeNamespace = var.bstrVal;
  7919. CBString cbNS (myRelativeNamespace, FALSE);
  7920. IWbemContext* mycontext = ISAMCreateLocaleIDContextObject(locale);
  7921. if ( SUCCEEDED(pGateway->OpenNamespace(cbNS.GetString(), 0, mycontext, &pNewGateway, NULL)) )
  7922. #endif
  7923. {
  7924. BOOL fIsLocalConnection = IsLocalServer(servername);
  7925. ISAMSetCloaking2(pNewGateway,
  7926. fIsLocalConnection,
  7927. IsW2KOrMore(),
  7928. dwAuthLevel,
  7929. dwImpLevel,
  7930. pNewAuthIdent);
  7931. /*
  7932. if ( fIsLocalConnection && IsW2KOrMore() )
  7933. {
  7934. WbemSetDynamicCloaking(pNewGateway, dwAuthLevel, dwImpLevel);
  7935. }
  7936. else
  7937. {
  7938. //Set Dcom blanket
  7939. SetInterfaceSecurityEx(pNewGateway, pNewAuthIdent, gpPrincipal, dwAuthLevel, dwImpLevel);
  7940. }
  7941. */
  7942. size_t len = wcstombs (NULL, var.bstrVal, MB_CUR_MAX);
  7943. if (-1 != len)
  7944. {
  7945. char *name = new char [len + 1];
  7946. name[0] = 0;
  7947. wcstombs (name, var.bstrVal, len);
  7948. name [len] = 0;
  7949. ISAMGetNestedNamespaces (absName, name, pNewGateway, dwAuthLevel, dwImpLevel, servername,
  7950. // loginMethod,
  7951. username, password, fIntpretEmptPwdAsBlank, locale, authority, map);
  7952. delete name;
  7953. }
  7954. if (pNewAuthIdent)
  7955. {
  7956. WbemFreeAuthIdentity( pNewAuthIdent );
  7957. pNewAuthIdent = NULL;
  7958. }
  7959. }
  7960. #ifndef USING_ABSPATH
  7961. if (mycontext)
  7962. mycontext->Release();
  7963. #endif
  7964. VariantClear(&var);
  7965. }
  7966. //Tidy Up
  7967. if (pNamespaceEnum)
  7968. {
  7969. pNamespaceEnum->Release();
  7970. }
  7971. }
  7972. delete absName;
  7973. if (pAuthIdent )
  7974. {
  7975. WbemFreeAuthIdentity( pAuthIdent );
  7976. pAuthIdent = NULL;
  7977. }
  7978. return NO_ISAM_ERR;
  7979. }
  7980. /***************************************************************************/
  7981. SWORD INTFUNC ISAMBuildTree (HTREEITEM hParent,
  7982. char *namespaceName, //relative name
  7983. CTreeCtrl& treeCtrl,
  7984. CConnectionDialog& dialog,
  7985. char *server,
  7986. // WBEM_LOGIN_AUTHENTICATION loginMethod,
  7987. char *username,
  7988. char *password,
  7989. BOOL fIntpretEmptPwdAsBlank,
  7990. char *locale,
  7991. char *authority,
  7992. BOOL fNeedChildren,
  7993. BOOL deep,
  7994. HTREEITEM& hTreeItem)
  7995. {
  7996. // Note the first name in the tree will be displayed as absolute
  7997. // could strip off the non- root bit - might do it
  7998. ODBCTRACE ("\nWBEM ODBC Driver :ISAMBuildTree\n");
  7999. // Add self
  8000. hTreeItem = dialog.InsertItem(treeCtrl, hParent, namespaceName);
  8001. ODBCTRACE ("\nWBEM ODBC Driver :Add Self :");
  8002. ODBCTRACE (namespaceName);
  8003. ODBCTRACE ("\n");
  8004. //Enumerate children and recurse
  8005. //BUT ONLY IF REQUESTED
  8006. if (fNeedChildren)
  8007. {
  8008. ODBCTRACE ("\nWBEM ODBC Driver : fNeedChildren = TRUE\n");
  8009. //Work out absolute name of new namespace
  8010. TV_ITEM tvItem2;
  8011. tvItem2.hItem = hTreeItem;
  8012. tvItem2.mask = TVIF_PARAM;
  8013. if (treeCtrl.GetItem (&tvItem2))
  8014. {
  8015. char* txt = ((ISAMTreeItemData*)tvItem2.lParam)->absName;
  8016. return ISAMBuildTreeChildren(hTreeItem, txt, treeCtrl, dialog,
  8017. server,
  8018. // loginMethod,
  8019. username, password, fIntpretEmptPwdAsBlank,locale, authority, deep);
  8020. }
  8021. else
  8022. {
  8023. return ISAM_ERROR;
  8024. }
  8025. }
  8026. else
  8027. {
  8028. ODBCTRACE ("\nWBEM ODBC Driver : fNeedChildren = FALSE\n");
  8029. }
  8030. return NO_ISAM_ERR;
  8031. }
  8032. /***************************************************************************/
  8033. // Checked for SetInterfaceSecurityEx on IWbemServices and IEnumWbemClassObject
  8034. SWORD INTFUNC ISAMBuildTreeChildren (HTREEITEM hParent,
  8035. char *namespaceName, //absolute name
  8036. CTreeCtrl& treeCtrl,
  8037. CConnectionDialog& dialog,
  8038. char *server,
  8039. // WBEM_LOGIN_AUTHENTICATION loginMethod,
  8040. char *username,
  8041. char *password,
  8042. BOOL fIntpretEmptPwdAsBlank,
  8043. char *locale,
  8044. char *authority,
  8045. BOOL deep)
  8046. {
  8047. ODBCTRACE ("\nWBEM ODBC Driver : ISAMBuildTreeChildren\n");
  8048. MyImpersonator fred (username, password, authority, "ISAMBuildTreeChildren");
  8049. //Advance to the namespace for which you require the children
  8050. DWORD dwAuthLevel = 0;
  8051. DWORD dwImpLevel = 0;
  8052. COAUTHIDENTITY* pAuthIdent = NULL;
  8053. IWbemServicesPtr pGateway = NULL;
  8054. ISAMGetGatewayServer (pGateway, (LPUSTR)server,
  8055. // loginMethod,
  8056. (LPUSTR)namespaceName, (LPUSTR)username, (LPUSTR)password, (LPUSTR)locale, (LPUSTR)authority,
  8057. dwAuthLevel, dwImpLevel, fIntpretEmptPwdAsBlank, &pAuthIdent);
  8058. if (pGateway == NULL)
  8059. {
  8060. ODBCTRACE ("\nWBEM ODBC Driver : ISAMBuildTreeChildren : Failed to get gateway server\n");
  8061. return ISAM_ERROR;
  8062. }
  8063. //cloaking
  8064. BOOL fIsLocalConnection = IsLocalServer(server);
  8065. if ( fIsLocalConnection && IsW2KOrMore() )
  8066. {
  8067. WbemSetDynamicCloaking(pGateway, dwAuthLevel, dwImpLevel);
  8068. }
  8069. //Indicate that this node has been checked for children
  8070. TV_ITEM tvItem;
  8071. tvItem.hItem = hParent;
  8072. tvItem.mask = TVIF_PARAM;
  8073. if (treeCtrl.GetItem (&tvItem))
  8074. {
  8075. ((ISAMTreeItemData*)tvItem.lParam)->fExpanded = TRUE;
  8076. }
  8077. //Get all children namespaces by fetching instances of __NAMESPACE
  8078. IEnumWbemClassObjectPtr pNamespaceEnum = NULL;
  8079. BSTR nspaceBSTR = SysAllocString(WBEMDR32_L_NAMESPACE);
  8080. IWbemContext* pContext = ISAMCreateLocaleIDContextObject(locale);
  8081. SCODE scCI = pGateway->CreateInstanceEnum(nspaceBSTR, 0, pContext, &pNamespaceEnum);
  8082. SysFreeString(nspaceBSTR);
  8083. if (pContext)
  8084. pContext->Release();
  8085. ISAMSetCloaking2(pNamespaceEnum,
  8086. fIsLocalConnection,
  8087. IsW2KOrMore(),
  8088. dwAuthLevel,
  8089. dwImpLevel,
  8090. pAuthIdent);
  8091. /*
  8092. if ( fIsLocalConnection && IsW2KOrMore() )
  8093. {
  8094. WbemSetDynamicCloaking(pNamespaceEnum, dwAuthLevel, dwImpLevel);
  8095. }
  8096. else
  8097. {
  8098. //Set Dcom blanket
  8099. SetInterfaceSecurityEx(pNamespaceEnum, pAuthIdent, gpPrincipal, dwAuthLevel, dwImpLevel);
  8100. }
  8101. */
  8102. if ( FAILED(scCI) || (pNamespaceEnum == NULL) )
  8103. {
  8104. return ISAM_ERROR;
  8105. }
  8106. ULONG uRet = 0;
  8107. IWbemClassObjectPtr pNewInst = NULL;
  8108. pNamespaceEnum->Reset();
  8109. while ( S_OK == pNamespaceEnum->Next(-1, 1, &pNewInst, &uRet) )
  8110. {
  8111. //(14)
  8112. VARIANTARG var;
  8113. BSTR thenameBSTR = SysAllocString(WBEMDR32_L_NAME);
  8114. pNewInst->Get(thenameBSTR, 0, &var, NULL, NULL);
  8115. SysFreeString(thenameBSTR);
  8116. //RAID 42256
  8117. UINT cpThread = Utility_GetCodePageFromLCID(GetThreadLocale());
  8118. int len = WideCharToMultiByte(cpThread,WC_COMPOSITECHECK, (const wchar_t*)var.bstrVal, -1,
  8119. NULL, 0, NULL, NULL);
  8120. if (-1 != len)
  8121. {
  8122. char *name = new char [len + 1];
  8123. //RAID 42256
  8124. _bstr_t myValue((BSTR)var.bstrVal);
  8125. Utility_WideCharToDBCS(myValue, &name, len);
  8126. name [len] = '\0';
  8127. //Check if this child already exists in tree
  8128. CString fullPath = namespaceName;
  8129. fullPath += "\\";
  8130. fullPath += name;
  8131. HTREEITEM hDummy;
  8132. if (! dialog.FindAbsName((char*)(LPCTSTR)fullPath, hParent, hDummy) )
  8133. {
  8134. //Add child to tree control
  8135. HTREEITEM newTreeItem = NULL;
  8136. ISAMBuildTree (hParent, name,
  8137. treeCtrl,
  8138. dialog,
  8139. server,
  8140. // loginMethod,
  8141. username,
  8142. password,
  8143. fIntpretEmptPwdAsBlank,
  8144. locale,
  8145. authority,
  8146. deep,
  8147. deep,
  8148. newTreeItem);
  8149. if (deep && newTreeItem)
  8150. dialog.AddNamespaces(newTreeItem, FALSE);
  8151. }
  8152. delete name;
  8153. }
  8154. //Tidy Up
  8155. VariantClear(&var);
  8156. }
  8157. if (pAuthIdent )
  8158. {
  8159. WbemFreeAuthIdentity( pAuthIdent );
  8160. pAuthIdent = NULL;
  8161. }
  8162. return NO_ISAM_ERR;
  8163. }
  8164. /***************************************************************************/
  8165. // Checked for SetInterfaceSecurityEx on IWbemServices
  8166. void ISAMGetIWbemServices(LPISAM lpISAM, CSafeWbemServices& mServices, IWbemServicesPtr& myServicesPtr)
  8167. {
  8168. myServicesPtr = NULL;
  8169. mServices.GetInterfacePtr(myServicesPtr);
  8170. ISAMPatchUpGatewaySecurity(lpISAM, myServicesPtr);
  8171. }
  8172. void CSafeWbemServices::Transfer(CSafeWbemServices& original)
  8173. {
  8174. m_pStream = original.m_pStream;
  8175. original.m_pStream = NULL;
  8176. m_params = original.m_params;
  8177. original.m_params = NULL;
  8178. m_fValid = original.m_fValid;
  8179. original.m_fValid = FALSE;
  8180. }
  8181. HRESULT CSafeWbemServices::GetInterfacePtr(IWbemServicesPtr& pServices)
  8182. {
  8183. bool bRet = false;
  8184. if(m_pStream)
  8185. {
  8186. HRESULT hr;
  8187. //pop Com pointer out from stream
  8188. //as you are popping into &SmartPointer so increase in ref count
  8189. hr = CoGetInterfaceAndReleaseStream(m_pStream,IID_IWbemServices,(void**)&pServices);
  8190. m_pStream = NULL;
  8191. if (m_params)
  8192. m_params->m_myStream = NULL;
  8193. bRet = true;
  8194. if ( SUCCEEDED(hr) )
  8195. {
  8196. //push value back into stream
  8197. //as you are CoMarshalling into stream ref count bumped up by one
  8198. hr = CoMarshalInterThreadInterfaceInStream(IID_IWbemServices,pServices,&m_pStream);
  8199. if (m_params)
  8200. m_params->m_myStream = m_pStream;
  8201. }
  8202. }
  8203. return S_OK;
  8204. }
  8205. // Checked for SetInterfaceSecurityEx on IWbemServices
  8206. void CSafeWbemServices::SetInterfacePtr(LPISAM lpISAM, LPUSTR lpQualifierName, SWORD cbQualifierName)
  8207. {
  8208. ODBCTRACE("\nWBEM ODBC Driver :CSafeWbemServices::SetInterfacePtr\n");
  8209. //
  8210. //Create interface on Working Thread
  8211. //
  8212. //Create parameter set so that an equivalent one can be created
  8213. //on the working thread. (never used but must exist)
  8214. if (m_params)
  8215. {
  8216. BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REMOVE_SERVICES, 0, (LPARAM)m_params);
  8217. m_pStream = NULL;
  8218. delete m_params;
  8219. m_params = NULL;
  8220. }
  8221. m_params = new MyWorkingThreadParams(lpISAM, lpQualifierName, cbQualifierName, m_pStream);
  8222. //post message to create this object on working thread
  8223. ODBCTRACE("\nWBEM ODBC Driver :CSafeWbemServices::SetInterfacePtr : pos 1\n");
  8224. BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_CREATE_SERVICES, 0, (LPARAM)m_params);
  8225. ODBCTRACE("\nWBEM ODBC Driver :CSafeWbemServices::SetInterfacePtr : pos 2\n");
  8226. m_fValid = ( SUCCEEDED(m_params->sc) ) ? TRUE : FALSE;
  8227. m_pStream = m_params->m_myStream;
  8228. }
  8229. CSafeWbemServices::CSafeWbemServices()
  8230. {
  8231. m_params = NULL;
  8232. m_fValid = FALSE;
  8233. m_pStream = NULL;
  8234. }
  8235. CSafeWbemServices::~CSafeWbemServices()
  8236. {
  8237. //clean up working thread parameters
  8238. //and IWbemServices object on working thread
  8239. if (m_params)
  8240. {
  8241. BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REMOVE_SERVICES, 0, (LPARAM)m_params);
  8242. m_pStream = NULL;
  8243. delete m_params;
  8244. m_params = NULL;
  8245. }
  8246. }
  8247. void CSafeWbemServices::Invalidate()
  8248. {
  8249. if (m_params)
  8250. {
  8251. BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REMOVE_SERVICES, 0, (LPARAM)m_params);
  8252. m_pStream = NULL;
  8253. delete m_params;
  8254. m_params = NULL;
  8255. }
  8256. m_fValid = FALSE;
  8257. m_pStream = NULL;
  8258. }
  8259. BOOL CSafeWbemServices::PostSuspensiveThreadMessage(DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam)
  8260. {
  8261. BOOL status = FALSE;
  8262. ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage\n");
  8263. EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
  8264. ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage : in critical section\n");
  8265. //check data in lParam
  8266. MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
  8267. //Extract Event Handle
  8268. HANDLE EventHnd = myData->m_EventHnd;
  8269. //make sure the event is in its non-signaled state
  8270. //before posting the thread message
  8271. ResetEvent(EventHnd);
  8272. ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage: about to leave critical section\n");
  8273. LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
  8274. //post message
  8275. ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage: PostThreadMessage\n");
  8276. status = PostThreadMessage(idThread, Msg, wParam, lParam);
  8277. if (!status)
  8278. {
  8279. ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage: PostThreadMessage failed\n");
  8280. }
  8281. //Make it suspensive
  8282. WaitForSingleObject(EventHnd, INFINITE);
  8283. ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage : After wait for single object\n");
  8284. return status;
  8285. }
  8286. // Checked for SetInterfaceSecurityEx on IWbemServices
  8287. LONG OnUserCreateServices(UINT wParam, LONG lParam)
  8288. {
  8289. ODBCTRACE("\n\n*****WBEM ODBC Driver : OnUserCreateServices*****\n\n");
  8290. COleInitializationManager oleManager;
  8291. EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
  8292. ODBCTRACE("\nWBEM ODBC Driver : OnUserCreateServices : entered critial section\n");
  8293. //this is done on the worker thread
  8294. //check data in lParam
  8295. MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
  8296. //Tidy up existing stream
  8297. if(myData->m_myStream)
  8298. {
  8299. //pop interface into smart pointer.
  8300. //As it goes into &SmartPointer ref count stays the same
  8301. IWbemServicesPtr tempy;
  8302. HRESULT hr = CoGetInterfaceAndReleaseStream(myData->m_myStream, IID_IWbemServices, (void**)&tempy);
  8303. //when SmartPointer goes out of scope it will call Release and free up interface cleanly
  8304. }
  8305. myData->m_myStream = NULL;
  8306. //Setup impersonation on working thread
  8307. MyImpersonator im (myData->m_lpISAM, "Worker Thread:CreateServices");
  8308. //now add IWbemServices
  8309. IWbemServicesPtr tempy = NULL;
  8310. ISAMGetGatewayServer(tempy, myData->m_lpISAM, myData->m_lpQualifierName, myData->m_cbQualifierName);
  8311. myData->pGateway = tempy.Detach();
  8312. // CBString myServerStr;
  8313. // myServerStr.AddString( (LPSTR)myData->m_lpISAM->szServer, FALSE );
  8314. // CServerLocationCheck myCheck (myServerStr);
  8315. BOOL fIsLocalConnection = myData->m_lpISAM->fIsLocalConnection;//myCheck.IsLocal();
  8316. if ( fIsLocalConnection && (myData->m_lpISAM->fW2KOrMore) )
  8317. {
  8318. WbemSetDynamicCloaking(myData->pGateway, myData->m_lpISAM->dwAuthLevel, myData->m_lpISAM->dwImpLevel);
  8319. }
  8320. if (myData->pGateway)
  8321. {
  8322. HRESULT hr;
  8323. ODBCTRACE("\nWBEM ODBC Driver OnUserCreateServices : succeeded to create IWbemServices on working thread\n");
  8324. //push Com pointer in stream
  8325. //The CoMarshalling will bump up ref count by one
  8326. if (SUCCEEDED(hr =
  8327. CoMarshalInterThreadInterfaceInStream(IID_IWbemServices, myData->pGateway, &(myData->m_myStream))))
  8328. {
  8329. //
  8330. //Created services pointer now to be marshalled in stream
  8331. myData->sc = WBEM_S_NO_ERROR;
  8332. }
  8333. else
  8334. myData->sc = hr;
  8335. }
  8336. else
  8337. {
  8338. myData->sc = WBEM_E_FAILED;
  8339. ODBCTRACE("\nWBEM ODBC Driver OnUserCreateServices : failed to create IWbemServices on working thread\n");
  8340. }
  8341. //so that WaitForSingleObject returns
  8342. SetEvent(myData->m_EventHnd);
  8343. LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
  8344. ODBCTRACE("\nWBEM ODBC Driver : OnUserCreateServices : left critial section\n");
  8345. return 0;
  8346. }
  8347. LONG OnUserRemoveServices(UINT wParam, LONG lParam)
  8348. {
  8349. ODBCTRACE("\n\n*****WBEM ODBC Driver : OnUserRemoveServices*****\n\n");
  8350. COleInitializationManager oleManager;
  8351. EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
  8352. ODBCTRACE("\nWBEM ODBC Driver : OnUserRemoveServices : entered crital section\n");
  8353. //this is done on the worker thread
  8354. //check data in lParam
  8355. MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
  8356. ODBCTRACE("\nWBEM ODBC Driver : OnUserRemoveServices : about to Release IWbemServices\n");
  8357. //Remove the interface form the stream
  8358. if(myData->m_myStream)
  8359. {
  8360. //the release should pop any Com pointers out from stream
  8361. //the use of smart pointers should call Release to free up
  8362. // the Com pointer
  8363. IWbemServicesPtr tempy = NULL;
  8364. HRESULT hr = CoGetInterfaceAndReleaseStream(myData->m_myStream, IID_IWbemServices, (void**)&tempy);
  8365. myData->m_myStream = NULL;
  8366. }
  8367. if (myData->pGateway)
  8368. {
  8369. //remove the IWbemServices pointer from worker thread
  8370. myData->pGateway->Release();
  8371. myData->pGateway = NULL;
  8372. }
  8373. //so that WaitForSingleObject returns
  8374. SetEvent(myData->m_EventHnd);
  8375. LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
  8376. ODBCTRACE("\nWBEM ODBC Driver : OnUserRemoveServices : left critial section\n");
  8377. return 0;
  8378. }
  8379. LONG OnUserCreateEnum(UINT wParam, LONG lParam)
  8380. {
  8381. ODBCTRACE("\n\n*****WBEM ODBC Driver : OnUserCreateEnum*****\n\n");
  8382. COleInitializationManager oleManager;
  8383. EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
  8384. ODBCTRACE("\nWBEM ODBC Driver : OnUserCreateEnum : entered critial section\n");
  8385. //this is done on the worker thread
  8386. //check data in lParam
  8387. MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
  8388. //now add IEnumWbemClassObject
  8389. //first check if you need to ExecQuery or CreateInstanceEnum
  8390. //remember to return scode in myData
  8391. if(myData->m_myStream)
  8392. {
  8393. //the release should pop any Com pointers out from stream
  8394. //the use of smart pointers should call Release to free up
  8395. // the Com pointer
  8396. IEnumWbemClassObjectPtr tempy = NULL;
  8397. HRESULT hr = CoGetInterfaceAndReleaseStream(myData->m_myStream, IID_IEnumWbemClassObject, (void**)&tempy);
  8398. }
  8399. myData->m_myStream = NULL;
  8400. //Create tempory context object
  8401. IWbemContext* pContext = ISAMCreateLocaleIDContextObject(myData->m_lpISAM->m_Locale);
  8402. //Setup impersonation on working thread
  8403. MyImpersonator im (myData->m_lpISAM, "Worker Thread");
  8404. IWbemServicesPtr myServicesPtr = NULL;
  8405. ISAMGetIWbemServices(myData->m_lpISAM, *(myData->pServ), myServicesPtr);
  8406. // CBString myServerStr;
  8407. // myServerStr.AddString( (LPSTR)myData->m_lpISAM->szServer, FALSE );
  8408. // CServerLocationCheck myCheck (myServerStr);
  8409. BOOL fIsLocalConnection = myData->m_lpISAM->fIsLocalConnection;//myCheck.IsLocal();
  8410. if ( fIsLocalConnection && (myData->m_lpISAM->fW2KOrMore) )
  8411. {
  8412. WbemSetDynamicCloaking(myServicesPtr, myData->m_lpISAM->dwAuthLevel, myData->m_lpISAM->dwImpLevel);
  8413. }
  8414. DWORD dwSize;
  8415. char buffer[1001];
  8416. buffer[0] = 0;
  8417. GetUserName(buffer, &dwSize);
  8418. CString lpMessage;
  8419. lpMessage.Format("\nUser Account just before Enum or ExecQuery : %s\n", buffer);
  8420. ODBCTRACE(lpMessage);
  8421. if ( (myData->fIsExecQuery) == WMI_CREATE_INST_ENUM )
  8422. {
  8423. //CreateInstanceEnum
  8424. myData->sc = myServicesPtr->CreateInstanceEnum(myData->tableName, 0, pContext, &(myData->pEnum));
  8425. }
  8426. else
  8427. {
  8428. //ExecQuery
  8429. long flags = 0;
  8430. if ( (myData->fIsExecQuery) == WMI_EXEC_FWD_ONLY )
  8431. flags = WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY;
  8432. else
  8433. if ( (myData->fIsExecQuery) == WMI_PROTOTYPE )
  8434. flags = WBEM_FLAG_PROTOTYPE;
  8435. BSTR wqlBSTR = SysAllocString(WBEMDR32_L_WQL);
  8436. myData->sc = myServicesPtr->ExecQuery(wqlBSTR, myData->sqltextBSTR, flags, pContext, &(myData->pEnum));
  8437. SysFreeString(wqlBSTR);
  8438. }
  8439. //Tidy up
  8440. if (pContext)
  8441. pContext->Release();
  8442. if ( SUCCEEDED(myData->sc) )
  8443. {
  8444. ODBCTRACE("\nWBEM ODBC Driver OnUserCreateEnum : succeeded to create IEnumWbemClassObject on working thread\n");
  8445. if (myData->pEnum)
  8446. {
  8447. //push Com pointer in stream
  8448. //The CoMarshalling will bump the ref count up by one
  8449. if (FAILED(
  8450. CoMarshalInterThreadInterfaceInStream(IID_IEnumWbemClassObject, myData->pEnum, &(myData->m_myStream))))
  8451. {
  8452. ODBCTRACE("\nWBEM ODBC Driver OnUserCreateEnum : failed to CoMarshalInterThreadInterfaceInStream\n");
  8453. }
  8454. }
  8455. }
  8456. else
  8457. {
  8458. ODBCTRACE("\nWBEM ODBC Driver OnUserCreateEnum : failed to create IEnumWbemClassObject on working thread\n");
  8459. }
  8460. //so that WaitForSingleObject returns
  8461. SetEvent(myData->m_EventHnd);
  8462. LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
  8463. ODBCTRACE("\nWBEM ODBC Driver : OnUserCreateEnum : left critial section\n");
  8464. return 0;
  8465. }
  8466. LONG OnUserRemoveEnum(UINT wParam, LONG lParam)
  8467. {
  8468. ODBCTRACE("\n\n*****WBEM ODBC Driver : OnUserRemoveEnum*****\n\n");
  8469. COleInitializationManager oleManager;
  8470. EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
  8471. ODBCTRACE("\nWBEM ODBC Driver : OnUserRemoveEnum : entered crital section\n");
  8472. //this is done on the worker thread
  8473. //check data in lParam
  8474. MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
  8475. ODBCTRACE("\nWBEM ODBC Driver : OnUserRemoveEnum : about to Release IEnumWbemClassObject\n");
  8476. if(myData->m_myStream)
  8477. {
  8478. //the release should pop any Com pointers out from stream
  8479. //the use of smart pointers should call Release to free up
  8480. // the Com pointer
  8481. IEnumWbemClassObjectPtr tempy = NULL;
  8482. HRESULT hr = CoGetInterfaceAndReleaseStream(myData->m_myStream, IID_IEnumWbemClassObject, (void**)&tempy);
  8483. }
  8484. myData->m_myStream = NULL;
  8485. if (myData->pEnum)
  8486. {
  8487. //remove the IWbemServices pointer from worker thread
  8488. myData->pEnum->Release();
  8489. myData->pEnum = NULL;
  8490. }
  8491. //so that WaitForSingleObject returns
  8492. SetEvent(myData->m_EventHnd);
  8493. LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
  8494. ODBCTRACE("\nWBEM ODBC Driver : OnUserRemoveEnum : left critial section\n");
  8495. return 0;
  8496. }
  8497. void OnIncreamentRefCount(UINT wParam, LONG lParam)
  8498. {
  8499. EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
  8500. ++glob_myWorkerThread.m_cRef;
  8501. CString message;
  8502. message.Format ("\n***** Working thread count (increment) = %ld *****\n", glob_myWorkerThread.m_cRef);
  8503. ODBCTRACE(message);
  8504. //check data in lParam
  8505. MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
  8506. //so that WaitForSingleObject returns
  8507. SetEvent(myData->m_EventHnd);
  8508. LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
  8509. }
  8510. void OnDecreamentRefCount(UINT wParam, LONG lParam)
  8511. {
  8512. EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
  8513. if (glob_myWorkerThread.m_cRef)
  8514. {
  8515. --glob_myWorkerThread.m_cRef;
  8516. CString message;
  8517. message.Format ("\n***** Working thread count (descrement) = %ld *****\n", glob_myWorkerThread.m_cRef);
  8518. ODBCTRACE(message);
  8519. }
  8520. //check data in lParam
  8521. MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
  8522. //so that WaitForSingleObject returns
  8523. SetEvent(myData->m_EventHnd);
  8524. LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
  8525. }
  8526. //DWORD WINAPI MyWorkerThread(LPVOID myVal)
  8527. unsigned __stdcall MyWorkerThread(LPVOID myVal)
  8528. {
  8529. //this is done on the worker thread
  8530. DWORD dwThreadId = GetCurrentThreadId();
  8531. //force a thread message queue to be created
  8532. MSG msg;
  8533. PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
  8534. //so that WaitForSingleObject returns
  8535. //infinate loop for thread to read messages
  8536. BOOL status = FALSE;
  8537. BOOL myLoop = TRUE;
  8538. while (myLoop)
  8539. {
  8540. //look for messages in the range WM_USER, MYUSRMESS_REMOVE_ENUM
  8541. status = PeekMessage(&msg, NULL, WM_USER, MYUSRMESS_REMOVE_ENUM, PM_NOREMOVE);
  8542. if (status)
  8543. {
  8544. switch (msg.message)
  8545. {
  8546. case MYUSRMESS_CREATE_SERVICES:
  8547. {
  8548. ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_CREATE_SERVICES\n");
  8549. PeekMessage(&msg, NULL, MYUSRMESS_CREATE_SERVICES, MYUSRMESS_CREATE_SERVICES, PM_REMOVE);
  8550. OnUserCreateServices(msg.wParam, msg.lParam);
  8551. }
  8552. break;
  8553. case MYUSRMESS_REMOVE_SERVICES:
  8554. {
  8555. ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_REMOVE_SERVICES\n");
  8556. PeekMessage(&msg, NULL, MYUSRMESS_REMOVE_SERVICES, MYUSRMESS_REMOVE_SERVICES, PM_REMOVE);
  8557. OnUserRemoveServices(msg.wParam, msg.lParam);
  8558. }
  8559. break;
  8560. case MYUSRMESS_CLOSE_WKERTHRED:
  8561. {
  8562. ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_CLOSE_WKERTHRED\n");
  8563. PeekMessage(&msg, NULL, MYUSRMESS_CLOSE_WKERTHRED, MYUSRMESS_CLOSE_WKERTHRED, PM_REMOVE);
  8564. ISAMCloseWorkerThread2(msg.wParam, msg.lParam);
  8565. myLoop = FALSE; //need to exit thread when ISAMCloseWorkerThread2 exists
  8566. }
  8567. break;
  8568. case MYUSRMESS_REFCOUNT_INCR:
  8569. {
  8570. ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_REFCOUNT_INCR\n");
  8571. PeekMessage(&msg, NULL, MYUSRMESS_REFCOUNT_INCR, MYUSRMESS_REFCOUNT_INCR, PM_REMOVE);
  8572. OnIncreamentRefCount(msg.wParam, msg.lParam);
  8573. }
  8574. break;
  8575. case MYUSRMESS_REFCOUNT_DECR:
  8576. {
  8577. ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_REFCOUNT_DECR\n");
  8578. PeekMessage(&msg, NULL, MYUSRMESS_REFCOUNT_DECR, MYUSRMESS_REFCOUNT_DECR, PM_REMOVE);
  8579. OnDecreamentRefCount(msg.wParam, msg.lParam);
  8580. }
  8581. break;
  8582. case MYUSRMESS_CREATE_ENUM:
  8583. {
  8584. ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_CREATE_ENUM\n");
  8585. PeekMessage(&msg, NULL, MYUSRMESS_CREATE_ENUM, MYUSRMESS_CREATE_ENUM, PM_REMOVE);
  8586. OnUserCreateEnum(msg.wParam, msg.lParam);
  8587. }
  8588. break;
  8589. case MYUSRMESS_REMOVE_ENUM:
  8590. {
  8591. ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_REMOVE_ENUM\n");
  8592. PeekMessage(&msg, NULL, MYUSRMESS_REMOVE_ENUM, MYUSRMESS_REMOVE_ENUM, PM_REMOVE);
  8593. OnUserRemoveEnum(msg.wParam, msg.lParam);
  8594. }
  8595. break;
  8596. default:
  8597. {
  8598. CString myMessage;
  8599. myMessage.Format("\nWBEM ODBC Driver : MyWorkerThread : unknown message %ld which I will remove off the thread queue\n", msg.message);
  8600. ODBCTRACE(myMessage);
  8601. PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
  8602. }
  8603. break;
  8604. }
  8605. }
  8606. Sleep(10);
  8607. }
  8608. //The thread will exit here
  8609. return 500;
  8610. }
  8611. CWorkerThreadManager::CWorkerThreadManager()
  8612. {
  8613. fIsValid = FALSE;
  8614. //initalize critical section for shared data
  8615. InitializeCriticalSection(&m_cs);
  8616. dwThreadId = 0;
  8617. m_cRef = 0;
  8618. hr = NULL;
  8619. }
  8620. void CWorkerThreadManager::CreateWorkerThread()
  8621. {
  8622. //Create a worker thread
  8623. EnterCriticalSection(& m_cs );
  8624. dwThreadId = 0;
  8625. m_cRef = 1; //sets the ref count to 1
  8626. hr = (HANDLE)_beginthreadex(NULL, 0, &MyWorkerThread, NULL, 0, (unsigned int*)&dwThreadId);
  8627. fIsValid = TRUE;
  8628. LeaveCriticalSection(& m_cs );
  8629. }
  8630. void CWorkerThreadManager::Invalidate()
  8631. {
  8632. //only called after working thread is exited
  8633. dwThreadId = 0;
  8634. hr = NULL;
  8635. fIsValid = FALSE;
  8636. m_cRef = 0;
  8637. }
  8638. void ISAMCloseWorkerThread1()
  8639. {
  8640. ODBCTRACE("\n\n***** ISAMCloseWorkerThread1 *****\n\n");
  8641. MyWorkingThreadParams* m_params = new MyWorkingThreadParams(NULL, NULL, 0, NULL);
  8642. EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
  8643. HANDLE EventHnd = m_params->m_EventHnd;
  8644. ResetEvent(EventHnd);
  8645. LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
  8646. PostThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_CLOSE_WKERTHRED, 0, (LPARAM)m_params);
  8647. //Wait on termination of thread
  8648. WaitForSingleObject(glob_myWorkerThread.GetThreadHandle(), INFINITE);
  8649. delete m_params;
  8650. }
  8651. CWorkerThreadManager::~CWorkerThreadManager()
  8652. {
  8653. //close thread
  8654. ODBCTRACE("\n\n***** Shutting down worker thread *****\n\n");
  8655. //close critical section
  8656. DeleteCriticalSection(&m_cs);
  8657. }
  8658. void ISAMCloseWorkerThread2(UINT wParam, LONG lParam)
  8659. {
  8660. //this is done on the worker thread
  8661. ODBCTRACE("\n\n***** ISAMCloseWorkerThread2 *****\n\n");
  8662. EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
  8663. //this is done on the worker thread
  8664. //check data in lParam
  8665. MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
  8666. //so that WaitForSingleObject returns
  8667. //so ISAMCloseWorkerThread1 can continue and Invalidate the
  8668. //global worker thread
  8669. SetEvent(myData->m_EventHnd);
  8670. LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
  8671. //when you exit this method and return to 'MyWorkerThread'
  8672. //it will exit the loop and thus automatically terminate the thread
  8673. }
  8674. MyWorkingThreadParams::MyWorkingThreadParams(LPISAM lpISAM, LPUSTR lpQualifierName, SWORD cbQualifierName, IStream* myStream)
  8675. {
  8676. //This will be created on worker thread
  8677. m_lpISAM = lpISAM;
  8678. m_lpQualifierName = lpQualifierName;
  8679. m_cbQualifierName = cbQualifierName;
  8680. m_myStream = myStream;
  8681. pGateway = NULL; //will be filled in later
  8682. pEnum = NULL;
  8683. //Create an event object
  8684. //so that message to worker thread can be suspensive
  8685. m_EventHnd = CreateEvent(NULL, TRUE, FALSE, NULL);
  8686. }
  8687. MyWorkingThreadParams::MyWorkingThreadParams(LPISAM lpISAM, WmiEnumTypes a_fIsExecQuery, BSTR theBstrValue, CSafeWbemServices* a_pServ, IStream* myStream)
  8688. {
  8689. //This will be created on worker thread
  8690. m_lpISAM = lpISAM;
  8691. fIsExecQuery = a_fIsExecQuery;
  8692. sqltextBSTR = NULL;
  8693. tableName = NULL;
  8694. if (a_fIsExecQuery != WMI_CREATE_INST_ENUM)
  8695. {
  8696. sqltextBSTR = theBstrValue;
  8697. }
  8698. else
  8699. {
  8700. tableName = theBstrValue;
  8701. }
  8702. pServ = a_pServ;
  8703. m_myStream = myStream;
  8704. pGateway = NULL;
  8705. pEnum = NULL; //will be filled in later
  8706. sc = 0;
  8707. //Create an event object
  8708. //so that message to worker thread can be suspensive
  8709. m_EventHnd = CreateEvent(NULL, TRUE, FALSE, NULL);
  8710. }
  8711. MyWorkingThreadParams::~MyWorkingThreadParams()
  8712. {
  8713. //This will be cleaned up on worker thread
  8714. if (m_EventHnd)
  8715. {
  8716. CloseHandle(m_EventHnd);
  8717. }
  8718. if (pGateway)
  8719. {
  8720. ODBCTRACE("\nShould never get here, deleting Gateway\n");
  8721. }
  8722. if (pEnum)
  8723. {
  8724. ODBCTRACE("\nShould never get here, deleting Enumeration\n");
  8725. }
  8726. }
  8727. COleInitializationManager::COleInitializationManager()
  8728. {
  8729. //Initialize Ole
  8730. OleInitialize(0);
  8731. }
  8732. COleInitializationManager::~COleInitializationManager()
  8733. {
  8734. //Uninitialize OLE
  8735. OleUninitialize();
  8736. }
  8737. CSafeIEnumWbemClassObject::CSafeIEnumWbemClassObject()
  8738. {
  8739. m_fValid = FALSE;
  8740. m_pStream = NULL;
  8741. m_params = NULL;
  8742. }
  8743. CSafeIEnumWbemClassObject::~CSafeIEnumWbemClassObject()
  8744. {
  8745. if (m_params)
  8746. {
  8747. BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REMOVE_ENUM, 0, (LPARAM)m_params);
  8748. m_pStream = NULL;
  8749. delete m_params;
  8750. m_params = NULL;
  8751. }
  8752. }
  8753. BOOL CSafeIEnumWbemClassObject::PostSuspensiveThreadMessage(DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam)
  8754. {
  8755. BOOL status = FALSE;
  8756. ODBCTRACE("\nWBEM ODBC Driver : CSafeIEnumWbemClassObject::PostSuspensiveThreadMessage\n");
  8757. EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
  8758. ODBCTRACE("\nWBEM ODBC Driver : CSafeIEnumWbemClassObject::PostSuspensiveThreadMessage : in critical section\n");
  8759. //check data in lParam
  8760. MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
  8761. //Extract Event Handle
  8762. HANDLE EventHnd = myData->m_EventHnd;
  8763. //make sure the event is in its non-signaled state
  8764. //before posting the thread message
  8765. ResetEvent(EventHnd);
  8766. ODBCTRACE("\nWBEM ODBC Driver : CSafeIEnumWbemClassObject::PostSuspensiveThreadMessage: about to leave critical section\n");
  8767. LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
  8768. //post message
  8769. ODBCTRACE("\nWBEM ODBC Driver : CSafeIEnumWbemClassObject::PostSuspensiveThreadMessage: PostThreadMessage\n");
  8770. status = PostThreadMessage(idThread, Msg, wParam, lParam);
  8771. if (!status)
  8772. {
  8773. ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage: PostThreadMessage failed\n");
  8774. }
  8775. //Make it suspensive
  8776. WaitForSingleObject(EventHnd, INFINITE);
  8777. ODBCTRACE("\nWBEM ODBC Driver : CSafeIEnumWbemClassObject::PostSuspensiveThreadMessage : After wait for single object\n");
  8778. return status;
  8779. }
  8780. HRESULT CSafeIEnumWbemClassObject::GetInterfacePtr(IEnumWbemClassObjectPtr& pIEnum)
  8781. {
  8782. bool bRet = false;
  8783. if(m_pStream)
  8784. {
  8785. HRESULT hr;
  8786. //pop Com pointer out from stream
  8787. //as we are using &SmartPointer the ref count stays the same
  8788. hr = CoGetInterfaceAndReleaseStream(m_pStream,IID_IEnumWbemClassObject,(void**)&pIEnum);
  8789. m_pStream = NULL;
  8790. if (m_params)
  8791. m_params->m_myStream = NULL;
  8792. bRet = true;
  8793. if ( SUCCEEDED(hr) )
  8794. {
  8795. //push the interface back into stream.
  8796. //As we are CoMarshalling the interface the ref count bumps up by one
  8797. hr = CoMarshalInterThreadInterfaceInStream(IID_IEnumWbemClassObject,pIEnum,&m_pStream);
  8798. if (m_params)
  8799. m_params->m_myStream = m_pStream;
  8800. }
  8801. }
  8802. return S_OK;
  8803. }
  8804. HRESULT CSafeIEnumWbemClassObject::SetInterfacePtr(LPISAM lpISAM, WmiEnumTypes fIsEXecQuery, BSTR theBstrValue, CSafeWbemServices* pServ)
  8805. {
  8806. //Tidy up any previous values
  8807. if (m_params)
  8808. {
  8809. BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REMOVE_ENUM, 0, (LPARAM)m_params);
  8810. m_pStream = NULL;
  8811. delete m_params;
  8812. m_params = NULL;
  8813. }
  8814. //Set new value
  8815. m_params = new MyWorkingThreadParams(lpISAM, fIsEXecQuery, theBstrValue, pServ, m_pStream);
  8816. //post message to create this object on working thread
  8817. ODBCTRACE("\nWBEM ODBC Driver :CSafeWbemServices::SetInterfacePtr : pos 1\n");
  8818. BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_CREATE_ENUM, 0, (LPARAM)m_params);
  8819. ODBCTRACE("\nWBEM ODBC Driver :CSafeWbemServices::SetInterfacePtr : pos 2\n");
  8820. m_fValid = ( SUCCEEDED(m_params->sc) ) ? TRUE : FALSE;
  8821. m_pStream = m_params->m_myStream;
  8822. return (m_params->sc);
  8823. }
  8824. void CSafeIEnumWbemClassObject::Invalidate()
  8825. {
  8826. if (m_params)
  8827. {
  8828. BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REMOVE_ENUM, 0, (LPARAM)m_params);
  8829. m_pStream = NULL;
  8830. delete m_params;
  8831. m_params = NULL;
  8832. }
  8833. m_pStream = NULL;
  8834. m_fValid = FALSE;
  8835. }
  8836. // Checked for SetInterfaceSecurityEx on IWbemServices
  8837. BOOL IsLocalServer(LPSTR szServer)
  8838. {
  8839. //A local server could be specified as a NULL or blank string
  8840. //a '.' character or a fully qualified \\MyLocalServer
  8841. //we need to check each of these cases
  8842. if (!szServer || !*szServer)
  8843. return TRUE;
  8844. // Get past the \\ if any.
  8845. if (szServer[0] == '\\' && szServer[1] == '\\')
  8846. szServer += 2;
  8847. // Check for '.'.
  8848. if (!strcmp(szServer, "."))
  8849. return TRUE;
  8850. // Get the server name and compare.
  8851. char szName[MAX_COMPUTERNAME_LENGTH + 1] = "";
  8852. DWORD dwSize = sizeof(szName);
  8853. GetComputerNameA(szName, &dwSize);
  8854. return _stricmp(szServer, szName) == 0;
  8855. }