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.
422 lines
9.5 KiB
422 lines
9.5 KiB
|
|
|
|
|
|
|
|
#define INITGUID 1
|
|
|
|
#include <nt.h>
|
|
#include <ntdef.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <partmgrp.h>
|
|
#include <stdio.h>
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
|
|
#define PROGRAM_TITLE L"MonDisks - Monitor Disk Arrivals Program V0.1"
|
|
|
|
|
|
#define HandleInvalid(_Handle) ((NULL == (_Handle)) || (INVALID_HANDLE_VALUE == (_Handle)))
|
|
#define HandleValid(_Handle) (!HandleInvalid (_Handle))
|
|
|
|
#define GET_STATUS_FROM_BOOL(_bSucceeded) ((_bSucceeded) ? NOERROR : HRESULT_FROM_WIN32 (GetLastError()))
|
|
#define GET_STATUS_FROM_HANDLE(_handle) ((!HandleInvalid(_handle)) ? NOERROR : HRESULT_FROM_WIN32 (GetLastError()))
|
|
#define GET_STATUS_FROM_POINTER(_ptr) ((NULL != (_ptr)) ? NOERROR : E_OUTOFMEMORY)
|
|
|
|
#define SIZEOF_ARRAY(_aBase) (sizeof (_aBase) / sizeof ((_aBase)[0]))
|
|
|
|
|
|
DWORD WINAPI MonitorThread (LPVOID lpvThreadParam);
|
|
void PrintResults (PPARTMGR_SIGNATURE_CHECK_DISKS pSignatureCheckBufferDisks);
|
|
|
|
|
|
|
|
PSTR PartitionName = "\\Device\\Harddisk%d\\Partition%d";
|
|
PSTR DefaultDevice = "\\Device\\Harddisk0\\Partition0";
|
|
BOOL bExitApplication = FALSE;
|
|
|
|
|
|
|
|
HANDLE handleEventCancelIo = INVALID_HANDLE_VALUE;
|
|
|
|
|
|
|
|
VOID PrintError (IN DWORD ErrorCode)
|
|
{
|
|
PWSTR pMsgBuf;
|
|
ULONG count;
|
|
|
|
count = FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
ErrorCode,
|
|
0,
|
|
(LPWSTR) &pMsgBuf,
|
|
0,
|
|
NULL);
|
|
|
|
if (count != 0)
|
|
{
|
|
printf (" (0x%08x) %ws\n", ErrorCode, pMsgBuf);
|
|
LocalFree (pMsgBuf);
|
|
}
|
|
else
|
|
{
|
|
printf ("Format message failed. Error: 0x%08x\n", GetLastError());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
BOOL WINAPI CtrlC_HandlerRoutine (IN DWORD /* dwType */)
|
|
{
|
|
bExitApplication = TRUE;
|
|
|
|
if (HandleValid (handleEventCancelIo))
|
|
{
|
|
SetEvent (handleEventCancelIo);
|
|
}
|
|
|
|
|
|
|
|
// Mark that the break was handled.
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" __cdecl wmain (int argc, WCHAR *argv [])
|
|
{
|
|
HRESULT hrStatus;
|
|
NTSTATUS ntStatus;
|
|
HANDLE handlePartitionManager = INVALID_HANDLE_VALUE;
|
|
HANDLE handleMonitorThread = INVALID_HANDLE_VALUE;
|
|
DWORD idMonitorThread = 0;
|
|
DWORD accessMode;
|
|
DWORD shareMode;
|
|
DWORD bytesReturned;
|
|
DWORD errorCode;
|
|
BOOL bSucceeded;
|
|
|
|
|
|
ANSI_STRING objName;
|
|
UNICODE_STRING unicodeName;
|
|
OBJECT_ATTRIBUTES objAttributes;
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
|
|
|
|
UNREFERENCED_PARAMETER (argc);
|
|
UNREFERENCED_PARAMETER (argv);
|
|
|
|
|
|
SetConsoleCtrlHandler (CtrlC_HandlerRoutine, TRUE);
|
|
|
|
|
|
handleEventCancelIo = CreateEvent (NULL, FALSE, FALSE, NULL);
|
|
|
|
|
|
//
|
|
// Note it is important to access the device with 0 access mode so that
|
|
// the file open code won't do extra I/O to the device
|
|
//
|
|
shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
|
|
accessMode = GENERIC_READ | GENERIC_WRITE;
|
|
|
|
|
|
RtlInitString (&objName, DefaultDevice);
|
|
|
|
ntStatus = RtlAnsiStringToUnicodeString (&unicodeName,
|
|
&objName,
|
|
TRUE);
|
|
|
|
hrStatus = HRESULT_FROM_NT (ntStatus);
|
|
|
|
|
|
if (FAILED (hrStatus))
|
|
{
|
|
printf("Error converting device name %s to unicode. Error: 0x%08x\n",
|
|
DefaultDevice,
|
|
hrStatus);
|
|
}
|
|
|
|
else
|
|
{
|
|
InitializeObjectAttributes (&objAttributes,
|
|
&unicodeName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL);
|
|
|
|
ntStatus = NtCreateFile (&handlePartitionManager,
|
|
SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
|
|
&objAttributes,
|
|
&ioStatusBlock,
|
|
NULL,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
FILE_OPEN,
|
|
0,
|
|
NULL,
|
|
0);
|
|
|
|
|
|
RtlFreeUnicodeString (&unicodeName);
|
|
|
|
hrStatus = HRESULT_FROM_NT (ntStatus);
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FAILED (hrStatus))
|
|
{
|
|
printf ("Error opening device %s. Error: 0x%08x.\n",
|
|
DefaultDevice,
|
|
hrStatus );
|
|
}
|
|
|
|
else
|
|
{
|
|
handleMonitorThread = CreateThread (NULL,
|
|
0,
|
|
MonitorThread,
|
|
handlePartitionManager,
|
|
0,
|
|
&idMonitorThread);
|
|
|
|
hrStatus = GET_STATUS_FROM_HANDLE (handleMonitorThread);
|
|
}
|
|
|
|
|
|
|
|
|
|
if (SUCCEEDED (hrStatus))
|
|
{
|
|
/*
|
|
** Loop pinging various disks until we tire of life.
|
|
*/
|
|
while (SUCCEEDED (hrStatus) && !bExitApplication)
|
|
{
|
|
char line [80];
|
|
fgets(line, sizeof (line), stdin);
|
|
|
|
|
|
bSucceeded = DeviceIoControl (handlePartitionManager,
|
|
IOCTL_DISK_UPDATE_PROPERTIES,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
0,
|
|
&bytesReturned,
|
|
NULL);
|
|
|
|
|
|
hrStatus = GET_STATUS_FROM_BOOL (bSucceeded);
|
|
|
|
if (FAILED (hrStatus))
|
|
{
|
|
errorCode = GetLastError ();
|
|
|
|
printf ("Error updating disk properties; error was 0x%08x\n", hrStatus);
|
|
|
|
PrintError (errorCode);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (HandleValid (handleMonitorThread))
|
|
{
|
|
bSucceeded = SetEvent (handleEventCancelIo);
|
|
|
|
WaitForSingleObject (handleMonitorThread, INFINITE);
|
|
|
|
CloseHandle (handleMonitorThread);
|
|
}
|
|
|
|
|
|
if (HandleValid (handlePartitionManager))
|
|
{
|
|
ntStatus = NtClose (handlePartitionManager);
|
|
}
|
|
|
|
|
|
if (HandleValid (handleEventCancelIo))
|
|
{
|
|
CloseHandle (handleEventCancelIo);
|
|
}
|
|
|
|
|
|
return (hrStatus);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DWORD WINAPI MonitorThread (LPVOID lpvThreadParam)
|
|
{
|
|
NTSTATUS ntStatus;
|
|
HRESULT hrStatus;
|
|
HANDLE handlePartitionManager = (HANDLE) lpvThreadParam;
|
|
DWORD bytesReturned;
|
|
ULONG bufferLength;
|
|
PARTMGR_SIGNATURE_CHECK_EPOCH SignatureCheckBufferEpoch;
|
|
PPARTMGR_SIGNATURE_CHECK_DISKS pSignatureCheckBufferDisks;
|
|
BOOL bSucceeded;
|
|
DWORD errorCode;
|
|
OVERLAPPED asyncContext;
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
|
|
|
|
|
|
|
|
memset (&asyncContext, 0x00, sizeof (asyncContext));
|
|
|
|
asyncContext.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
|
|
|
|
|
|
|
|
bufferLength = sizeof (PARTMGR_SIGNATURE_CHECK_DISKS) + sizeof (ULONG) * 10;
|
|
|
|
pSignatureCheckBufferDisks = (PPARTMGR_SIGNATURE_CHECK_DISKS) malloc (bufferLength);
|
|
|
|
|
|
SignatureCheckBufferEpoch.RequestEpoch = PARTMGR_REQUEST_CURRENT_DISK_EPOCH;
|
|
|
|
bSucceeded = DeviceIoControl (handlePartitionManager,
|
|
IOCTL_PARTMGR_NOTIFY_SIGNATURE_CHECK,
|
|
&SignatureCheckBufferEpoch,
|
|
sizeof (SignatureCheckBufferEpoch),
|
|
pSignatureCheckBufferDisks,
|
|
bufferLength,
|
|
&bytesReturned,
|
|
NULL);
|
|
|
|
|
|
hrStatus = GET_STATUS_FROM_BOOL (bSucceeded);
|
|
|
|
if (SUCCEEDED (hrStatus))
|
|
{
|
|
PrintResults (pSignatureCheckBufferDisks);
|
|
}
|
|
else
|
|
{
|
|
errorCode = GetLastError ();
|
|
|
|
printf ("Error determining current epoch; error was 0x%08x\n", hrStatus);
|
|
|
|
PrintError (errorCode);
|
|
}
|
|
|
|
|
|
|
|
|
|
while (SUCCEEDED (hrStatus) && (pSignatureCheckBufferDisks->CurrentEpoch > 0))
|
|
{
|
|
SignatureCheckBufferEpoch.RequestEpoch = pSignatureCheckBufferDisks->CurrentEpoch;
|
|
|
|
|
|
bSucceeded = DeviceIoControl (handlePartitionManager,
|
|
IOCTL_PARTMGR_NOTIFY_SIGNATURE_CHECK,
|
|
&SignatureCheckBufferEpoch,
|
|
sizeof (SignatureCheckBufferEpoch),
|
|
pSignatureCheckBufferDisks,
|
|
bufferLength,
|
|
&bytesReturned,
|
|
&asyncContext);
|
|
|
|
hrStatus = GET_STATUS_FROM_BOOL (bSucceeded);
|
|
|
|
if (HRESULT_FROM_WIN32 (ERROR_IO_PENDING) == hrStatus)
|
|
{
|
|
DWORD Result;
|
|
HANDLE aWaitHandles [2];
|
|
|
|
|
|
aWaitHandles [0] = handleEventCancelIo;
|
|
aWaitHandles [1] = asyncContext.hEvent;
|
|
|
|
Result = WaitForMultipleObjects (SIZEOF_ARRAY (aWaitHandles),
|
|
aWaitHandles,
|
|
FALSE,
|
|
INFINITE);
|
|
|
|
|
|
switch (Result)
|
|
{
|
|
case WAIT_OBJECT_0 + 0:
|
|
ntStatus = NtCancelIoFile (handlePartitionManager,
|
|
&ioStatusBlock);
|
|
|
|
/*
|
|
** FALL THROUGH
|
|
*/
|
|
|
|
case WAIT_OBJECT_0 + 1:
|
|
bSucceeded = GetOverlappedResult (handlePartitionManager,
|
|
&asyncContext,
|
|
&bytesReturned,
|
|
TRUE);
|
|
|
|
hrStatus = GET_STATUS_FROM_BOOL (bSucceeded);
|
|
|
|
if (SUCCEEDED (hrStatus))
|
|
{
|
|
PrintResults (pSignatureCheckBufferDisks);
|
|
}
|
|
else
|
|
{
|
|
errorCode = GetLastError ();
|
|
printf ("Error waiting for notification; error was 0x%08x\n", hrStatus);
|
|
PrintError (errorCode);
|
|
}
|
|
|
|
|
|
ResetEvent (asyncContext.hEvent);
|
|
break;
|
|
|
|
|
|
default:
|
|
ASSERT (FALSE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
free (pSignatureCheckBufferDisks);
|
|
|
|
return (hrStatus);
|
|
|
|
}
|
|
|
|
|
|
void PrintResults (PPARTMGR_SIGNATURE_CHECK_DISKS pSignatureCheckBufferDisks)
|
|
{
|
|
ULONG disk;
|
|
|
|
printf ("Returned Values\n"
|
|
"\tCurrent Epoch: 0x%08x\n"
|
|
"\tHighest Epoch for returned disks: 0x%08x\n"
|
|
"\tNumber of disks returned: 0x%08x\n"
|
|
"\tDisks\n",
|
|
pSignatureCheckBufferDisks->CurrentEpoch,
|
|
pSignatureCheckBufferDisks->HighestDiskEpochReturned,
|
|
pSignatureCheckBufferDisks->DiskNumbersReturned);
|
|
|
|
for (disk = 0; disk < pSignatureCheckBufferDisks->DiskNumbersReturned; disk++)
|
|
{
|
|
printf ("\t\t0x%08x\n", pSignatureCheckBufferDisks->DiskNumber [disk]);
|
|
}
|
|
}
|