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.

296 lines
7.0 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. ULONG
  4. OpenDiskStatus(
  5. IN PSTR NTDeviceName,
  6. OUT PHANDLE Handle
  7. )
  8. {
  9. OBJECT_ATTRIBUTES oa;
  10. NTSTATUS status;
  11. IO_STATUS_BLOCK status_block;
  12. ANSI_STRING AnsiName;
  13. UNICODE_STRING UnicodeName;
  14. RtlInitAnsiString(&AnsiName,NTDeviceName);
  15. status = RtlAnsiStringToUnicodeString(&UnicodeName,&AnsiName,TRUE);
  16. if(!NT_SUCCESS(status)) {
  17. *Handle = NULL;
  18. return(0);
  19. }
  20. memset(&oa, 0, sizeof(OBJECT_ATTRIBUTES));
  21. oa.Length = sizeof(OBJECT_ATTRIBUTES);
  22. oa.ObjectName = &UnicodeName;
  23. oa.Attributes = OBJ_CASE_INSENSITIVE;
  24. status = NtOpenFile(Handle,
  25. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  26. &oa,
  27. &status_block,
  28. FILE_SHARE_READ | FILE_SHARE_WRITE,
  29. FILE_SYNCHRONOUS_IO_ALERT
  30. );
  31. RtlFreeUnicodeString(&UnicodeName);
  32. return((ULONG)status);
  33. }
  34. HANDLE
  35. OpenDiskNT(
  36. IN PSTR NTDeviceName
  37. )
  38. {
  39. NTSTATUS status;
  40. HANDLE Handle = NULL;
  41. status = (NTSTATUS)OpenDiskStatus(NTDeviceName,&Handle);
  42. return(NT_SUCCESS(status) ? Handle : NULL);
  43. }
  44. HANDLE
  45. OpenDisk(
  46. IN PSTR DOSDriveName,
  47. IN BOOL WriteAccessDesired
  48. )
  49. {
  50. OBJECT_ATTRIBUTES oa;
  51. IO_STATUS_BLOCK status_block;
  52. HANDLE Handle;
  53. UNICODE_STRING NTDriveNameW;
  54. PWSTR DOSDriveNameW;
  55. BOOLEAN b;
  56. NTSTATUS status;
  57. unsigned CharsInName,i;
  58. ACCESS_MASK AccessMask;
  59. // convert byte DOS drive name to widechar DOS drive name
  60. CharsInName = lstrlen(DOSDriveName);
  61. DOSDriveNameW = SAlloc((CharsInName+1)*sizeof(WCHAR));
  62. if(DOSDriveNameW == NULL) {
  63. SetErrorText(IDS_ERROR_DLLOOM);
  64. return(NULL);
  65. }
  66. for(i=0; i<CharsInName; i++) {
  67. DOSDriveNameW[i] = (WCHAR)(UCHAR)DOSDriveName[i];
  68. }
  69. DOSDriveNameW[CharsInName] = 0;
  70. // convert widechar DOS drive name to widechar NT drivename
  71. b = RtlDosPathNameToNtPathName_U(DOSDriveNameW,
  72. &NTDriveNameW,
  73. NULL,
  74. NULL
  75. );
  76. SFree(DOSDriveNameW);
  77. if(!b) {
  78. SetErrorText(IDS_ERROR_INVALIDDISK);
  79. return(NULL);
  80. }
  81. if(NTDriveNameW.Buffer[(NTDriveNameW.Length/sizeof(WCHAR))-1] == (WCHAR)'\\')
  82. {
  83. NTDriveNameW.Buffer[(NTDriveNameW.Length/sizeof(WCHAR))-1] = 0;
  84. NTDriveNameW.Length -= sizeof(WCHAR);
  85. }
  86. memset(&oa, 0, sizeof(OBJECT_ATTRIBUTES));
  87. oa.Length = sizeof(OBJECT_ATTRIBUTES);
  88. oa.ObjectName = &NTDriveNameW;
  89. oa.Attributes = OBJ_CASE_INSENSITIVE;
  90. AccessMask = SYNCHRONIZE | FILE_READ_DATA;
  91. if(WriteAccessDesired) {
  92. AccessMask |= FILE_WRITE_DATA;
  93. }
  94. status = NtOpenFile(&Handle,
  95. AccessMask,
  96. &oa,
  97. &status_block,
  98. FILE_SHARE_READ | FILE_SHARE_WRITE,
  99. FILE_SYNCHRONOUS_IO_ALERT
  100. );
  101. if(!NT_SUCCESS(status)) {
  102. SetErrorText(IDS_ERROR_OPENFAIL);
  103. }
  104. RtlFreeUnicodeString(&NTDriveNameW);
  105. return(NT_SUCCESS(status) ? Handle : NULL);
  106. }
  107. BOOL
  108. CloseDisk(
  109. IN HANDLE Handle
  110. )
  111. {
  112. return(NT_SUCCESS(NtClose(Handle)));
  113. }
  114. NTSTATUS
  115. GetDriveGeometry(
  116. IN HANDLE Handle,
  117. IN PDISK_GEOMETRY disk_geometry
  118. )
  119. {
  120. IO_STATUS_BLOCK status_block;
  121. return(NtDeviceIoControlFile(Handle,
  122. 0,
  123. NULL,
  124. NULL,
  125. &status_block,
  126. IOCTL_DISK_GET_DRIVE_GEOMETRY,
  127. NULL,
  128. 0,
  129. disk_geometry,
  130. sizeof(DISK_GEOMETRY)
  131. )
  132. );
  133. }
  134. ULONG
  135. GetSectorSize(
  136. IN HANDLE Handle
  137. )
  138. {
  139. NTSTATUS nts;
  140. DISK_GEOMETRY disk_geometry;
  141. nts = GetDriveGeometry(Handle,&disk_geometry);
  142. if(!NT_SUCCESS(nts)) {
  143. SetErrorText(IDS_ERROR_IOCTLFAIL);
  144. return(0);
  145. }
  146. return(disk_geometry.BytesPerSector);
  147. }
  148. ULONG
  149. GetPartitionSize(
  150. IN PSTR DiskName
  151. )
  152. {
  153. HANDLE DiskHandle;
  154. NTSTATUS nts;
  155. IO_STATUS_BLOCK status_block;
  156. PARTITION_INFORMATION pinfo;
  157. LARGE_INTEGER PartitionSize;
  158. if((DiskHandle = OpenDisk(DiskName,FALSE)) == NULL) {
  159. return(0);
  160. }
  161. nts = NtDeviceIoControlFile(DiskHandle,
  162. 0,
  163. NULL,
  164. NULL,
  165. &status_block,
  166. IOCTL_DISK_GET_PARTITION_INFO,
  167. NULL,
  168. 0,
  169. &pinfo,
  170. sizeof(PARTITION_INFORMATION)
  171. );
  172. CloseDisk(DiskHandle);
  173. if(NT_SUCCESS(nts)) {
  174. PartitionSize = RtlExtendedLargeIntegerDivide(pinfo.PartitionLength,
  175. 1024*1024,
  176. NULL);
  177. return(PartitionSize.LowPart);
  178. } else {
  179. return(0);
  180. }
  181. }
  182. BOOL
  183. ReadDiskSectors(
  184. IN HANDLE Handle,
  185. IN ULONG Sector,
  186. IN ULONG NumSectors,
  187. IN PVOID Buffer,
  188. IN ULONG SectorSize
  189. )
  190. {
  191. IO_STATUS_BLOCK IoStatusBlock;
  192. LARGE_INTEGER ByteOffset;
  193. NTSTATUS nts;
  194. ByteOffset.QuadPart = UInt32x32To64(Sector,SectorSize);
  195. IoStatusBlock.Status = 0;
  196. IoStatusBlock.Information = 0;
  197. nts = NtReadFile(Handle,
  198. 0,
  199. NULL,
  200. NULL,
  201. &IoStatusBlock,
  202. Buffer,
  203. NumSectors * SectorSize,
  204. &ByteOffset,
  205. NULL
  206. );
  207. return(NT_SUCCESS(nts));
  208. }
  209. BOOL
  210. WriteDiskSectors(
  211. IN HANDLE Handle,
  212. IN ULONG Sector,
  213. IN ULONG NumSectors,
  214. IN PVOID Buffer,
  215. IN ULONG SectorSize
  216. )
  217. {
  218. IO_STATUS_BLOCK IoStatusBlock;
  219. LARGE_INTEGER ByteOffset;
  220. NTSTATUS nts;
  221. ByteOffset.QuadPart = UInt32x32To64(Sector,SectorSize);
  222. IoStatusBlock.Status = 0;
  223. IoStatusBlock.Information = 0;
  224. nts = NtWriteFile(Handle,
  225. 0,
  226. NULL,
  227. NULL,
  228. &IoStatusBlock,
  229. Buffer,
  230. NumSectors * SectorSize,
  231. &ByteOffset,
  232. NULL
  233. );
  234. return(NT_SUCCESS(nts));
  235. }
  236. BOOL
  237. ShutdownSystemWorker (
  238. IN BOOL Reboot
  239. )
  240. {
  241. if(OwnProcess) {
  242. return ExitWindowsEx(Reboot ? EWX_REBOOT : EWX_LOGOFF, 0);
  243. }
  244. return(FALSE);
  245. }