#include "precomp.h" #pragma hdrstop ULONG OpenDiskStatus( IN PSTR NTDeviceName, OUT PHANDLE Handle ) { OBJECT_ATTRIBUTES oa; NTSTATUS status; IO_STATUS_BLOCK status_block; ANSI_STRING AnsiName; UNICODE_STRING UnicodeName; RtlInitAnsiString(&AnsiName,NTDeviceName); status = RtlAnsiStringToUnicodeString(&UnicodeName,&AnsiName,TRUE); if(!NT_SUCCESS(status)) { *Handle = NULL; return(0); } memset(&oa, 0, sizeof(OBJECT_ATTRIBUTES)); oa.Length = sizeof(OBJECT_ATTRIBUTES); oa.ObjectName = &UnicodeName; oa.Attributes = OBJ_CASE_INSENSITIVE; status = NtOpenFile(Handle, SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA, &oa, &status_block, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT ); RtlFreeUnicodeString(&UnicodeName); return((ULONG)status); } HANDLE OpenDiskNT( IN PSTR NTDeviceName ) { NTSTATUS status; HANDLE Handle = NULL; status = (NTSTATUS)OpenDiskStatus(NTDeviceName,&Handle); return(NT_SUCCESS(status) ? Handle : NULL); } HANDLE OpenDisk( IN PSTR DOSDriveName, IN BOOL WriteAccessDesired ) { OBJECT_ATTRIBUTES oa; IO_STATUS_BLOCK status_block; HANDLE Handle; UNICODE_STRING NTDriveNameW; PWSTR DOSDriveNameW; BOOLEAN b; NTSTATUS status; unsigned CharsInName,i; ACCESS_MASK AccessMask; // convert byte DOS drive name to widechar DOS drive name CharsInName = lstrlen(DOSDriveName); DOSDriveNameW = SAlloc((CharsInName+1)*sizeof(WCHAR)); if(DOSDriveNameW == NULL) { SetErrorText(IDS_ERROR_DLLOOM); return(NULL); } for(i=0; i<CharsInName; i++) { DOSDriveNameW[i] = (WCHAR)(UCHAR)DOSDriveName[i]; } DOSDriveNameW[CharsInName] = 0; // convert widechar DOS drive name to widechar NT drivename b = RtlDosPathNameToNtPathName_U(DOSDriveNameW, &NTDriveNameW, NULL, NULL ); SFree(DOSDriveNameW); if(!b) { SetErrorText(IDS_ERROR_INVALIDDISK); return(NULL); } if(NTDriveNameW.Buffer[(NTDriveNameW.Length/sizeof(WCHAR))-1] == (WCHAR)'\\') { NTDriveNameW.Buffer[(NTDriveNameW.Length/sizeof(WCHAR))-1] = 0; NTDriveNameW.Length -= sizeof(WCHAR); } memset(&oa, 0, sizeof(OBJECT_ATTRIBUTES)); oa.Length = sizeof(OBJECT_ATTRIBUTES); oa.ObjectName = &NTDriveNameW; oa.Attributes = OBJ_CASE_INSENSITIVE; AccessMask = SYNCHRONIZE | FILE_READ_DATA; if(WriteAccessDesired) { AccessMask |= FILE_WRITE_DATA; } status = NtOpenFile(&Handle, AccessMask, &oa, &status_block, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT ); if(!NT_SUCCESS(status)) { SetErrorText(IDS_ERROR_OPENFAIL); } RtlFreeUnicodeString(&NTDriveNameW); return(NT_SUCCESS(status) ? Handle : NULL); } BOOL CloseDisk( IN HANDLE Handle ) { return(NT_SUCCESS(NtClose(Handle))); } NTSTATUS GetDriveGeometry( IN HANDLE Handle, IN PDISK_GEOMETRY disk_geometry ) { IO_STATUS_BLOCK status_block; return(NtDeviceIoControlFile(Handle, 0, NULL, NULL, &status_block, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, disk_geometry, sizeof(DISK_GEOMETRY) ) ); } ULONG GetSectorSize( IN HANDLE Handle ) { NTSTATUS nts; DISK_GEOMETRY disk_geometry; nts = GetDriveGeometry(Handle,&disk_geometry); if(!NT_SUCCESS(nts)) { SetErrorText(IDS_ERROR_IOCTLFAIL); return(0); } return(disk_geometry.BytesPerSector); } ULONG GetPartitionSize( IN PSTR DiskName ) { HANDLE DiskHandle; NTSTATUS nts; IO_STATUS_BLOCK status_block; PARTITION_INFORMATION pinfo; LARGE_INTEGER PartitionSize; if((DiskHandle = OpenDisk(DiskName,FALSE)) == NULL) { return(0); } nts = NtDeviceIoControlFile(DiskHandle, 0, NULL, NULL, &status_block, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &pinfo, sizeof(PARTITION_INFORMATION) ); CloseDisk(DiskHandle); if(NT_SUCCESS(nts)) { PartitionSize = RtlExtendedLargeIntegerDivide(pinfo.PartitionLength, 1024*1024, NULL); return(PartitionSize.LowPart); } else { return(0); } } BOOL ReadDiskSectors( IN HANDLE Handle, IN ULONG Sector, IN ULONG NumSectors, IN PVOID Buffer, IN ULONG SectorSize ) { IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER ByteOffset; NTSTATUS nts; ByteOffset.QuadPart = UInt32x32To64(Sector,SectorSize); IoStatusBlock.Status = 0; IoStatusBlock.Information = 0; nts = NtReadFile(Handle, 0, NULL, NULL, &IoStatusBlock, Buffer, NumSectors * SectorSize, &ByteOffset, NULL ); return(NT_SUCCESS(nts)); } BOOL WriteDiskSectors( IN HANDLE Handle, IN ULONG Sector, IN ULONG NumSectors, IN PVOID Buffer, IN ULONG SectorSize ) { IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER ByteOffset; NTSTATUS nts; ByteOffset.QuadPart = UInt32x32To64(Sector,SectorSize); IoStatusBlock.Status = 0; IoStatusBlock.Information = 0; nts = NtWriteFile(Handle, 0, NULL, NULL, &IoStatusBlock, Buffer, NumSectors * SectorSize, &ByteOffset, NULL ); return(NT_SUCCESS(nts)); } BOOL ShutdownSystemWorker ( IN BOOL Reboot ) { if(OwnProcess) { return ExitWindowsEx(Reboot ? EWX_REBOOT : EWX_LOGOFF, 0); } return(FALSE); }