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.

533 lines
12 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. disk.h
  5. Abstract:
  6. Interface for routines that query and manipulate the
  7. disk configuration of the current system.
  8. Author:
  9. John Vert (jvert) 10/10/1996
  10. Revision History:
  11. --*/
  12. #ifndef _CLUSRTL_DISK_H_
  13. #define _CLUSRTL_DISK_H_
  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #ifdef __cplusplus
  21. }
  22. #endif
  23. #ifdef __cplusplus
  24. #ifndef __AFX_H__
  25. #undef ASSERT // make afx.h happy
  26. #endif
  27. #include <afxwin.h> // MFC core and standard components
  28. #include <afxext.h> // MFC extensions
  29. #include <afxcmn.h> // MFC support for Windows 95 Common Controls
  30. #include "afxtempl.h"
  31. #include "winioctl.h"
  32. #include "ntddscsi.h"
  33. #include "ntdskreg.h"
  34. #include "ntddft.h"
  35. #include "ntddstor.h"
  36. //
  37. // classes representing info stored in Machine\System\Disk\Information
  38. // registry key
  39. //
  40. class CFtInfoPartition {
  41. public:
  42. // initialize from registry data
  43. CFtInfoPartition(class CFtInfoDisk *Disk, DISK_PARTITION UNALIGNED *Description);
  44. // initialize from data on disk
  45. CFtInfoPartition(class CFtInfoDisk *Disk, class CPhysicalPartition *Partition);
  46. CFtInfoPartition(class CFtInfoDisk *Disk, PARTITION_INFORMATION *PartitionInfo);
  47. ~CFtInfoPartition();
  48. VOID GetData(PDISK_PARTITION pDest);
  49. DWORD GetOffset();
  50. VOID SetOffset(DWORD NewOffset) {m_RelativeOffset = NewOffset;};
  51. VOID MakeSticky(UCHAR DriveLetter);
  52. BOOL IsFtPartition() { return(m_PartitionInfo->FtType != NotAnFtMember);};
  53. DISK_PARTITION UNALIGNED *m_PartitionInfo;
  54. class CFtInfoDisk *m_ParentDisk;
  55. private:
  56. DWORD m_RelativeOffset; // relative offset from parent DISK_DESCRIPTION
  57. BOOL m_Modified;
  58. };
  59. class CFtInfoDisk {
  60. public:
  61. // initialize from registry data
  62. CFtInfoDisk(DISK_DESCRIPTION UNALIGNED *Description);
  63. // initialize from data on disk
  64. CFtInfoDisk(class CPhysicalDisk *Disk);
  65. CFtInfoDisk(DRIVE_LAYOUT_INFORMATION *DriveLayoutData);
  66. // ?
  67. CFtInfoDisk(CFtInfoDisk *DiskInfo);
  68. ~CFtInfoDisk();
  69. //
  70. // Overloaded operators
  71. //
  72. BOOL operator==(const CFtInfoDisk& Disk1);
  73. CFtInfoPartition *GetPartition(LARGE_INTEGER StartingOffset,
  74. LARGE_INTEGER Length);
  75. CFtInfoPartition *GetPartitionByOffset(DWORD Offset);
  76. CFtInfoPartition *GetPartitionByIndex(DWORD Index);
  77. DWORD FtPartitionCount();
  78. DWORD GetSize();
  79. VOID GetData(PBYTE pDest);
  80. DWORD GetOffset() {return m_Offset;};
  81. VOID SetOffset(DWORD NewOffset) {m_Offset = NewOffset;};
  82. DWORD m_PartitionCount;
  83. DWORD m_Signature;
  84. private:
  85. DWORD m_Offset;
  86. CTypedPtrList<CPtrList, CFtInfoPartition*> m_PartitionInfo;
  87. };
  88. //
  89. // class representing FTDISK registry information. Currently not used
  90. //
  91. class CFtInfoFtSet {
  92. public:
  93. CFtInfoFtSet() { m_FtDescription = NULL; }
  94. ~CFtInfoFtSet();
  95. //
  96. // Initialization
  97. //
  98. BOOL Initialize(USHORT Type, FT_STATE FtVolumeState);
  99. BOOL Initialize(class CFtInfo *FtInfo, PFT_DESCRIPTION Description);
  100. //
  101. // Overloaded operators
  102. //
  103. BOOL operator==(const CFtInfoFtSet& FtSet1);
  104. DWORD GetSize() const;
  105. VOID GetData(PBYTE pDest);
  106. DWORD GetMemberCount() const { return((DWORD)m_Members.GetSize()); };
  107. BOOL IsAlone();
  108. DWORD AddMember(CFtInfoPartition *Partition, PFT_MEMBER_DESCRIPTION Description, USHORT FtGroup);
  109. CFtInfoPartition *GetMemberBySignature (DWORD Signature) const;
  110. CFtInfoPartition *GetMemberByIndex (DWORD Index) const;
  111. PFT_MEMBER_DESCRIPTION GetMemberDescription(DWORD Index) {
  112. return(&m_FtDescription->FtMemberDescription[Index]);
  113. };
  114. USHORT GetType() const {return(m_FtDescription->Type);};
  115. FT_STATE GetState() const {return(m_FtDescription->FtVolumeState);};
  116. private:
  117. BOOL m_Modified;
  118. PFT_DESCRIPTION m_FtDescription;
  119. CTypedPtrArray<CPtrArray, CFtInfoPartition*> m_Members;
  120. };
  121. //
  122. // main registry info class. holds lists of disk and ftset registry info along
  123. // with methods for extracting info from lists
  124. //
  125. class CFtInfo {
  126. public:
  127. CFtInfo();
  128. CFtInfo(HKEY hKey, LPWSTR lpszValueName);
  129. CFtInfo(PDISK_CONFIG_HEADER Header);
  130. CFtInfo(CFtInfoFtSet *FtSet);
  131. ~CFtInfo();
  132. //
  133. // commit changes to FtInfo database to the registry
  134. //
  135. DWORD CommitRegistryData();
  136. DWORD GetSize();
  137. VOID GetData(PDISK_CONFIG_HEADER pDest);
  138. CFtInfoPartition *FindPartition(DWORD Signature,
  139. LARGE_INTEGER StartingOffset,
  140. LARGE_INTEGER Length);
  141. CFtInfoPartition *FindPartition(UCHAR DriveLetter);
  142. CFtInfoDisk *FindDiskInfo(DWORD Signature);
  143. CFtInfoDisk *EnumDiskInfo(DWORD Index);
  144. VOID AddDiskInfo(CFtInfoDisk *NewDisk) { m_DiskInfo.AddTail( NewDisk ); }
  145. VOID SetDiskInfo(CFtInfoDisk *NewDisk);
  146. BOOL DeleteDiskInfo(DWORD Signature);
  147. CFtInfoFtSet *EnumFtSetInfo(DWORD Index);
  148. CFtInfoFtSet *FindFtSetInfo(DWORD Signature);
  149. BOOL DeleteFtSetInfo(CFtInfoFtSet *FtSet);
  150. VOID AddFtSetInfo(CFtInfoFtSet *FtSet, CFtInfoFtSet *OldFtSet = NULL);
  151. private:
  152. CTypedPtrList<CPtrList, CFtInfoDisk*> m_DiskInfo;
  153. CTypedPtrList<CPtrList, CFtInfoFtSet*> m_FtSetInfo;
  154. VOID Initialize(HKEY hKey, LPWSTR lpszValueName);
  155. VOID Initialize(PDISK_CONFIG_HEADER Header, DWORD Length);
  156. VOID Initialize();
  157. public:
  158. LPBYTE m_buffer;
  159. DWORD m_bufferLength;
  160. };
  161. //
  162. // disk and related partition classes built from actual probing of disks via
  163. // IOCTLs and other disk APIs. This info is built "bottom up" in that the disk
  164. // config is discovered via the SetupDi APIs
  165. //
  166. class CPhysicalDisk {
  167. public:
  168. CPhysicalDisk() { m_FtInfo = NULL; }
  169. DWORD Initialize(CFtInfo *FtInfo, LPWSTR DeviceName);
  170. BOOL IsSticky();
  171. DWORD MakeSticky(CFtInfo *FtInfo);
  172. BOOL IsNTFS();
  173. DWORD FtPartitionCount() {
  174. if (m_FtInfo == NULL) {
  175. return(0);
  176. } else {
  177. return(m_FtInfo->FtPartitionCount());
  178. }
  179. };
  180. DWORD m_PartitionCount;
  181. DWORD m_Signature;
  182. DWORD m_DiskNumber;
  183. BOOL m_IsSCSI;
  184. BOOL m_IsRemovable;
  185. CTypedPtrList<CPtrList, class CPhysicalPartition*> m_PartitionList;
  186. CTypedPtrList<CPtrList, class CLogicalDrive*> m_LogicalDriveList;
  187. BOOL ShareBus(CPhysicalDisk *OtherDisk);
  188. SCSI_ADDRESS m_ScsiAddress;
  189. CString m_Identifier;
  190. CFtInfoDisk *m_FtInfo;
  191. private:
  192. HANDLE GetPhysicalDriveHandle(DWORD Access);
  193. HANDLE GetPhysicalDriveHandle(DWORD Access, LPWSTR DeviceName);
  194. };
  195. class CPhysicalPartition {
  196. public:
  197. CPhysicalPartition(CPhysicalDisk *Disk, PPARTITION_INFORMATION Info);
  198. CPhysicalDisk *m_PhysicalDisk;
  199. PARTITION_INFORMATION m_Info;
  200. CFtInfoPartition *m_FtPartitionInfo;
  201. };
  202. //
  203. // class representing a drive as represented by a drive letter. built in a
  204. // "top down" fashion in that each drive letter is examined to determine the
  205. // physical partition to which the letter is mapped. This structure only
  206. // exists if the logical drive is a real disk, i.e., not built for CDROMs,
  207. // etc.
  208. //
  209. class CLogicalDrive {
  210. public:
  211. CLogicalDrive() {
  212. m_Partition = NULL;
  213. m_ContainerSet = NULL;
  214. }
  215. BOOL Initialize(CPhysicalPartition *Partition);
  216. BOOL IsSCSI(VOID);
  217. BOOL ShareBus(CLogicalDrive *OtherDrive);
  218. DWORD MakeSticky();
  219. WCHAR m_DriveLetter;
  220. CString m_VolumeLabel;
  221. CString m_Identifier;
  222. BOOL m_IsNTFS;
  223. BOOL m_IsSticky;
  224. CPhysicalPartition *m_Partition;
  225. class CFtSet *m_ContainerSet;
  226. };
  227. //
  228. // logical class for FT sets. not used
  229. //
  230. class CFtSet {
  231. public:
  232. CFtSet() { m_FtInfo = NULL; }
  233. BOOL Initialize(class CDiskConfig *Config, CFtInfoFtSet *FtInfo);
  234. CFtInfoFtSet *m_FtInfo;
  235. DWORD MakeSticky();
  236. BOOL IsSticky(VOID);
  237. BOOL IsNTFS(VOID);
  238. BOOL IsSCSI(VOID);
  239. BOOL ShareBus(CLogicalDrive *OtherDrive);
  240. CTypedPtrList<CPtrList, CLogicalDrive*> m_OtherVolumes;
  241. CLogicalDrive Volume;
  242. CTypedPtrList<CPtrList, CPhysicalPartition*> m_Member;
  243. };
  244. //
  245. // main disk configuration class.
  246. //
  247. class CDiskConfig {
  248. public:
  249. CDiskConfig() { m_SystemVolume = NULL; }
  250. ~CDiskConfig();
  251. BOOL Initialize(VOID);
  252. CTypedPtrList<CPtrList, CFtSet*> m_FtSetList;
  253. // database of physical drives indexed by drive number.
  254. CMap<int, int, CPhysicalDisk*, CPhysicalDisk*&> m_PhysicalDisks;
  255. // database of logical drives indexed by drive letter
  256. CMap<WCHAR, WCHAR, CLogicalDrive*, CLogicalDrive*&> m_LogicalDrives;
  257. VOID RemoveAllFtInfoData();
  258. VOID RemoveDisk(CPhysicalDisk *Disk);
  259. DWORD MakeSticky(CPhysicalDisk *Disk);
  260. DWORD MakeSticky(CFtSet *FtSet);
  261. VOID SetDiskInfo(CFtInfoDisk *NewDisk) {
  262. m_FTInfo.DeleteDiskInfo(NewDisk->m_Signature);
  263. m_FTInfo.SetDiskInfo(NewDisk);
  264. m_FTInfo.CommitRegistryData();
  265. };
  266. CPhysicalPartition *FindPartition(CFtInfoPartition *FtPartition);
  267. BOOL OnSystemBus(CPhysicalDisk *Disk);
  268. BOOL OnSystemBus(CFtSet *FtSet);
  269. DWORD MakeSystemDriveSticky() {
  270. if (m_SystemVolume) {
  271. return(MakeSticky(m_SystemVolume->m_Partition->m_PhysicalDisk));
  272. } else {
  273. return(ERROR_SUCCESS);
  274. }
  275. };
  276. CLogicalDrive *m_SystemVolume;
  277. private:
  278. CFtInfo m_FTInfo;
  279. };
  280. typedef struct _DRIVE_LETTER_INFO {
  281. UINT DriveType;
  282. STORAGE_DEVICE_NUMBER DeviceNumber;
  283. } DRIVE_LETTER_INFO, *PDRIVE_LETTER_INFO;
  284. extern DRIVE_LETTER_INFO DriveLetterMap[];
  285. #endif
  286. // Some handy C wrappers for the C++ stuff.
  287. //
  288. #ifdef __cplusplus
  289. extern "C" {
  290. #endif
  291. typedef struct _FT_INFO *PFT_INFO;
  292. typedef struct _FULL_FTSET_INFO *PFULL_FTSET_INFO;
  293. typedef struct _FT_DISK_INFO *PFT_DISK_INFO;
  294. typedef struct _DISK_INFO *PDISK_INFO;
  295. typedef struct _FULL_DISK_INFO *PFULL_DISK_INFO;
  296. PFT_INFO
  297. DiskGetFtInfo(
  298. VOID
  299. );
  300. VOID
  301. DiskFreeFtInfo(
  302. PFT_INFO FtInfo
  303. );
  304. DWORD
  305. DiskEnumFtSetSignature(
  306. IN PFULL_FTSET_INFO FtSet,
  307. IN DWORD MemberIndex,
  308. OUT LPDWORD MemberSignature
  309. );
  310. DWORD
  311. DiskSetFullFtSetInfo(
  312. IN PFT_INFO FtInfo,
  313. IN PFULL_FTSET_INFO FtSet
  314. );
  315. PFULL_FTSET_INFO
  316. DiskGetFullFtSetInfo(
  317. IN PFT_INFO FtInfo,
  318. IN LPCWSTR lpszMemberList,
  319. OUT LPDWORD pSize
  320. );
  321. PFULL_FTSET_INFO
  322. DiskGetFullFtSetInfoByIndex(
  323. IN PFT_INFO FtInfo,
  324. IN DWORD Index,
  325. OUT LPDWORD pSize
  326. );
  327. VOID
  328. DiskMarkFullFtSetDirty(
  329. IN PFULL_FTSET_INFO FtSet
  330. );
  331. DWORD
  332. DiskDeleteFullFtSetInfo(
  333. IN PFT_INFO FtInfo,
  334. IN LPCWSTR lpszMemberList
  335. );
  336. BOOL
  337. DiskFtInfoEqual(
  338. IN PFULL_FTSET_INFO Info1,
  339. IN PFULL_FTSET_INFO Info2
  340. );
  341. FT_TYPE
  342. DiskFtInfoGetType(
  343. IN PFULL_FTSET_INFO Info
  344. );
  345. BOOL
  346. DiskCheckFtSetLetters(
  347. IN PFT_INFO FtInfo,
  348. IN PFULL_FTSET_INFO Bytes,
  349. OUT WCHAR *Letter
  350. );
  351. DWORD
  352. DiskSetFullDiskInfo(
  353. IN PFT_INFO FtInfo,
  354. IN PFULL_DISK_INFO Bytes
  355. );
  356. PFULL_DISK_INFO
  357. DiskGetFullDiskInfo(
  358. IN PFT_INFO FtInfo,
  359. IN DWORD Signature,
  360. OUT LPDWORD pSize
  361. );
  362. enum {
  363. DISKRTL_REPLACE_IF_EXISTS = 0x1,
  364. DISKRTL_COMMIT = 0x2,
  365. };
  366. DWORD
  367. DiskAddDiskInfoEx(
  368. IN PFT_INFO DiskInfo,
  369. IN DWORD DiskIndex,
  370. IN DWORD Signature,
  371. IN DWORD Options
  372. );
  373. DWORD
  374. DiskAddDriveLetterEx(
  375. IN PFT_INFO DiskInfo,
  376. IN DWORD Signature,
  377. IN LARGE_INTEGER StartingOffset,
  378. IN LARGE_INTEGER PartitionLength,
  379. IN UCHAR DriveLetter,
  380. IN DWORD Options
  381. );
  382. DWORD
  383. DiskCommitFtInfo(
  384. IN PFT_INFO FtInfo
  385. );
  386. PFT_INFO
  387. DiskGetFtInfoFromFullDiskinfo(
  388. IN PFULL_DISK_INFO Bytes
  389. );
  390. PFT_DISK_INFO
  391. FtInfo_GetFtDiskInfoBySignature(
  392. IN PFT_INFO FtInfo,
  393. IN DWORD Signature
  394. );
  395. DISK_PARTITION UNALIGNED *
  396. FtDiskInfo_GetPartitionInfoByIndex(
  397. IN PFT_DISK_INFO DiskInfo,
  398. IN DWORD Index
  399. );
  400. DWORD
  401. FtDiskInfo_GetPartitionCount(
  402. IN PFT_DISK_INFO DiskInfo
  403. );
  404. //
  405. // Error handlers to be defined by the user of this library
  406. //
  407. VOID
  408. DiskErrorFatal(
  409. INT MessageId,
  410. DWORD Error,
  411. LPSTR File,
  412. DWORD Line
  413. );
  414. VOID
  415. DiskErrorLogInfo(
  416. LPSTR String,
  417. ...
  418. );
  419. #ifdef __cplusplus
  420. }
  421. #endif
  422. #endif // _CLUSRTL_DISK_H_