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.

481 lines
11 KiB

  1. // database.cpp, implementation of CSecurityDatabase class
  2. // Copyright (c)1997-1999 Microsoft Corporation
  3. //
  4. //////////////////////////////////////////////////////////////////////
  5. #include "precomp.h"
  6. #include "database.h"
  7. #include "persistmgr.h"
  8. //#include <io.h>
  9. #include <time.h>
  10. #include "requestobject.h"
  11. const DWORD dwSecDBVersion = 1;
  12. /*
  13. Routine Description:
  14. Name:
  15. CSecurityDatabase::CSecurityDatabase
  16. Functionality:
  17. This is the constructor. Pass along the parameters to the base class
  18. Virtual:
  19. No (you know that, constructor won't be virtual!)
  20. Arguments:
  21. pKeyChain - Pointer to the ISceKeyChain COM interface which is prepared
  22. by the caller who constructs this instance.
  23. pNamespace - Pointer to WMI namespace of our provider (COM interface).
  24. Passed along by the caller. Must not be NULL.
  25. pCtx - Pointer to WMI context object (COM interface). Passed along
  26. by the caller. It's up to WMI whether this interface pointer is NULL or not.
  27. Return Value:
  28. None as any constructor
  29. Notes:
  30. if you create any local members, think about initialize them here
  31. */
  32. CSecurityDatabase::CSecurityDatabase (
  33. IN ISceKeyChain *pKeyChain,
  34. IN IWbemServices *pNamespace,
  35. IN IWbemContext *pCtx
  36. )
  37. :
  38. CGenericClass(pKeyChain, pNamespace, pCtx)
  39. {
  40. }
  41. /*
  42. Routine Description:
  43. Name:
  44. CSecurityDatabase::~CSecurityDatabase
  45. Functionality:
  46. Destructor. Necessary as good C++ discipline since we have virtual functions.
  47. Virtual:
  48. Yes.
  49. Arguments:
  50. none as any destructor
  51. Return Value:
  52. None as any destructor
  53. Notes:
  54. if you create any local members, think about whether
  55. there is any need for a non-trivial destructor
  56. */
  57. CSecurityDatabase::~CSecurityDatabase ()
  58. {
  59. }
  60. //Sce_Database
  61. /*
  62. Routine Description:
  63. Name:
  64. CSecurityDatabase::CreateObject
  65. Functionality:
  66. Create WMI objects (Sce_Database). Depending on parameter atAction,
  67. this creation may mean:
  68. (a) Get a single instance (atAction == ACTIONTYPE_GET)
  69. (b) Get several instances satisfying some criteria (atAction == ACTIONTYPE_QUERY)
  70. Virtual:
  71. Yes.
  72. Arguments:
  73. pHandler - COM interface pointer for notifying WMI for creation result.
  74. atAction - Get single instance ACTIONTYPE_GET
  75. Get several instances ACTIONTYPE_QUERY
  76. Return Value:
  77. Success: it must return success code (use SUCCEEDED to test). It is
  78. not guaranteed to return WBEM_NO_ERROR. The returned objects are indicated to WMI,
  79. not directly passed back via parameters.
  80. Failure: Various errors may occurs. Except WBEM_E_NOT_FOUND, any such error should indicate
  81. the failure of getting the wanted instance. If WBEM_E_NOT_FOUND is returned in querying
  82. situations, this may not be an error depending on caller's intention.
  83. Notes:
  84. for Sce_Database, we don't support delete!
  85. */
  86. HRESULT
  87. CSecurityDatabase::CreateObject (
  88. IN IWbemObjectSink *pHandler,
  89. IN ACTIONTYPE atAction
  90. )
  91. {
  92. //
  93. // we know how to:
  94. // Get single instance ACTIONTYPE_GET
  95. // Get several instances ACTIONTYPE_QUERY
  96. //
  97. if ( ACTIONTYPE_GET != atAction &&
  98. ACTIONTYPE_QUERY != atAction ) {
  99. return WBEM_E_NOT_SUPPORTED;
  100. }
  101. //
  102. // Sce_Database class has only one key property (path)
  103. //
  104. DWORD dwCount = 0;
  105. HRESULT hr = m_srpKeyChain->GetKeyPropertyCount(&dwCount);
  106. if (SUCCEEDED(hr) && dwCount == 1)
  107. {
  108. //
  109. // We must have the pPath key property.
  110. // m_srpKeyChain->GetKeyPropertyValue WBEM_S_FALSE if the key is not recognized
  111. // So, we need to test against WBEM_S_FALSE if the property is mandatory
  112. //
  113. CComVariant varPath;
  114. hr = m_srpKeyChain->GetKeyPropertyValue(pPath, &varPath);
  115. if (FAILED(hr) || hr == WBEM_S_FALSE)
  116. {
  117. return WBEM_E_NOT_FOUND;
  118. }
  119. if (SUCCEEDED(hr) && hr != WBEM_S_FALSE && varPath.vt == VT_BSTR)
  120. {
  121. //
  122. // Create the database instance
  123. //
  124. //
  125. // expand those env variable tokens inside a path
  126. //
  127. CComBSTR bstrExpandedPath;
  128. //
  129. // bDb will be returned true if the the path is pointing to a database type file
  130. //
  131. BOOL bDb=FALSE;
  132. hr = CheckAndExpandPath(varPath.bstrVal, &bstrExpandedPath, &bDb);
  133. if ( !bDb )
  134. {
  135. hr = WBEM_E_INVALID_OBJECT_PATH;
  136. }
  137. else
  138. {
  139. //
  140. // make sure the store (just a file) really exists
  141. //
  142. DWORD dwAttrib = GetFileAttributes(bstrExpandedPath);
  143. if ( dwAttrib != -1 )
  144. {
  145. hr = ConstructInstance(pHandler, bstrExpandedPath, varPath.bstrVal);
  146. }
  147. else
  148. {
  149. hr = WBEM_E_NOT_FOUND;
  150. }
  151. }
  152. }
  153. }
  154. else if (SUCCEEDED(hr))
  155. {
  156. //
  157. // the object says that it has more than one key properties,
  158. // we know that is incorrect
  159. //
  160. hr = WBEM_E_INVALID_OBJECT;
  161. }
  162. return hr;
  163. }
  164. /*
  165. Routine Description:
  166. Name:
  167. CSecurityDatabase::ConstructInstance
  168. Functionality:
  169. This is private function to create an instance of Sce_Database.
  170. Virtual:
  171. No.
  172. Arguments:
  173. pHandler - COM interface pointer for notifying WMI of any events.
  174. wszDatabaseName - file path to the database.
  175. wszLogDatabasePath - Log path.
  176. Return Value:
  177. Success: it must return success code (use SUCCEEDED to test). It is
  178. not guaranteed to return WBEM_NO_ERROR.
  179. Failure: Various errors may occurs. Any such error should indicate the creating the instance.
  180. Notes:
  181. */
  182. HRESULT
  183. CSecurityDatabase::ConstructInstance (
  184. IN IWbemObjectSink *pHandler,
  185. IN LPCWSTR wszDatabaseName,
  186. IN LPCWSTR wszLogDatabasePath
  187. )
  188. {
  189. // Get information from the database
  190. // ==================
  191. HRESULT hr = WBEM_S_NO_ERROR;
  192. SCESTATUS rc;
  193. //
  194. // hProfile is where SCE reads info to
  195. //
  196. PVOID hProfile=NULL;
  197. rc = SceOpenProfile(wszDatabaseName, SCE_JET_FORMAT, &hProfile);
  198. if ( rc != SCESTATUS_SUCCESS )
  199. {
  200. //
  201. // SCE returned errors needs to be translated to HRESULT.
  202. //
  203. return ProvDosErrorToWbemError(ProvSceStatusToDosError(rc));
  204. }
  205. PWSTR wszDescription = NULL;
  206. SYSTEMTIME stConfig;
  207. SYSTEMTIME stAnalyze;
  208. CComBSTR bstrConfig;
  209. CComBSTR bstrAnalyze;
  210. //
  211. // need to free wszDescription
  212. //
  213. rc = SceGetScpProfileDescription(hProfile, &wszDescription);
  214. if ( SCESTATUS_SUCCESS == rc )
  215. {
  216. rc = SceGetDbTime(hProfile, &stConfig, &stAnalyze);
  217. }
  218. //
  219. // SCE returned errors needs to be translated to HRESULT.
  220. // In case this is not an error, hr will be assigned to WBEM_NO_ERROR
  221. //
  222. hr = ProvDosErrorToWbemError(ProvSceStatusToDosError(rc));
  223. SceCloseProfile( &hProfile );
  224. //
  225. // now log it
  226. //
  227. CComBSTR bstrLogOut;
  228. //
  229. // the use of the macro SCE_PROV_IfErrorGotoCleanup cause
  230. // a "goto CleanUp;" with hr set to the return value from
  231. // the function (macro parameter)
  232. //
  233. if ( SUCCEEDED(hr) )
  234. {
  235. SCE_PROV_IfErrorGotoCleanup(MakeSingleBackSlashPath((PWSTR)wszLogDatabasePath, L'\\', &bstrLogOut));
  236. //
  237. // convert the time stamp
  238. //
  239. SCE_PROV_IfErrorGotoCleanup(GetDMTFTime(stConfig, &bstrConfig));
  240. SCE_PROV_IfErrorGotoCleanup(GetDMTFTime(stAnalyze, &bstrAnalyze));
  241. //
  242. // create a blank object that can be filled with properties
  243. //
  244. CComPtr<IWbemClassObject> srpObj;
  245. SCE_PROV_IfErrorGotoCleanup(SpawnAnInstance(&srpObj));
  246. //
  247. // create a property mgr for this new object to put properties
  248. //
  249. CScePropertyMgr ScePropMgr;
  250. ScePropMgr.Attach(srpObj);
  251. //
  252. // put properties: path, description, analyze, and configuration
  253. //
  254. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pPath, bstrLogOut));
  255. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pDescription, wszDescription));
  256. if (bstrAnalyze)
  257. {
  258. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pLastAnalysis, bstrAnalyze));
  259. }
  260. if (bstrConfig)
  261. {
  262. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pLastConfiguration, bstrConfig));
  263. }
  264. //
  265. // put version
  266. //
  267. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pVersion, dwSecDBVersion));
  268. //
  269. // inform WMI of the new instance it requests
  270. //
  271. SCE_PROV_IfErrorGotoCleanup(pHandler->Indicate(1, &srpObj));
  272. }
  273. CleanUp:
  274. delete [] wszDescription;
  275. return hr;
  276. }
  277. /*
  278. Routine Description:
  279. Name:
  280. GetDMTFTime
  281. Functionality:
  282. Helper to format a string version time stamp.
  283. Virtual:
  284. No.
  285. Arguments:
  286. t_Systime - the system time to format.
  287. bstrOut - out parameter to return the string version of the time.
  288. Return Value:
  289. Success: WBEM_NO_ERROR.
  290. Failure: Various errors may occurs. Any such error should indicate failure to format.
  291. Notes:
  292. */
  293. HRESULT
  294. GetDMTFTime (
  295. IN SYSTEMTIME t_Systime,
  296. IN BSTR *bstrOut
  297. )
  298. {
  299. if ( !bstrOut )
  300. {
  301. return WBEM_E_INVALID_PARAMETER;
  302. }
  303. *bstrOut = SysAllocStringLen(NULL, DMTFLEN + 1);
  304. if ( ! (*bstrOut) )
  305. {
  306. return WBEM_E_OUT_OF_MEMORY;
  307. }
  308. HRESULT hr = WBEM_NO_ERROR;
  309. FILETIME t_ft;
  310. LONG micros=0;
  311. if ( SystemTimeToFileTime(&t_Systime, &t_ft) )
  312. {
  313. ULONGLONG uTime=0;
  314. uTime = t_ft.dwHighDateTime;
  315. uTime = uTime << 32;
  316. uTime |= t_ft.dwLowDateTime;
  317. LONGLONG tmpMicros = uTime % 10000000;
  318. micros = (LONG)(tmpMicros / 10);
  319. }
  320. swprintf((*bstrOut),
  321. L"%04.4d%02.2d%02.2d%02.2d%02.2d%02.2d.%06.6d%c%03.3ld",
  322. t_Systime.wYear,
  323. t_Systime.wMonth,
  324. t_Systime.wDay,
  325. t_Systime.wHour,
  326. t_Systime.wMinute,
  327. t_Systime.wSecond,
  328. micros,
  329. L'-',
  330. 0
  331. );
  332. return hr;
  333. }