Leaked source code of windows server 2003
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

  1. #define INITGUID 1
  2. #include <nt.h>
  3. #include <ntdef.h>
  4. #include <ntrtl.h>
  5. #include <nturtl.h>
  6. #include <windows.h>
  7. #include <partmgrp.h>
  8. #include <stdio.h>
  9. #include <stddef.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #define PROGRAM_TITLE L"MonDisks - Monitor Disk Arrivals Program V0.1"
  13. #define HandleInvalid(_Handle) ((NULL == (_Handle)) || (INVALID_HANDLE_VALUE == (_Handle)))
  14. #define HandleValid(_Handle) (!HandleInvalid (_Handle))
  15. #define GET_STATUS_FROM_BOOL(_bSucceeded) ((_bSucceeded) ? NOERROR : HRESULT_FROM_WIN32 (GetLastError()))
  16. #define GET_STATUS_FROM_HANDLE(_handle) ((!HandleInvalid(_handle)) ? NOERROR : HRESULT_FROM_WIN32 (GetLastError()))
  17. #define GET_STATUS_FROM_POINTER(_ptr) ((NULL != (_ptr)) ? NOERROR : E_OUTOFMEMORY)
  18. #define SIZEOF_ARRAY(_aBase) (sizeof (_aBase) / sizeof ((_aBase)[0]))
  19. DWORD WINAPI MonitorThread (LPVOID lpvThreadParam);
  20. void PrintResults (PPARTMGR_SIGNATURE_CHECK_DISKS pSignatureCheckBufferDisks);
  21. PSTR PartitionName = "\\Device\\Harddisk%d\\Partition%d";
  22. PSTR DefaultDevice = "\\Device\\Harddisk0\\Partition0";
  23. BOOL bExitApplication = FALSE;
  24. HANDLE handleEventCancelIo = INVALID_HANDLE_VALUE;
  25. VOID PrintError (IN DWORD ErrorCode)
  26. {
  27. PWSTR pMsgBuf;
  28. ULONG count;
  29. count = FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER |
  30. FORMAT_MESSAGE_FROM_SYSTEM |
  31. FORMAT_MESSAGE_IGNORE_INSERTS,
  32. NULL,
  33. ErrorCode,
  34. 0,
  35. (LPWSTR) &pMsgBuf,
  36. 0,
  37. NULL);
  38. if (count != 0)
  39. {
  40. printf (" (0x%08x) %ws\n", ErrorCode, pMsgBuf);
  41. LocalFree (pMsgBuf);
  42. }
  43. else
  44. {
  45. printf ("Format message failed. Error: 0x%08x\n", GetLastError());
  46. }
  47. }
  48. BOOL WINAPI CtrlC_HandlerRoutine (IN DWORD /* dwType */)
  49. {
  50. bExitApplication = TRUE;
  51. if (HandleValid (handleEventCancelIo))
  52. {
  53. SetEvent (handleEventCancelIo);
  54. }
  55. // Mark that the break was handled.
  56. return TRUE;
  57. }
  58. extern "C" __cdecl wmain (int argc, WCHAR *argv [])
  59. {
  60. HRESULT hrStatus;
  61. NTSTATUS ntStatus;
  62. HANDLE handlePartitionManager = INVALID_HANDLE_VALUE;
  63. HANDLE handleMonitorThread = INVALID_HANDLE_VALUE;
  64. DWORD idMonitorThread = 0;
  65. DWORD accessMode;
  66. DWORD shareMode;
  67. DWORD bytesReturned;
  68. DWORD errorCode;
  69. BOOL bSucceeded;
  70. ANSI_STRING objName;
  71. UNICODE_STRING unicodeName;
  72. OBJECT_ATTRIBUTES objAttributes;
  73. IO_STATUS_BLOCK ioStatusBlock;
  74. UNREFERENCED_PARAMETER (argc);
  75. UNREFERENCED_PARAMETER (argv);
  76. SetConsoleCtrlHandler (CtrlC_HandlerRoutine, TRUE);
  77. handleEventCancelIo = CreateEvent (NULL, FALSE, FALSE, NULL);
  78. //
  79. // Note it is important to access the device with 0 access mode so that
  80. // the file open code won't do extra I/O to the device
  81. //
  82. shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
  83. accessMode = GENERIC_READ | GENERIC_WRITE;
  84. RtlInitString (&objName, DefaultDevice);
  85. ntStatus = RtlAnsiStringToUnicodeString (&unicodeName,
  86. &objName,
  87. TRUE);
  88. hrStatus = HRESULT_FROM_NT (ntStatus);
  89. if (FAILED (hrStatus))
  90. {
  91. printf("Error converting device name %s to unicode. Error: 0x%08x\n",
  92. DefaultDevice,
  93. hrStatus);
  94. }
  95. else
  96. {
  97. InitializeObjectAttributes (&objAttributes,
  98. &unicodeName,
  99. OBJ_CASE_INSENSITIVE,
  100. NULL,
  101. NULL);
  102. ntStatus = NtCreateFile (&handlePartitionManager,
  103. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  104. &objAttributes,
  105. &ioStatusBlock,
  106. NULL,
  107. FILE_ATTRIBUTE_NORMAL,
  108. FILE_SHARE_READ | FILE_SHARE_WRITE,
  109. FILE_OPEN,
  110. 0,
  111. NULL,
  112. 0);
  113. RtlFreeUnicodeString (&unicodeName);
  114. hrStatus = HRESULT_FROM_NT (ntStatus);
  115. }
  116. if (FAILED (hrStatus))
  117. {
  118. printf ("Error opening device %s. Error: 0x%08x.\n",
  119. DefaultDevice,
  120. hrStatus );
  121. }
  122. else
  123. {
  124. handleMonitorThread = CreateThread (NULL,
  125. 0,
  126. MonitorThread,
  127. handlePartitionManager,
  128. 0,
  129. &idMonitorThread);
  130. hrStatus = GET_STATUS_FROM_HANDLE (handleMonitorThread);
  131. }
  132. if (SUCCEEDED (hrStatus))
  133. {
  134. /*
  135. ** Loop pinging various disks until we tire of life.
  136. */
  137. while (SUCCEEDED (hrStatus) && !bExitApplication)
  138. {
  139. char line [80];
  140. fgets(line, sizeof (line), stdin);
  141. bSucceeded = DeviceIoControl (handlePartitionManager,
  142. IOCTL_DISK_UPDATE_PROPERTIES,
  143. NULL,
  144. 0,
  145. NULL,
  146. 0,
  147. &bytesReturned,
  148. NULL);
  149. hrStatus = GET_STATUS_FROM_BOOL (bSucceeded);
  150. if (FAILED (hrStatus))
  151. {
  152. errorCode = GetLastError ();
  153. printf ("Error updating disk properties; error was 0x%08x\n", hrStatus);
  154. PrintError (errorCode);
  155. }
  156. }
  157. }
  158. if (HandleValid (handleMonitorThread))
  159. {
  160. bSucceeded = SetEvent (handleEventCancelIo);
  161. WaitForSingleObject (handleMonitorThread, INFINITE);
  162. CloseHandle (handleMonitorThread);
  163. }
  164. if (HandleValid (handlePartitionManager))
  165. {
  166. ntStatus = NtClose (handlePartitionManager);
  167. }
  168. if (HandleValid (handleEventCancelIo))
  169. {
  170. CloseHandle (handleEventCancelIo);
  171. }
  172. return (hrStatus);
  173. }
  174. DWORD WINAPI MonitorThread (LPVOID lpvThreadParam)
  175. {
  176. NTSTATUS ntStatus;
  177. HRESULT hrStatus;
  178. HANDLE handlePartitionManager = (HANDLE) lpvThreadParam;
  179. DWORD bytesReturned;
  180. ULONG bufferLength;
  181. PARTMGR_SIGNATURE_CHECK_EPOCH SignatureCheckBufferEpoch;
  182. PPARTMGR_SIGNATURE_CHECK_DISKS pSignatureCheckBufferDisks;
  183. BOOL bSucceeded;
  184. DWORD errorCode;
  185. OVERLAPPED asyncContext;
  186. IO_STATUS_BLOCK ioStatusBlock;
  187. memset (&asyncContext, 0x00, sizeof (asyncContext));
  188. asyncContext.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
  189. bufferLength = sizeof (PARTMGR_SIGNATURE_CHECK_DISKS) + sizeof (ULONG) * 10;
  190. pSignatureCheckBufferDisks = (PPARTMGR_SIGNATURE_CHECK_DISKS) malloc (bufferLength);
  191. SignatureCheckBufferEpoch.RequestEpoch = PARTMGR_REQUEST_CURRENT_DISK_EPOCH;
  192. bSucceeded = DeviceIoControl (handlePartitionManager,
  193. IOCTL_PARTMGR_NOTIFY_SIGNATURE_CHECK,
  194. &SignatureCheckBufferEpoch,
  195. sizeof (SignatureCheckBufferEpoch),
  196. pSignatureCheckBufferDisks,
  197. bufferLength,
  198. &bytesReturned,
  199. NULL);
  200. hrStatus = GET_STATUS_FROM_BOOL (bSucceeded);
  201. if (SUCCEEDED (hrStatus))
  202. {
  203. PrintResults (pSignatureCheckBufferDisks);
  204. }
  205. else
  206. {
  207. errorCode = GetLastError ();
  208. printf ("Error determining current epoch; error was 0x%08x\n", hrStatus);
  209. PrintError (errorCode);
  210. }
  211. while (SUCCEEDED (hrStatus) && (pSignatureCheckBufferDisks->CurrentEpoch > 0))
  212. {
  213. SignatureCheckBufferEpoch.RequestEpoch = pSignatureCheckBufferDisks->CurrentEpoch;
  214. bSucceeded = DeviceIoControl (handlePartitionManager,
  215. IOCTL_PARTMGR_NOTIFY_SIGNATURE_CHECK,
  216. &SignatureCheckBufferEpoch,
  217. sizeof (SignatureCheckBufferEpoch),
  218. pSignatureCheckBufferDisks,
  219. bufferLength,
  220. &bytesReturned,
  221. &asyncContext);
  222. hrStatus = GET_STATUS_FROM_BOOL (bSucceeded);
  223. if (HRESULT_FROM_WIN32 (ERROR_IO_PENDING) == hrStatus)
  224. {
  225. DWORD Result;
  226. HANDLE aWaitHandles [2];
  227. aWaitHandles [0] = handleEventCancelIo;
  228. aWaitHandles [1] = asyncContext.hEvent;
  229. Result = WaitForMultipleObjects (SIZEOF_ARRAY (aWaitHandles),
  230. aWaitHandles,
  231. FALSE,
  232. INFINITE);
  233. switch (Result)
  234. {
  235. case WAIT_OBJECT_0 + 0:
  236. ntStatus = NtCancelIoFile (handlePartitionManager,
  237. &ioStatusBlock);
  238. /*
  239. ** FALL THROUGH
  240. */
  241. case WAIT_OBJECT_0 + 1:
  242. bSucceeded = GetOverlappedResult (handlePartitionManager,
  243. &asyncContext,
  244. &bytesReturned,
  245. TRUE);
  246. hrStatus = GET_STATUS_FROM_BOOL (bSucceeded);
  247. if (SUCCEEDED (hrStatus))
  248. {
  249. PrintResults (pSignatureCheckBufferDisks);
  250. }
  251. else
  252. {
  253. errorCode = GetLastError ();
  254. printf ("Error waiting for notification; error was 0x%08x\n", hrStatus);
  255. PrintError (errorCode);
  256. }
  257. ResetEvent (asyncContext.hEvent);
  258. break;
  259. default:
  260. ASSERT (FALSE);
  261. break;
  262. }
  263. }
  264. }
  265. free (pSignatureCheckBufferDisks);
  266. return (hrStatus);
  267. }
  268. void PrintResults (PPARTMGR_SIGNATURE_CHECK_DISKS pSignatureCheckBufferDisks)
  269. {
  270. ULONG disk;
  271. printf ("Returned Values\n"
  272. "\tCurrent Epoch: 0x%08x\n"
  273. "\tHighest Epoch for returned disks: 0x%08x\n"
  274. "\tNumber of disks returned: 0x%08x\n"
  275. "\tDisks\n",
  276. pSignatureCheckBufferDisks->CurrentEpoch,
  277. pSignatureCheckBufferDisks->HighestDiskEpochReturned,
  278. pSignatureCheckBufferDisks->DiskNumbersReturned);
  279. for (disk = 0; disk < pSignatureCheckBufferDisks->DiskNumbersReturned; disk++)
  280. {
  281. printf ("\t\t0x%08x\n", pSignatureCheckBufferDisks->DiskNumber [disk]);
  282. }
  283. }