Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

383 lines
13 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // Database.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // Implementation of the CDatabase class. Mainly initialize, compact...
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 02/12/1999 Original version. Thierry Perraut
  16. //
  17. //////////////////////////////////////////////////////////////////////////////
  18. #include "precomp.hpp"
  19. #include "database.h"
  20. #include "msjetoledb.h"
  21. #include "jetoledb.h"
  22. //////////////////////////////////////////////////////////////////////////////
  23. //
  24. // Uninitialize: called at the end by main(), that calls compact()
  25. //
  26. //////////////////////////////////////////////////////////////////////////////
  27. HRESULT CDatabase::Uninitialize (bool bFatalError)
  28. {
  29. HRESULT hres;
  30. #ifdef THPDEBUG
  31. bFatalError = false;
  32. #endif
  33. ////////////////////////////////////////
  34. // if a fatal error occured before
  35. ////////////////////////////////////////
  36. if (bFatalError)
  37. {
  38. hres = (m_pITransactionLocal->Abort (NULL, TRUE, FALSE));
  39. TracePrintf ("Fatal Error: import to the database aborted.");
  40. }
  41. else
  42. {
  43. hres = (m_pITransactionLocal->Commit (TRUE, XACTTC_SYNC, 0));
  44. #ifdef DEBUG
  45. TracePrintf ("Successful import.\n");
  46. #endif
  47. }
  48. ///////////
  49. // Clean
  50. ///////////
  51. m_pIOpenRowset->Release();
  52. m_pITransactionLocal->Release();
  53. m_pIDBCreateSession->Release();
  54. ////////////////////////////////////////
  55. // compact the DB
  56. ////////////////////////////////////////
  57. CHECK_CALL_HRES (Compact());
  58. m_pIDBInitialize->Release();
  59. return hres;
  60. }
  61. //////////////////////////////////////////////////////////////////////////////
  62. //
  63. // Compact the database
  64. //
  65. //////////////////////////////////////////////////////////////////////////////
  66. HRESULT CDatabase::Compact ()
  67. {
  68. HRESULT hres;
  69. CHECK_CALL_HRES (m_pIDBInitialize->Uninitialize ());
  70. ///////////////////////////////////////////////
  71. // Set the properties for the data source.
  72. //////////////////////////////////////////////
  73. CComPtr <IDBProperties> l_pIDBProperties;
  74. CHECK_CALL_HRES (m_pIDBInitialize->QueryInterface (
  75. __uuidof (IDBProperties),
  76. (void **) &l_pIDBProperties)
  77. );
  78. //////////////////////////////////
  79. // Prepare the create session
  80. //////////////////////////////////
  81. DBPROP lprop[2];
  82. VariantInit(&lprop[0].vValue);
  83. lprop[0].dwOptions = DBPROPOPTIONS_REQUIRED;
  84. lprop[0].dwPropertyID = DBPROP_INIT_DATASOURCE;
  85. V_VT (&(lprop[0].vValue)) = VT_BSTR;
  86. //////////////////////////////////////////////////////
  87. // put the path to the DB in the property.
  88. // remark: temporaryname was used befire
  89. // but the compacted database will have the name
  90. // that was given as a parameter to that program
  91. //////////////////////////////////////////////////////
  92. V_BSTR (&(lprop[0].vValue)) = SysAllocString (TEMPORARY_FILENAME);
  93. VariantInit(&lprop[1].vValue);
  94. lprop[1].dwOptions = DBPROPOPTIONS_REQUIRED;
  95. lprop[1].dwPropertyID = DBPROP_INIT_MODE;
  96. V_VT (&(lprop[1].vValue)) = VT_I4;
  97. V_I4 (&(lprop[1].vValue)) = DB_MODE_READ;
  98. DBPROPSET lPropSet;
  99. lPropSet.rgProperties = lprop;
  100. lPropSet.cProperties = 2;
  101. lPropSet.guidPropertySet = DBPROPSET_DBINIT;
  102. ///////////////////////
  103. // Set the properties
  104. ///////////////////////
  105. CHECK_CALL_HRES (l_pIDBProperties->SetProperties (
  106. 1,
  107. &lPropSet
  108. ));
  109. CHECK_CALL_HRES (m_pIDBInitialize->Initialize ());
  110. IJetCompact* l_pIJetCompact;
  111. CHECK_CALL_HRES ((m_pIDBInitialize->QueryInterface (
  112. __uuidof (IJetCompact),
  113. (void **) &l_pIJetCompact))
  114. );
  115. /////////////////////////////////////////////////////////////
  116. // Prepare the properties for the data dest. (destination)
  117. /////////////////////////////////////////////////////////////
  118. DBPROP lpropDest[1];
  119. VariantInit (&lprop[0].vValue);
  120. lpropDest[0].dwOptions = DBPROPOPTIONS_REQUIRED;
  121. lpropDest[0].dwPropertyID = DBPROP_INIT_DATASOURCE;
  122. V_VT (&(lpropDest[0].vValue)) = VT_BSTR;
  123. ///////////////////////////////////////////////////
  124. // Delete the database file if it already existed.
  125. // that should be safe because the temporary DB
  126. // was succesfully created
  127. ///////////////////////////////////////////////////
  128. DeleteFileW(mpDBPath.c_str());
  129. //////////////////////////////////////////////
  130. // put the path to the DB in the property.
  131. //////////////////////////////////////////////
  132. V_BSTR (&(lpropDest[0].vValue)) = SysAllocString (mpDBPath.c_str());
  133. DBPROPSET lPropSetDest[1];
  134. lPropSetDest[0].rgProperties = lpropDest;
  135. lPropSetDest[0].cProperties = 1;
  136. lPropSetDest[0].guidPropertySet = DBPROPSET_DBINIT;
  137. CHECK_CALL_HRES (l_pIJetCompact->Compact(1, lPropSetDest));
  138. /////////////
  139. // Clean
  140. /////////////
  141. CHECK_CALL_HRES (m_pIDBInitialize->Uninitialize());
  142. ////////////////////////////////////////////
  143. //result not checked: that's not important
  144. ////////////////////////////////////////////
  145. DeleteFileW(TEMPORARY_FILENAME);
  146. SysFreeString( V_BSTR (&(lpropDest[0].vValue)) );
  147. SysFreeString( V_BSTR (&(lprop[0].vValue)) );
  148. // The CHECK_CALL_HRES set the value of hres
  149. return hres;
  150. }
  151. // ///////////////////////////////////////////////////////////////////////////
  152. //
  153. // InitializeDB
  154. //
  155. // Comes from the file \ias\devtest\services\dictionary\dnary\dnarydump.cpp
  156. //
  157. // ///////////////////////////////////////////////////////////////////////////
  158. HRESULT CDatabase::InitializeDB(WCHAR * pDatabasePath)
  159. {
  160. CLSID clsid;
  161. HRESULT hres;
  162. ////////////////////////////////////////////////////
  163. // Retrieve the classID for the jet 4.0 provider
  164. ////////////////////////////////////////////////////
  165. CHECK_CALL_HRES(
  166. CLSIDFromProgID (
  167. OLESTR ("Microsoft.Jet.OLEDB.4.0"),
  168. &clsid //Pointer to the CLSID
  169. )
  170. );
  171. ////////////////////////////////////
  172. // init: init the provider directly
  173. ////////////////////////////////////
  174. CHECK_CALL_HRES(
  175. CoCreateInstance (
  176. clsid,
  177. NULL,
  178. CLSCTX_INPROC_SERVER,
  179. __uuidof (IDBInitialize),
  180. (void **) &m_pIDBInitialize
  181. )
  182. );
  183. mpDBPath = pDatabasePath;
  184. //////////////////////////////////////////////
  185. // Set the properties for the data source.
  186. //////////////////////////////////////////////
  187. CComPtr <IDBProperties> pIDBProperties;
  188. CHECK_CALL_HRES(
  189. m_pIDBInitialize->QueryInterface(
  190. __uuidof (IDBProperties),
  191. (void **) &pIDBProperties
  192. )
  193. );
  194. ///////////////////////////////
  195. // Prepare the create session
  196. ///////////////////////////////
  197. DBPROP lprop[2];
  198. VariantInit (&lprop[0].vValue);
  199. lprop[0].dwOptions = DBPROPOPTIONS_REQUIRED;
  200. lprop[0].dwPropertyID = DBPROP_INIT_DATASOURCE;
  201. V_VT (&(lprop[0].vValue)) = VT_BSTR;
  202. //////////////////////////////////////////////
  203. // put the path to the DB in the property.
  204. // this is the temporary filename
  205. //////////////////////////////////////////////
  206. V_BSTR (&(lprop[0].vValue)) = SysAllocString (TEMPORARY_FILENAME);
  207. VariantInit(&lprop[1].vValue);
  208. lprop[1].dwOptions = DBPROPOPTIONS_REQUIRED;
  209. lprop[1].dwPropertyID = DBPROP_INIT_MODE;
  210. V_VT (&(lprop[1].vValue)) = VT_I4;
  211. V_I4 (&(lprop[1].vValue)) = DB_MODE_READWRITE;
  212. DBPROPSET lPropSet;
  213. lPropSet.rgProperties = lprop;
  214. lPropSet.cProperties = 2;
  215. lPropSet.guidPropertySet = DBPROPSET_DBINIT;
  216. // Set the properties
  217. CHECK_CALL_HRES(pIDBProperties->SetProperties (1, &lPropSet));
  218. ////////////////////
  219. // Lock properties
  220. ////////////////////
  221. DBPROP dbpropb[1];
  222. dbpropb[0].dwPropertyID = DBPROP_JETOLEDB_DATABASELOCKMODE;
  223. dbpropb[0].dwOptions = DBPROPOPTIONS_REQUIRED;
  224. dbpropb[0].colid = DB_NULLID;
  225. dbpropb[0].vValue.vt = VT_I4;
  226. dbpropb[0].vValue.lVal = DBPROPVAL_DL_OLDMODE;
  227. DBPROPSET dbpropSetb;
  228. dbpropSetb.guidPropertySet = DBPROPSET_JETOLEDB_DBINIT;
  229. dbpropSetb.cProperties = 1;
  230. dbpropSetb.rgProperties = dbpropb;
  231. // Set the properties
  232. CHECK_CALL_HRES (pIDBProperties->SetProperties(1, &dbpropSetb));
  233. CHECK_CALL_HRES (m_pIDBInitialize->Initialize ());
  234. CHECK_CALL_HRES(
  235. m_pIDBInitialize->QueryInterface(
  236. __uuidof (IDBCreateSession),
  237. (void **) &m_pIDBCreateSession
  238. )
  239. );
  240. CHECK_CALL_HRES(
  241. m_pIDBCreateSession->CreateSession (
  242. NULL, // pUnkOuter
  243. __uuidof (IOpenRowset),
  244. (IUnknown **) & m_pIOpenRowset
  245. )
  246. );
  247. CHECK_CALL_HRES(
  248. m_pIOpenRowset->QueryInterface (
  249. __uuidof (ITransactionLocal),
  250. (PVOID *) & m_pITransactionLocal
  251. )
  252. );
  253. //////////////////////////////////////////////
  254. // start a transaction
  255. // everything is "under" that transaction
  256. //////////////////////////////////////////////
  257. CHECK_CALL_HRES(
  258. m_pITransactionLocal->StartTransaction (
  259. ISOLATIONLEVEL_READUNCOMMITTED,
  260. 0,
  261. NULL,
  262. NULL
  263. )
  264. );
  265. ////////////////////////////
  266. // prepare the properties
  267. ////////////////////////////
  268. mlrgProperties[0].dwPropertyID = DBPROP_IRowsetChange;
  269. mlrgProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;
  270. mlrgProperties[0].colid = DB_NULLID;
  271. VariantInit(&mlrgProperties[0].vValue);
  272. V_VT (&(mlrgProperties[0].vValue)) = VT_BOOL;
  273. V_BOOL (&(mlrgProperties[0].vValue)) = VARIANT_TRUE;
  274. mlrgProperties[1].dwPropertyID = DBPROP_UPDATABILITY;
  275. mlrgProperties[1].dwOptions = DBPROPOPTIONS_REQUIRED;
  276. mlrgProperties[1].colid = DB_NULLID;
  277. VariantInit (&mlrgProperties[1].vValue);
  278. V_VT (&(mlrgProperties[1].vValue)) = VT_I4;
  279. V_I4 (&(mlrgProperties[1].vValue)) = DBPROPVAL_UP_CHANGE |
  280. DBPROPVAL_UP_DELETE |
  281. DBPROPVAL_UP_INSERT;
  282. mlrgPropSets->rgProperties = mlrgProperties;
  283. mlrgPropSets->cProperties = 2;
  284. mlrgPropSets->guidPropertySet = DBPROPSET_ROWSET;
  285. SysFreeString(V_BSTR (&(lprop[0].vValue)));
  286. return hres;
  287. }
  288. // ///////////////////////////////////////////////////////////////////////////
  289. //
  290. // InitializeRowset
  291. //
  292. // ///////////////////////////////////////////////////////////////////////////
  293. HRESULT CDatabase::InitializeRowset(WCHAR * pTableName, IRowset ** ppRowset)
  294. {
  295. //Create the tableID
  296. mTableID.eKind = DBKIND_NAME;
  297. mTableID.uName.pwszName = pTableName;
  298. //Open the (defined by parameters) rowset
  299. return m_pIOpenRowset->OpenRowset(
  300. NULL,
  301. &mTableID,
  302. NULL,
  303. __uuidof (IRowset),
  304. 1,
  305. mlrgPropSets,
  306. (IUnknown **) ppRowset
  307. );
  308. }