297 lines
7 KiB
C
297 lines
7 KiB
C
#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);
|
|
}
|