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.

515 lines
14 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Abstract:
  4. @doc
  5. @module vs_reg.hxx | Declaration of CVssRegistryKey
  6. @end
  7. Author:
  8. Adi Oltean [aoltean] 03/13/2001
  9. Revision History:
  10. Name Date Comments
  11. aoltean 03/13/2001 Created
  12. --*/
  13. #ifndef __VSGEN_REGISTRY_HXX__
  14. #define __VSGEN_REGISTRY_HXX__
  15. #if _MSC_VER > 1000
  16. #pragma once
  17. #endif
  18. ////////////////////////////////////////////////////////////////////////
  19. // Standard foo for file name aliasing. This code block must be after
  20. // all includes of VSS header files.
  21. //
  22. #ifdef VSS_FILE_ALIAS
  23. #undef VSS_FILE_ALIAS
  24. #endif
  25. #define VSS_FILE_ALIAS "SPRREGMH"
  26. //
  27. ////////////////////////////////////////////////////////////////////////
  28. /////////////////////////////////////////////////////////////////////////////
  29. // Constants
  30. const x_nVssMaxRegBuffer = MAX_PATH;
  31. const x_nVssMaxRegNumBuffer = 30; // Enough for storing numbers
  32. /////////////////////////////////////////////////////////////////////////////
  33. // Constants
  34. const WCHAR x_wszVSSKey[] = L"SYSTEM\\CurrentControlSet\\Services\\VSS";
  35. // Provider registration
  36. const WCHAR x_wszVSSKeyProviders[] = L"Providers";
  37. const WCHAR x_wszVSSKeyProviderCLSID[] = L"CLSID";
  38. const WCHAR x_wszVSSProviderValueName[] = L"";
  39. const WCHAR x_wszVSSProviderValueType[] = L"Type";
  40. const WCHAR x_wszVSSProviderValueVersion[] = L"Version";
  41. const WCHAR x_wszVSSProviderValueVersionId[] = L"VersionId";
  42. const WCHAR x_wszVSSCLSIDValueName[] = L"";
  43. // Diff area
  44. const WCHAR x_wszVssVolumesKey[] = L"SYSTEM\\CurrentControlSet\\Services\\VSS\\Volumes";
  45. const WCHAR x_wszVssAssociationsKey[] = L"SYSTEM\\CurrentControlSet\\Services\\VSS\\Volumes\\Associations";
  46. const WCHAR x_wszVssMaxDiffValName[] = L"MaxDiffSpace";
  47. const WCHAR x_wszVssAccessControlKey[] = L"SYSTEM\\CurrentControlSet\\Services\\VSS\\VssAccessControl";
  48. // COM Registry keys/values
  49. const WCHAR x_wszDefaultLaunchPermissionKeyName[] = L"Software\\Microsoft\\Ole";
  50. const WCHAR x_wszDefaultLaunchPermissionValueName[] = L"DefaultLaunchPermission";
  51. const WCHAR x_wszAppLaunchPermissionValueName[] = L"LaunchPermission";
  52. // Diag data
  53. const WCHAR x_wszVssDiagPath[] = L"SYSTEM\\CurrentControlSet\\Services\\VSS\\Diag";
  54. const WCHAR x_wszVssDiagEnabledValue[] = L"Enabled";
  55. // Setup key
  56. const WCHAR x_SetupKey[] = L"SYSTEM\\Setup";
  57. const WCHAR x_SystemSetupInProgress[] = L"SystemSetupInProgress";
  58. const WCHAR x_UpgradeInProgress[] = L"UpgradeInProgress";
  59. // Event Log source
  60. const WCHAR g_wszVssEventLogSourceKey[] = L"System\\CurrentControlSet\\Services\\EventLog\\Application\\VSS";
  61. const WCHAR g_wszVssEventTypesSupportedValName[] = L"TypesSupported";
  62. const WCHAR g_wszVssEventMessageFileValName[] = L"EventMessageFile";
  63. const WCHAR g_wszVssBinaryPath[] = L"%SystemRoot%\\System32\\VSSVC.EXE";
  64. const DWORD g_dwVssEventTypesSupported = 7;
  65. // Safeboot key
  66. const WCHAR x_SafebootKey[] = L"SYSTEM\\currentcontrolset\\control\\safeboot\\option";
  67. const WCHAR x_SafebootOptionValue[] = L"OptionValue";
  68. // Client accessible settings path
  69. const WCHAR x_wszVssCASettingsPath[] = L"SYSTEM\\CurrentControlSet\\Services\\VSS\\Settings";
  70. const WCHAR x_wszVssCAMaxShadowCopiesValueName[] = L"MaxShadowCopies";
  71. const WCHAR x_wszVssOfflineTimeoutValueName[] = L"ClusterOfflineTimeout";
  72. const WCHAR x_wszVssOnlineTimeoutValueName[] = L"ClusterOnlineTimeout";
  73. /////////////////////////////////////////////////////////////////////////////
  74. // Classes
  75. // Implements a low-level API for registry manipulation
  76. class CVssRegistryKey
  77. {
  78. // Constructors/destructors
  79. private:
  80. CVssRegistryKey(const CVssRegistryKey&);
  81. public:
  82. CVssRegistryKey(
  83. IN REGSAM samDesired = KEY_ALL_ACCESS,
  84. IN DWORD dwKeyCreateOptions = REG_OPTION_NON_VOLATILE
  85. );
  86. ~CVssRegistryKey();
  87. // Operations
  88. public:
  89. // Creates the registry key.
  90. // Throws an error if the key already exists
  91. void Create(
  92. IN HKEY hAncestorKey,
  93. IN LPCWSTR pwszPathFormat,
  94. IN ...
  95. ) throw(HRESULT);
  96. // Opens a registry key. Returns "false" if the key does not exist
  97. bool Open(
  98. IN HKEY hAncestorKey,
  99. IN LPCWSTR pwszPathFormat,
  100. IN ...
  101. ) throw(HRESULT);
  102. // Recursively deletes a subkey.
  103. // Throws an error if the subkey does not exist
  104. void DeleteSubkey(
  105. IN LPCWSTR pwszPathFormat,
  106. IN ...
  107. ) throw(HRESULT);
  108. // Deletes a value.
  109. // Throws an error if the value does not exist
  110. void DeleteValue(
  111. IN LPCWSTR pwszValueName
  112. ) throw(HRESULT);
  113. void SetValue(
  114. IN LPCWSTR pwszValueName,
  115. IN DWORD dwValue
  116. ) throw(HRESULT);
  117. // Adds a LONGLONG value to the registry key
  118. void SetValue(
  119. IN LPCWSTR pwszValueName,
  120. IN LONGLONG llValue
  121. ) throw(HRESULT);
  122. // Adds a REG_SZ/REG_EXPAND_SZ value to the registry key
  123. void SetValue(
  124. IN LPCWSTR pwszValueName,
  125. IN LPCWSTR pwszValue,
  126. IN REGSAM eSzType = REG_SZ
  127. ) throw(HRESULT);
  128. // Adds a multi-string value to the registry key
  129. void SetMultiszValue(
  130. IN LPCWSTR pwszValueName,
  131. IN LPCWSTR pwszValue
  132. ) throw(HRESULT);
  133. // Adds a binary value to the registry key
  134. void SetBinaryValue(
  135. IN LPCWSTR pwszValueName,
  136. IN BYTE * pbData,
  137. IN DWORD dwSize
  138. ) throw(HRESULT);
  139. // Reads a LONGLONG value from the registry key
  140. bool GetValue(
  141. IN LPCWSTR pwszValueName,
  142. OUT LONGLONG & llValue,
  143. IN bool bThrowIfNotFound = true
  144. ) throw(HRESULT);
  145. // Reads a VSS_PWSZ value from the registry key
  146. bool GetValue(
  147. IN LPCWSTR pwszValueName,
  148. OUT VSS_PWSZ & pwszValue,
  149. IN bool bThrowIfNotFound = true
  150. ) throw(HRESULT);
  151. // Reads a DWORD value from the registry key
  152. bool GetValue(
  153. IN LPCWSTR pwszValueName,
  154. OUT DWORD & dwValue,
  155. IN bool bThrowIfNotFound = true
  156. ) throw(HRESULT);
  157. // Reads a binary value from the registry key
  158. bool GetBinaryValue(
  159. IN LPCWSTR pwszValueName,
  160. OUT BYTE* & pbData,
  161. OUT DWORD & lSize,
  162. IN bool bThrowIfNotFound = true
  163. ) throw(HRESULT);
  164. // Closing the registry key
  165. void Close();
  166. // Get the handle for the currently opened key
  167. HKEY GetHandle() const { return m_hRegKey; };
  168. // Implementation
  169. private:
  170. REGSAM m_samDesired;
  171. DWORD m_dwKeyCreateOptions;
  172. HKEY m_hRegKey;
  173. CVssAutoPWSZ m_awszKeyPath; // For debugging only
  174. };
  175. // Implements a low-level API for registry key enumeration
  176. // We assume that the keys don't change during enumeration
  177. class CVssRegistryKeyIterator
  178. {
  179. // Constructors/destructors
  180. private:
  181. CVssRegistryKeyIterator(const CVssRegistryKeyIterator&);
  182. public:
  183. CVssRegistryKeyIterator();
  184. // Operations
  185. public:
  186. // Attach the iterator to a key
  187. void Attach(
  188. IN CVssRegistryKey & key
  189. ) throw(HRESULT);
  190. // Detach the iterator from a key.
  191. void Detach();
  192. // Tells if the current key is invalid (end of enumeration?)
  193. bool IsEOF();
  194. // Return the number of subkeys at the moment of attaching
  195. DWORD GetSubkeysCount();
  196. // Set the next key as being the current one in the enumeration
  197. void MoveNext();
  198. // Returns the name of the current key, if any
  199. VSS_PWSZ GetCurrentKeyName() throw(HRESULT);
  200. // Implementation
  201. private:
  202. HKEY m_hParentKey;
  203. DWORD m_dwKeyCount;
  204. DWORD m_dwCurrentKeyIndex;
  205. DWORD m_dwMaxSubKeyLen;
  206. CVssAutoPWSZ m_awszSubKeyName;
  207. bool m_bAttached;
  208. };
  209. // Implements a low-level API for registry value enumeration
  210. // We assume that the values don't change during enumeration
  211. class CVssRegistryValueIterator
  212. {
  213. // Constructors/destructors
  214. private:
  215. CVssRegistryValueIterator(const CVssRegistryValueIterator&);
  216. public:
  217. CVssRegistryValueIterator();
  218. // Operations
  219. public:
  220. // Attach the iterator to a key
  221. void Attach(
  222. IN CVssRegistryKey & key
  223. ) throw(HRESULT);
  224. // Detach the iterator from a key.
  225. void Detach();
  226. // Tells if the current key is invalid (end of enumeration?)
  227. bool IsEOF();
  228. // Return the number of subkeys at the moment of attaching
  229. DWORD GetValuesCount();
  230. // Set the next key as being the current one in the enumeration
  231. void MoveNext();
  232. // Returns the name of the current value
  233. VSS_PWSZ GetCurrentValueName() throw(HRESULT);
  234. // Returns the type of the current value
  235. DWORD GetCurrentValueType() throw(HRESULT);
  236. // Read the current value assuming it has REG_SZ type
  237. // WARNING: The caller is responsible for deallocating the value!
  238. void GetCurrentValueContent(
  239. OUT VSS_PWSZ & pwszValue
  240. ) throw(HRESULT);
  241. // Read the current value assuming it has REG_DWORD type
  242. void GetCurrentValueContent(
  243. OUT DWORD & dwValue
  244. ) throw(HRESULT);
  245. // Read the current value assuming it has REG_BINARY type
  246. void GetCurrentValueContent(
  247. OUT PBYTE & pbValue, // Must be deleted with "delete[]"
  248. OUT DWORD & cbSize
  249. ) throw(HRESULT);
  250. // Implementation
  251. private:
  252. void ReadCurrentValueDetails() throw(HRESULT);
  253. HKEY m_hKey;
  254. DWORD m_dwValuesCount;
  255. DWORD m_dwCurrentValueIndex;
  256. DWORD m_dwCurrentValueType;
  257. CVssAutoPWSZ m_awszValueName;
  258. DWORD m_cchMaxValueNameLen;
  259. DWORD m_cbValueDataSize;
  260. bool m_bSeekDone;
  261. bool m_bAttached;
  262. };
  263. // +-----------------+-----------------+
  264. // | Structure size | 0 (reserved) |
  265. // +-----------------+-----------------+
  266. // | Timestamp |
  267. // +-----------------+-----------------+
  268. // | Process ID | Thread ID |
  269. // +-----------------+-----------------+
  270. // | Event ID | Enter/Leave flag|
  271. // +-----------------+-----------------+
  272. // | Current State | Last Error (HR) |
  273. // +-----------------+-----------------+
  274. // | Snapshot Set ID |
  275. // | |
  276. // +-----------------+-----------------+
  277. // | LPVOID reserved |
  278. // +-----------------+-----------------+
  279. struct CVssDiagData
  280. {
  281. DWORD m_dwSize; // For future compatibility
  282. DWORD m_dwReserved; // Reserved - zero
  283. LONGLONG m_llTimestamp;
  284. DWORD m_dwProcessID;
  285. DWORD m_dwThreadID;
  286. DWORD m_dwEventID;
  287. DWORD m_dwEventContext;
  288. DWORD m_dwCurrentState;
  289. DWORD m_hrLastErrorCode;
  290. VSS_ID m_guidSnapshotSetID;
  291. LPVOID m_pReserved1; // Reserved - NULL
  292. LPVOID m_pReserved2; // Reserved - NULL
  293. };
  294. struct CVssQueuedEventData
  295. {
  296. CVssDiagData m_diag; // Diag data for that event
  297. LPCWSTR m_pwszEventName; // This is a static string
  298. };
  299. //
  300. // Defines a writer operation
  301. //
  302. typedef enum VSS_OPERATION
  303. {
  304. // Writers
  305. VSS_IN_IDENTIFY = 1000,
  306. VSS_IN_PREPAREBACKUP,
  307. VSS_IN_PREPARESNAPSHOT,
  308. VSS_IN_FREEZE,
  309. VSS_IN_THAW,
  310. VSS_IN_POSTSNAPSHOT,
  311. VSS_IN_BACKUPCOMPLETE,
  312. VSS_IN_PRERESTORE,
  313. VSS_IN_POSTRESTORE,
  314. VSS_IN_GETSTATE, // Added for diag
  315. VSS_IN_ABORT, // Added for diag
  316. VSS_IN_BACKUPSHUTDOWN,
  317. VSS_IN_BKGND_FREEZE_THREAD,
  318. // Lovelace
  319. VSS_IN_OPEN_VOLUME_HANDLE,
  320. VSS_IN_IOCTL_FLUSH_AND_HOLD,
  321. VSS_IN_IOCTL_RELEASE,
  322. // Replacement for S_OK (S_OK conflicts with VSS_WS_UNKNOWN)
  323. // (Used in Diag code only) - to be used only in VSS_HRESULT_CASE_STMT
  324. VSS_S_OK = 0xffffffff
  325. };
  326. const x_nMaxQueuedDiagData = 10;
  327. // Implements a lightweight diagnose tool for recording events
  328. class CVssDiag
  329. {
  330. // Constructors/destructors
  331. private:
  332. CVssDiag(const CVssDiag&);
  333. CVssDiag& operator = (const CVssDiag&);
  334. public:
  335. CVssDiag():
  336. m_bInitialized(false),
  337. m_key(KEY_ALL_ACCESS, REG_OPTION_VOLATILE),
  338. m_dwQueuedElements(0)
  339. {};
  340. ~CVssDiag()
  341. {
  342. if (m_bInitialized)
  343. FlushQueue();
  344. }
  345. // Operations
  346. public:
  347. enum {
  348. VSS_DIAG_LEAVE_OPERATION = 0x00000000,
  349. VSS_DIAG_ENTER_OPERATION = 0x00000001,
  350. VSS_DIAG_IGNORE_LEAVE = 0x00000002,
  351. VSS_DIAG_IS_STATE = 0x00000004,
  352. VSS_DIAG_IS_HRESULT = 0x00000008,
  353. };
  354. // Initialize the diagnose tool
  355. // Does not throw errora
  356. void Initialize(
  357. IN LPCWSTR pwszStaticContext
  358. );
  359. // Records an writer event.
  360. // Does not throw errors
  361. void RecordWriterEvent(
  362. IN VSS_OPERATION eOperation,
  363. IN DWORD dwEventContext,
  364. IN DWORD dwCurrentState,
  365. IN HRESULT hrLastError,
  366. IN GUID guidSnapshotSetID = GUID_NULL
  367. );
  368. // Records an generic event.
  369. // Does not throw errors
  370. void RecordGenericEvent(
  371. IN DWORD dwEventID,
  372. IN DWORD dwEventContext,
  373. IN DWORD dwCurrentState,
  374. IN HRESULT hrLastError,
  375. IN GUID guidSnapshotSetID = GUID_NULL
  376. );
  377. // Implementation
  378. private:
  379. // convert an event into the corresponding writer description
  380. LPCWSTR GetStringFromOperation(
  381. IN bool bInOperation,
  382. IN DWORD dwOperation
  383. );
  384. bool IsQueuedMode(
  385. IN DWORD dwEventID,
  386. IN DWORD dwEventContext
  387. );
  388. void FlushQueue();
  389. CVssRegistryKey m_key; // Registry key to hold data for each event
  390. bool m_bInitialized; // If the registry key is initialized
  391. CVssQueuedEventData m_QueuedDiagData[x_nMaxQueuedDiagData];
  392. DWORD m_dwQueuedElements;
  393. };
  394. // General info about the current machine
  395. class CVssMachineInformation
  396. {
  397. public:
  398. static bool IsDuringSetup();
  399. static bool IsDuringSafeMode();
  400. };
  401. #endif // __VSGEN_REGISTRY_HXX__