ReactOS  0.4.14-dev-552-g2fad488
ramdisk.c
Go to the documentation of this file.
1 /*
2  * PROJECT: Ramdisk Class Driver
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: drivers/storage/class/ramdisk/ramdisk.c
5  * PURPOSE: Main Driver Routines
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <initguid.h>
12 #include <ntddk.h>
13 #include <ntifs.h>
14 #include <ntdddisk.h>
15 #include <ntddcdrm.h>
16 #include <scsi.h>
17 #include <ntddscsi.h>
18 #include <ntddvol.h>
19 #include <mountdev.h>
20 #include <mountmgr.h>
21 #include <ketypes.h>
22 #include <iotypes.h>
23 #include <rtlfuncs.h>
24 #include <arc/arc.h>
26 #include "../../../filesystems/fs_rec/fs_rec.h"
27 #include <stdio.h>
28 #define NDEBUG
29 #include <debug.h>
30 
31 #define DO_XIP 0x00020000
32 
33 /* GLOBALS ********************************************************************/
34 
35 #define RAMDISK_SESSION_SIZE \
36  FIELD_OFFSET(CDROM_TOC, TrackData) + sizeof(TRACK_DATA)
37 
38 #define RAMDISK_TOC_SIZE \
39  FIELD_OFFSET(CDROM_TOC, TrackData) + 2 * sizeof(TRACK_DATA)
40 
41 #define TOC_DATA_TRACK (0x04)
42 
44 {
48 
50 {
59 
60 DEFINE_GUID(RamdiskBusInterface,
61  0x5DC52DF0,
62  0x2F8A,
63  0x410F,
64  0x80, 0xE4, 0x05, 0xF8, 0x10, 0xE7, 0xA8, 0x8A);
65 
66 DEFINE_GUID(RamdiskDiskInterface,
67  0x31D909F0,
68  0x2CDF,
69  0x4A20,
70  0x9E, 0xD4, 0x7D, 0x65, 0x47, 0x6C, 0xA7, 0x68);
71 
72 typedef struct _RAMDISK_EXTENSION
73 {
85 
86 typedef struct _RAMDISK_BUS_EXTENSION
87 {
90 
92 {
93  /* Inherited base class */
95 
96  /* Data we get from the creator */
106 
107  /* Data we get from the disk */
114 
128 
129 /* FUNCTIONS ******************************************************************/
130 
131 VOID
132 NTAPI
134 {
135  ULONG MinView, DefView, MinViewLength, DefViewLength, MaxViewLength;
137 
138  /* Set defaults */
139  MaximumViewLength = 0x10000000u;
140  MaximumPerDiskViewLength = 0x10000000u;
143  MinimumViewCount = 2;
144  DefaultViewCount = 16;
145  MaximumViewCount = 64;
146  MinimumViewLength = 0x10000u;
147  DefaultViewLength = 0x100000u;
148 
149  /* Setup the query table and query the registry */
151  QueryTable[0].Flags = 1;
152  QueryTable[0].Name = L"Parameters";
153  QueryTable[1].Flags = 32;
154  QueryTable[1].Name = L"ReportDetectedDevice";
156  QueryTable[2].Flags = 32;
157  QueryTable[2].Name = L"MarkRamdisksAsRemovable";
159  QueryTable[3].Flags = 32;
160  QueryTable[3].Name = L"MinimumViewCount";
162  QueryTable[4].Flags = 32;
163  QueryTable[4].Name = L"DefaultViewCount";
165  QueryTable[5].Flags = 32;
166  QueryTable[5].Name = L"MaximumViewCount";
168  QueryTable[6].Flags = 32;
169  QueryTable[6].Name = L"MinimumViewLength";
171  QueryTable[7].Flags = 32;
172  QueryTable[7].Name = L"DefaultViewLength";
174  QueryTable[8].Flags = 32;
175  QueryTable[8].Name = L"MaximumViewLength";
177  QueryTable[9].Flags = 32;
178  QueryTable[9].Name = L"MaximumPerDiskViewLength";
182  QueryTable,
183  NULL,
184  NULL);
185 
186  /* Parse minimum view count, cannot be bigger than 256 or smaller than 2 */
187  MinView = MinimumViewCount;
188  if (MinimumViewCount >= 2)
189  {
190  if (MinimumViewCount > 256) MinView = 256;
191  }
192  else
193  {
194  MinView = 2;
195  }
196  MinimumViewCount = MinView;
197 
198  /* Parse default view count, cannot be bigger than 256 or smaller than minimum */
199  DefView = DefaultViewCount;
200  if (DefaultViewCount >= MinView)
201  {
202  if (DefaultViewCount > 256) DefView = 256;
203  }
204  else
205  {
206  DefView = MinView;
207  }
208  DefaultViewCount = DefView;
209 
210  /* Parse maximum view count, cannot be bigger than 256 or smaller than default */
211  if (MaximumViewCount >= DefView)
212  {
213  if (MaximumViewCount > 256) MaximumViewCount = 256;
214  }
215  else
216  {
217  MaximumViewCount = DefView;
218  }
219 
220  /* Parse minimum view length, cannot be bigger than 1GB or smaller than 64KB */
221  MinViewLength = MinimumViewLength;
222  if (MinimumViewLength >= 0x10000)
223  {
224  if (MinimumViewLength > 0x40000000) MinViewLength = 0x40000000u;
225  }
226  else
227  {
228  MinViewLength = 0x10000u;
229  }
230  MinimumViewLength = MinViewLength;
231 
232  /* Parse default view length, cannot be bigger than 1GB or smaller than minimum */
233  DefViewLength = DefaultViewLength;
234  if (DefaultViewLength >= MinViewLength)
235  {
236  if (DefaultViewLength > 0x40000000) DefViewLength = 0x40000000u;
237  }
238  else
239  {
240  DefViewLength = MinViewLength;
241  }
242  DefaultViewLength = DefViewLength;
243 
244  /* Parse maximum view length, cannot be bigger than 1GB or smaller than default */
245  MaxViewLength = MaximumViewLength;
246  if (MaximumViewLength >= DefViewLength)
247  {
248  if (MaximumViewLength > 0x40000000) MaxViewLength = 0x40000000u;
249  }
250  else
251  {
252  MaxViewLength = DefViewLength;
253  }
254  MaximumViewLength = MaxViewLength;
255 
256  /* Parse maximum view length per disk, cannot be smaller than 16MB */
257  if (MaximumPerDiskViewLength >= 0x1000000)
258  {
259  if (MaxViewLength > 0xFFFFFFFF) MaximumPerDiskViewLength = -1;
260  }
261  else
262  {
263  MaximumPerDiskViewLength = 0x1000000u;
264  }
265 }
266 
267 PVOID
268 NTAPI
271  IN ULONG Length,
272  OUT PULONG OutputLength)
273 {
276  ULONG PageOffset;
277  SIZE_T ActualLength;
278  LARGE_INTEGER ActualOffset;
279  LARGE_INTEGER ActualPages;
280 
281  /* We only support boot disks for now */
282  ASSERT(DeviceExtension->DiskType == RAMDISK_BOOT_DISK);
283 
284  /* Calculate the actual offset in the drive */
285  ActualOffset.QuadPart = DeviceExtension->DiskOffset + Offset.QuadPart;
286 
287  /* Convert to pages */
288  ActualPages.QuadPart = ActualOffset.QuadPart >> PAGE_SHIFT;
289 
290  /* Now add the base page */
291  ActualPages.QuadPart = DeviceExtension->BasePage + ActualPages.QuadPart;
292 
293  /* Calculate final amount of bytes */
294  PhysicalAddress.QuadPart = ActualPages.QuadPart << PAGE_SHIFT;
295 
296  /* Calculate pages spanned for the mapping */
297  ActualLength = ADDRESS_AND_SIZE_TO_SPAN_PAGES(ActualOffset.QuadPart, Length);
298 
299  /* And convert this back to bytes */
300  ActualLength <<= PAGE_SHIFT;
301 
302  /* Get the offset within the page */
303  PageOffset = BYTE_OFFSET(ActualOffset.QuadPart);
304 
305  /* Map the I/O Space from the loader */
307 
308  /* Return actual offset within the page as well as the length */
309  if (MappedBase) MappedBase = (PVOID)((ULONG_PTR)MappedBase + PageOffset);
310  *OutputLength = Length;
311  return MappedBase;
312 }
313 
314 VOID
315 NTAPI
319  IN ULONG Length)
320 {
321  LARGE_INTEGER ActualOffset;
322  SIZE_T ActualLength;
323  ULONG PageOffset;
324 
325  /* We only support boot disks for now */
326  ASSERT(DeviceExtension->DiskType == RAMDISK_BOOT_DISK);
327 
328  /* Calculate the actual offset in the drive */
329  ActualOffset.QuadPart = DeviceExtension->DiskOffset + Offset.QuadPart;
330 
331  /* Calculate pages spanned for the mapping */
332  ActualLength = ADDRESS_AND_SIZE_TO_SPAN_PAGES(ActualOffset.QuadPart, Length);
333 
334  /* And convert this back to bytes */
335  ActualLength <<= PAGE_SHIFT;
336 
337  /* Get the offset within the page */
338  PageOffset = BYTE_OFFSET(ActualOffset.QuadPart);
339 
340  /* Calculate actual base address where we mapped this */
341  BaseAddress = (PVOID)((ULONG_PTR)BaseAddress - PageOffset);
342 
343  /* Unmap the I/O space we got from the loader */
344  MmUnmapIoSpace(BaseAddress, ActualLength);
345 }
346 
347 NTSTATUS
348 NTAPI
351  IN BOOLEAN ValidateOnly,
352  OUT PRAMDISK_DRIVE_EXTENSION *NewDriveExtension)
353 {
354  ULONG BasePage, DiskType, Length;
355  //ULONG ViewCount;
358  PRAMDISK_DRIVE_EXTENSION DriveExtension;
359  PVOID Buffer;
360  WCHAR LocalBuffer[16];
361  UNICODE_STRING SymbolicLinkName, DriveString, GuidString, DeviceName;
363  BIOS_PARAMETER_BLOCK BiosBlock;
364  ULONG BytesPerSector, SectorsPerTrack, Heads, BytesRead;
366  LARGE_INTEGER CurrentOffset, CylinderSize, DiskLength;
367  ULONG CylinderCount, SizeByCylinders;
368 
369  /* Check if we're a boot RAM disk */
370  DiskType = Input->DiskType;
371  if (DiskType >= RAMDISK_BOOT_DISK)
372  {
373  /* Check if we're an ISO */
374  if (DiskType == RAMDISK_BOOT_DISK)
375  {
376  /* NTLDR mounted us somewhere */
377  BasePage = Input->BasePage;
378  if (!BasePage) return STATUS_INVALID_PARAMETER;
379 
380  /* Sanitize disk options */
381  Input->Options.Fixed = TRUE;
382  Input->Options.Readonly = Input->Options.ExportAsCd |
383  Input->Options.Readonly;
384  Input->Options.Hidden = FALSE;
385  Input->Options.NoDosDevice = FALSE;
386  Input->Options.NoDriveLetter = IsWinPEBoot ? TRUE : FALSE;
387  }
388  else
389  {
390  /* The only other possibility is a WIM disk */
391  if (DiskType != RAMDISK_WIM_DISK)
392  {
393  /* Fail */
395  }
396 
397  /* Read the view count instead */
398  // ViewCount = Input->ViewCount;
399 
400  /* Sanitize disk options */
401  Input->Options.Hidden = FALSE;
402  Input->Options.NoDosDevice = FALSE;
403  Input->Options.Readonly = FALSE;
404  Input->Options.NoDriveLetter = TRUE;
405  Input->Options.Fixed = TRUE;
406  }
407 
408  /* Are we just validating and returning to the user? */
409  if (ValidateOnly) return STATUS_SUCCESS;
410 
411  /* Build the GUID string */
412  Status = RtlStringFromGUID(&Input->DiskGuid, &GuidString);
413  if (!(NT_SUCCESS(Status)) || !(GuidString.Buffer))
414  {
415  /* Fail */
417  goto FailCreate;
418  }
419 
420  /* Allocate our device name */
421  Length = GuidString.Length + 32;
423  if (!Buffer)
424  {
425  /* Fail */
427  goto FailCreate;
428  }
429 
430  /* Build the device name string */
431  DeviceName.Buffer = Buffer;
432  DeviceName.Length = Length - 2;
433  DeviceName.MaximumLength = Length;
434  wcsncpy(Buffer, L"\\Device\\Ramdisk", Length / sizeof(WCHAR));
435  wcsncat(Buffer, GuidString.Buffer, Length / sizeof(WCHAR));
436 
437  /* Create the drive device */
438  Status = IoCreateDevice(DeviceExtension->DeviceObject->DriverObject,
439  sizeof(RAMDISK_DRIVE_EXTENSION),
440  &DeviceName,
441  (Input->Options.ExportAsCd) ?
443  0,
444  0,
445  &DeviceObject);
446  if (!NT_SUCCESS(Status)) goto FailCreate;
447 
448  /* Grab the drive extension */
449  DriveExtension = DeviceObject->DeviceExtension;
450 
451  /* Check if we need a DOS device */
452  if (!Input->Options.NoDosDevice)
453  {
454  /* Build the symbolic link name */
455  SymbolicLinkName.MaximumLength = GuidString.Length + 36;
456  SymbolicLinkName.Length = GuidString.Length + 34;
458  SymbolicLinkName.MaximumLength,
459  'dmaR');
460  SymbolicLinkName.Buffer = Buffer;
461  if (Buffer)
462  {
463  /* Create it */
464  wcsncpy(Buffer,
465  L"\\GLOBAL??\\Ramdisk",
466  SymbolicLinkName.MaximumLength / sizeof(WCHAR));
467  wcsncat(Buffer,
468  GuidString.Buffer,
469  SymbolicLinkName.MaximumLength / sizeof(WCHAR));
470  Status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
471  if (!NT_SUCCESS(Status))
472  {
473  /* Nevermind... */
474  Input->Options.NoDosDevice = TRUE;
476  SymbolicLinkName.Buffer = NULL;
477  }
478  }
479  else
480  {
481  /* No DOS device */
482  Input->Options.NoDosDevice = TRUE;
483  }
484 
485  /* Is this an ISO boot ramdisk? */
486  if (Input->DiskType == RAMDISK_BOOT_DISK)
487  {
488  /* Does it need a drive letter? */
489  if (!Input->Options.NoDriveLetter)
490  {
491  /* Build it and take over the existing symbolic link */
492  _snwprintf(LocalBuffer,
493  30,
494  L"\\DosDevices\\%wc:",
495  Input->DriveLetter);
496  RtlInitUnicodeString(&DriveString, LocalBuffer);
497  IoDeleteSymbolicLink(&DriveString);
498  IoCreateSymbolicLink(&DriveString, &DeviceName);
499 
500  /* Save the drive letter */
501  DriveExtension->DriveLetter = Input->DriveLetter;
502  }
503  }
504 
505  }
506 
507  /* Setup the device object flags */
510 
511  /* Build the drive FDO */
512  *NewDriveExtension = DriveExtension;
513  DriveExtension->Type = RamdiskDrive;
514  DiskLength = Input->DiskLength;
515  ExInitializeFastMutex(&DriveExtension->DiskListLock);
516  IoInitializeRemoveLock(&DriveExtension->RemoveLock, 'dmaR', 1, 0);
517  DriveExtension->DriveDeviceName = DeviceName;
518  DriveExtension->SymbolicLinkName = SymbolicLinkName;
519  DriveExtension->GuidString = GuidString;
520  DriveExtension->DiskGuid = Input->DiskGuid;
521  DriveExtension->PhysicalDeviceObject = DeviceObject;
522  DriveExtension->DeviceObject = RamdiskBusFdo;
523  DriveExtension->AttachedDevice = RamdiskBusFdo;
524  DriveExtension->DiskType = Input->DiskType;
525  DriveExtension->DiskOptions = Input->Options;
526  DriveExtension->DiskLength = DiskLength;
527  DriveExtension->DiskOffset = Input->DiskOffset;
528  DriveExtension->BasePage = Input->BasePage;
529  DriveExtension->BytesPerSector = 0;
530  DriveExtension->SectorsPerTrack = 0;
531  DriveExtension->NumberOfHeads = 0;
532 
533  /* Make sure we don't free it later */
534  DeviceName.Buffer = NULL;
535  SymbolicLinkName.Buffer = NULL;
536  GuidString.Buffer = NULL;
537 
538  /* Check if this is a boot disk, or a registry ram drive */
539  if (!(Input->Options.ExportAsCd) &&
540  (Input->DiskType == RAMDISK_BOOT_DISK))
541  {
542  /* Not an ISO boot, but it's a boot FS -- map it to figure out the
543  * drive settings */
544  CurrentOffset.QuadPart = 0;
545  BaseAddress = RamdiskMapPages(DriveExtension,
546  CurrentOffset,
547  PAGE_SIZE,
548  &BytesRead);
549  if (BaseAddress)
550  {
551  /* Get the data */
553  FatUnpackBios(&BiosBlock, &BootSector->PackedBpb);
554  BytesPerSector = BiosBlock.BytesPerSector;
555  SectorsPerTrack = BiosBlock.SectorsPerTrack;
556  Heads = BiosBlock.Heads;
557 
558  /* Save it */
559  DriveExtension->BytesPerSector = BytesPerSector;
560  DriveExtension->SectorsPerTrack = SectorsPerTrack;
561  DriveExtension->NumberOfHeads = Heads;
562 
563  /* Unmap now */
564  CurrentOffset.QuadPart = 0;
565  RamdiskUnmapPages(DriveExtension,
566  BaseAddress,
567  CurrentOffset,
568  BytesRead);
569  }
570  else
571  {
572  /* Fail */
574  goto FailCreate;
575  }
576  }
577 
578  /* Check if the drive settings haven't been set yet */
579  if ((DriveExtension->BytesPerSector == 0) ||
580  (DriveExtension->SectorsPerTrack == 0) ||
581  (DriveExtension->NumberOfHeads == 0))
582  {
583  /* Check if this is a CD */
584  if (Input->Options.ExportAsCd)
585  {
586  /* Setup partition parameters default for ISO 9660 */
587  DriveExtension->BytesPerSector = 2048;
588  DriveExtension->SectorsPerTrack = 32;
589  DriveExtension->NumberOfHeads = 64;
590  }
591  else
592  {
593  /* Setup partition parameters default for FAT */
594  DriveExtension->BytesPerSector = 512;
595  DriveExtension->SectorsPerTrack = 128;
596  DriveExtension->NumberOfHeads = 16;
597  }
598  }
599 
600  /* Calculate the cylinder size */
601  CylinderSize.QuadPart = DriveExtension->BytesPerSector *
602  DriveExtension->SectorsPerTrack *
603  DriveExtension->NumberOfHeads;
604  CylinderCount = DiskLength.QuadPart / CylinderSize.QuadPart;
605  SizeByCylinders = CylinderSize.QuadPart * CylinderCount;
606  DriveExtension->Cylinders = CylinderCount;
607  if ((DiskLength.HighPart > 0) || (SizeByCylinders < DiskLength.LowPart))
608  {
609  /* Align cylinder size up */
610  DriveExtension->Cylinders++;
611  }
612 
613  /* Acquire the disk lock */
615  ExAcquireFastMutex(&DeviceExtension->DiskListLock);
616 
617  /* Insert us */
618  InsertTailList(&DeviceExtension->DiskList, &DriveExtension->DiskList);
619 
620  /* Release the lock */
621  ExReleaseFastMutex(&DeviceExtension->DiskListLock);
623 
624  /* Clear init flag */
626  return STATUS_SUCCESS;
627  }
628 
629 FailCreate:
631  return STATUS_SUCCESS;
632 }
633 
634 NTSTATUS
635 NTAPI
637  IN PIRP Irp,
638  IN BOOLEAN ValidateOnly)
639 {
641  ULONG Length;
642  PRAMDISK_BUS_EXTENSION DeviceExtension;
643  PRAMDISK_DRIVE_EXTENSION DriveExtension;
644  ULONG DiskType;
645  PWCHAR FileNameStart, FileNameEnd;
648 
649  /* Get the device extension and our input data */
650  DeviceExtension = DeviceObject->DeviceExtension;
651  Length = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength;
652  Input = (PRAMDISK_CREATE_INPUT)Irp->AssociatedIrp.SystemBuffer;
653 
654  /* Validate input parameters */
655  if ((Length < sizeof(RAMDISK_CREATE_INPUT)) ||
656  (Input->Version != sizeof(RAMDISK_CREATE_INPUT)))
657  {
659  }
660 
661  /* Validate the disk type */
662  DiskType = Input->DiskType;
663  if (DiskType == RAMDISK_WIM_DISK) return STATUS_INVALID_PARAMETER;
664 
665  /* Look at the disk type */
666  if (DiskType == RAMDISK_BOOT_DISK)
667  {
668  /* We only allow this as an early-init boot */
670 
671  /* Save command-line flags */
672  if (ExportBootDiskAsCd) Input->Options.ExportAsCd = TRUE;
673  if (IsWinPEBoot) Input->Options.NoDriveLetter = TRUE;
674  }
675 
676  /* Validate the disk type */
677  if ((Input->Options.ExportAsCd) && (DiskType != RAMDISK_BOOT_DISK))
678  {
679  /* If the type isn't CDFS, it has to at least be raw CD */
681  }
682 
683  /* Check if this is an actual file */
684  if (DiskType <= RAMDISK_MEMORY_MAPPED_DISK)
685  {
686  /* Validate the file name */
687  FileNameStart = (PWCHAR)((ULONG_PTR)Input + Length);
688  FileNameEnd = Input->FileName + 1;
689  while ((FileNameEnd < FileNameStart) && *(FileNameEnd)) FileNameEnd++;
690  if (FileNameEnd == FileNameStart) return STATUS_INVALID_PARAMETER;
691  }
692 
693  /* Create the actual device */
694  Status = RamdiskCreateDiskDevice(DeviceExtension,
695  Input,
696  ValidateOnly,
697  &DriveExtension);
698  if (NT_SUCCESS(Status))
699  {
700  /* Invalidate and set success */
701  IoInvalidateDeviceRelations(DeviceExtension->PhysicalDeviceObject, 0);
702  Irp->IoStatus.Information = STATUS_SUCCESS;
703  }
704 
705  /* We are done */
706  return Status;
707 }
708 
709 NTSTATUS
710 NTAPI
712  IN PRAMDISK_DRIVE_EXTENSION DeviceExtension)
713 {
717  LARGE_INTEGER Zero = {{0, 0}};
718  ULONG Length;
719  PIO_STACK_LOCATION IoStackLocation;
720 
721  /* Validate the length */
722  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
723  if (IoStackLocation->Parameters.DeviceIoControl.
725  {
726  /* Invalid length */
728  Irp->IoStatus.Status = Status;
729  Irp->IoStatus.Information = 0;
730  return Status;
731  }
732 
733  /* Map the partition table */
734  BaseAddress = RamdiskMapPages(DeviceExtension, Zero, PAGE_SIZE, &Length);
735  if (!BaseAddress)
736  {
737  /* No memory */
739  Irp->IoStatus.Status = Status;
740  Irp->IoStatus.Information = 0;
741  return Status;
742  }
743 
744  /* Fill out the information */
745  PartitionInfo = Irp->AssociatedIrp.SystemBuffer;
746  PartitionInfo->StartingOffset.QuadPart = DeviceExtension->BytesPerSector;
747  PartitionInfo->PartitionLength.QuadPart = DeviceExtension->BytesPerSector *
748  DeviceExtension->SectorsPerTrack *
749  DeviceExtension->NumberOfHeads *
750  DeviceExtension->Cylinders;
751  PartitionInfo->HiddenSectors = DeviceExtension->HiddenSectors;
752  PartitionInfo->PartitionNumber = 0;
753  PartitionInfo->PartitionType = *((PCHAR)BaseAddress + 450);
754  PartitionInfo->BootIndicator = (DeviceExtension->DiskType ==
756  PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartitionInfo->
757  PartitionType);
758  PartitionInfo->RewritePartition = FALSE;
759 
760  /* Unmap the partition table */
761  RamdiskUnmapPages(DeviceExtension, BaseAddress, Zero, Length);
762 
763  /* Done */
764  Irp->IoStatus.Status = STATUS_SUCCESS;
765  Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
766  return STATUS_SUCCESS;
767 }
768 
769 NTSTATUS
770 NTAPI
772  IN PRAMDISK_DRIVE_EXTENSION DeviceExtension)
773 {
777  PIO_STACK_LOCATION Stack;
778  LARGE_INTEGER Zero = {{0, 0}};
780 
781  /* First validate input */
783  if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(PARTITION_INFORMATION))
784  {
786  goto SetAndQuit;
787  }
788 
789  /* Map to get MBR */
790  BaseAddress = RamdiskMapPages(DeviceExtension, Zero, PAGE_SIZE, &BytesRead);
791  if (BaseAddress == NULL)
792  {
794  goto SetAndQuit;
795  }
796 
797  /* Set the new partition type on partition 0, field system indicator */
798  PartitionInfo = (PPARTITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
799  *((PCHAR)BaseAddress + 450) = PartitionInfo->PartitionType;
800 
801  /* And unmap */
802  RamdiskUnmapPages(DeviceExtension, BaseAddress, Zero, BytesRead);
804 
805 SetAndQuit:
806  Irp->IoStatus.Status = Status;
807  Irp->IoStatus.Information = 0;
808  return Status;
809 }
810 
811 VOID
812 NTAPI
814  IN PVOID Context)
815 {
816  PRAMDISK_BUS_EXTENSION DeviceExtension;
818  PIO_STACK_LOCATION IoStackLocation;
819  PIRP Irp = Context;
820 
821  /* Get the stack location */
822  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
823 
824  /* Free the work item */
825  IoFreeWorkItem(Irp->Tail.Overlay.DriverContext[0]);
826 
827  /* Grab the device extension and lock it */
828  DeviceExtension = DeviceObject->DeviceExtension;
829  Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
830  if (NT_SUCCESS(Status))
831  {
832  /* Discriminate by major code */
833  switch (IoStackLocation->MajorFunction)
834  {
835  /* Device control */
837  {
838  /* Let's take a look at the IOCTL */
839  switch (IoStackLocation->Parameters.DeviceIoControl.IoControlCode)
840  {
841  /* Ramdisk create request */
843  {
844  /* This time we'll do it for real */
846  break;
847  }
848 
850  {
852  break;
853  }
854 
856  UNIMPLEMENTED_DBGBREAK("Get drive layout request\n");
857  break;
858 
860  {
862  break;
863  }
864 
865  default:
866  UNIMPLEMENTED_DBGBREAK("Invalid request\n");
867  break;
868  }
869 
870  /* We're here */
871  break;
872  }
873 
874  /* Read or write request */
875  case IRP_MJ_READ:
876  case IRP_MJ_WRITE:
877  UNIMPLEMENTED_DBGBREAK("Read/Write request\n");
878  break;
879 
880  /* Internal request (SCSI?) */
882  UNIMPLEMENTED_DBGBREAK("SCSI request\n");
883  break;
884 
885  /* Flush request */
887  UNIMPLEMENTED_DBGBREAK("Flush request\n");
888  break;
889 
890  /* Anything else */
891  default:
892  UNIMPLEMENTED_DBGBREAK("Invalid request: %lx\n",
893  IoStackLocation->MajorFunction);
894  break;
895  }
896 
897  /* Complete the I/O */
898  IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
899  Irp->IoStatus.Status = Status;
900  Irp->IoStatus.Information = 0;
902  return;
903  }
904 
905  /* Fail the I/O */
906  Irp->IoStatus.Status = Status;
907  Irp->IoStatus.Information = 0;
909 }
910 
911 NTSTATUS
912 NTAPI
914  IN PIRP Irp)
915 {
916  PIO_WORKITEM WorkItem;
917 
918  /* Mark the IRP pending */
920 
921  /* Allocate a work item */
922  WorkItem = IoAllocateWorkItem(DeviceObject);
923  if (WorkItem)
924  {
925  /* Queue it up */
926  Irp->Tail.Overlay.DriverContext[0] = WorkItem;
928  return STATUS_PENDING;
929  }
930  else
931  {
932  /* Fail */
934  }
935 }
936 
937 NTSTATUS
938 NTAPI
940  IN PRAMDISK_DRIVE_EXTENSION DeviceExtension)
941 {
942  PMDL Mdl;
943  PVOID CurrentBase, SystemVa, BaseAddress;
944  PIO_STACK_LOCATION IoStackLocation;
945  LARGE_INTEGER CurrentOffset;
946  ULONG BytesRead, BytesLeft, CopyLength;
949 
950  /* Get the MDL and check if it's mapped */
951  Mdl = Irp->MdlAddress;
953  {
954  /* Use the mapped address */
955  SystemVa = Mdl->MappedSystemVa;
956  }
957  else
958  {
959  /* Map it ourselves */
960  SystemVa = MmMapLockedPagesSpecifyCache(Mdl,
961  0,
962  MmCached,
963  NULL,
964  0,
966  }
967 
968  /* Make sure we were able to map it */
969  CurrentBase = SystemVa;
970  if (!SystemVa) return STATUS_INSUFFICIENT_RESOURCES;
971 
972  /* Initialize default */
973  Irp->IoStatus.Information = 0;
974 
975  /* Get the I/O Stack Location and capture the data */
976  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
977  CurrentOffset = IoStackLocation->Parameters.Read.ByteOffset;
978  BytesLeft = IoStackLocation->Parameters.Read.Length;
979  if (!BytesLeft) return STATUS_INVALID_PARAMETER;
980 
981  /* Do the copy loop */
982  while (TRUE)
983  {
984  /* Map the pages */
985  BaseAddress = RamdiskMapPages(DeviceExtension,
986  CurrentOffset,
987  BytesLeft,
988  &BytesRead);
990 
991  /* Update our lengths */
992  Irp->IoStatus.Information += BytesRead;
993  CopyLength = BytesRead;
994 
995  /* Check if this was a read or write */
997  if (IoStackLocation->MajorFunction == IRP_MJ_READ)
998  {
999  /* Set our copy parameters */
1000  Destination = CurrentBase;
1001  Source = BaseAddress;
1002  goto DoCopy;
1003  }
1004  else if (IoStackLocation->MajorFunction == IRP_MJ_WRITE)
1005  {
1006  /* Set our copy parameters */
1008  Source = CurrentBase;
1009 DoCopy:
1010  /* Copy the data */
1011  RtlCopyMemory(Destination, Source, CopyLength);
1012  }
1013  else
1014  {
1015  /* Prepare us for failure */
1016  BytesLeft = CopyLength;
1018  }
1019 
1020  /* Unmap the pages */
1021  RamdiskUnmapPages(DeviceExtension, BaseAddress, CurrentOffset, BytesRead);
1022 
1023  /* Update offset and bytes left */
1024  BytesLeft -= BytesRead;
1025  CurrentOffset.QuadPart += BytesRead;
1026  CurrentBase = (PVOID)((ULONG_PTR)CurrentBase + BytesRead);
1027 
1028  /* Check if we are done */
1029  if (!BytesLeft) return Status;
1030  }
1031 }
1032 
1033 NTSTATUS
1034 NTAPI
1036  IN PIRP Irp)
1037 {
1038  /* Complete the IRP */
1039  Irp->IoStatus.Information = 1;
1040  Irp->IoStatus.Status = STATUS_SUCCESS;
1042  return STATUS_SUCCESS;
1043 }
1044 
1045 NTSTATUS
1046 NTAPI
1048  IN PIRP Irp)
1049 {
1050  PRAMDISK_DRIVE_EXTENSION DeviceExtension;
1051  // ULONG Length;
1052  // LARGE_INTEGER ByteOffset;
1053  PIO_STACK_LOCATION IoStackLocation;
1054  NTSTATUS Status, ReturnStatus;
1055 
1056  /* Get the device extension and make sure this isn't a bus */
1057  DeviceExtension = DeviceObject->DeviceExtension;
1058  if (DeviceExtension->Type == RamdiskBus)
1059  {
1060  /* Fail */
1062  goto Complete;
1063  }
1064 
1065  /* Capture parameters */
1066  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
1067  // Length = IoStackLocation->Parameters.Read.Length;
1068  // ByteOffset = IoStackLocation->Parameters.Read.ByteOffset;
1069 
1070  /* FIXME: Validate offset */
1071 
1072  /* FIXME: Validate sector */
1073 
1074  /* Validate write */
1075  if ((IoStackLocation->MajorFunction == IRP_MJ_WRITE) &&
1076  (DeviceExtension->DiskOptions.Readonly))
1077  {
1078  /* Fail, this is read-only */
1080  goto Complete;
1081  }
1082 
1083  /* See if we want to do this sync or async */
1084  if (DeviceExtension->DiskType > RAMDISK_MEMORY_MAPPED_DISK)
1085  {
1086  /* Do it sync */
1087  Status = RamdiskReadWriteReal(Irp, DeviceExtension);
1088  goto Complete;
1089  }
1090 
1091  /* Queue it to the worker */
1093  ReturnStatus = STATUS_PENDING;
1094 
1095  /* Check if we're pending or not */
1096  if (Status != STATUS_PENDING)
1097  {
1098 Complete:
1099  /* Complete the IRP */
1100  Irp->IoStatus.Status = Status;
1102  ReturnStatus = Status;
1103  }
1104 
1105  /* Return to caller */
1106  return ReturnStatus;
1107 }
1108 
1109 NTSTATUS
1110 NTAPI
1112  IN PIRP Irp)
1113 {
1114  NTSTATUS Status;
1117  PRAMDISK_DRIVE_EXTENSION DriveExtension = (PVOID)DeviceExtension;
1119  PCDROM_TOC Toc;
1120  PDISK_GEOMETRY DiskGeometry;
1121 
1122  /* Grab the remove lock */
1123  Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
1124  if (!NT_SUCCESS(Status))
1125  {
1126  /* Fail the IRP */
1127  Irp->IoStatus.Information = 0;
1128  Irp->IoStatus.Status = Status;
1130  return Status;
1131  }
1132 
1133  /* Setup some defaults */
1135  Information = 0;
1136 
1137  /* Check if this is an bus device or the drive */
1138  if (DeviceExtension->Type == RamdiskBus)
1139  {
1140  /* Check what the request is */
1141  switch (IoStackLocation->Parameters.DeviceIoControl.IoControlCode)
1142  {
1143  /* Request to create a ramdisk */
1144  case FSCTL_CREATE_RAM_DISK:
1145  {
1146  /* Do it */
1148  if (!NT_SUCCESS(Status)) goto CompleteRequest;
1149  break;
1150  }
1151 
1152  default:
1153  {
1154  /* We don't handle anything else yet */
1155  UNIMPLEMENTED_DBGBREAK("FSCTL: 0x%lx is UNSUPPORTED!\n",
1156  IoStackLocation->Parameters.DeviceIoControl.IoControlCode);
1157  }
1158  }
1159  }
1160  else
1161  {
1162  /* Check what the request is */
1163  switch (IoStackLocation->Parameters.DeviceIoControl.IoControlCode)
1164  {
1169  {
1170  /* Just pretend it's OK, don't do more */
1172  break;
1173  }
1174 
1179  {
1180  /* Validate the length */
1181  if (IoStackLocation->Parameters.DeviceIoControl.
1183  {
1184  /* Invalid length */
1186  break;
1187  }
1188 
1189  /* Fill it out */
1190  DiskGeometry = Irp->AssociatedIrp.SystemBuffer;
1191  DiskGeometry->Cylinders.QuadPart = DriveExtension->Cylinders;
1192  DiskGeometry->BytesPerSector = DriveExtension->BytesPerSector;
1193  DiskGeometry->SectorsPerTrack = DriveExtension->SectorsPerTrack;
1194  DiskGeometry->TracksPerCylinder = DriveExtension->NumberOfHeads;
1195  DiskGeometry->MediaType = DriveExtension->DiskOptions.Fixed ?
1197 
1198  /* We are done */
1200  Information = sizeof(DISK_GEOMETRY);
1201  break;
1202  }
1203 
1204  case IOCTL_CDROM_READ_TOC:
1205  {
1206  /* Validate the length */
1207  if (IoStackLocation->Parameters.DeviceIoControl.
1208  OutputBufferLength < sizeof(CDROM_TOC))
1209  {
1210  /* Invalid length */
1212  break;
1213  }
1214 
1215  /* Clear the TOC */
1216  Toc = Irp->AssociatedIrp.SystemBuffer;
1217  RtlZeroMemory(Toc, sizeof(CDROM_TOC));
1218 
1219  /* Fill it out */
1220  Toc->Length[0] = 0;
1221  Toc->Length[1] = RAMDISK_TOC_SIZE - sizeof(Toc->Length);
1222  Toc->FirstTrack = 1;
1223  Toc->LastTrack = 1;
1224  Toc->TrackData[0].Adr = 1;
1225  Toc->TrackData[0].Control = TOC_DATA_TRACK;
1226  Toc->TrackData[0].TrackNumber = 1;
1227 
1228  /* We are done */
1231  break;
1232  }
1233 
1235  {
1236  Status = RamdiskSetPartitionInfo(Irp, DriveExtension);
1237  break;
1238  }
1239 
1241  {
1242  /* Validate the length */
1243  if (IoStackLocation->Parameters.DeviceIoControl.
1245  {
1246  /* Invalid length */
1248  break;
1249  }
1250 
1251  /* Check if we need to do this sync or async */
1252  if (DriveExtension->DiskType > RAMDISK_MEMORY_MAPPED_DISK)
1253  {
1254  /* Call the helper function */
1255  Status = RamdiskGetPartitionInfo(Irp, DriveExtension);
1256  }
1257  else
1258  {
1259  /* Do it asynchronously later */
1260  goto CallWorker;
1261  }
1262 
1263  /* We are done */
1264  Information = Irp->IoStatus.Information;
1265  break;
1266  }
1267 
1269  {
1270  PGET_LENGTH_INFORMATION LengthInformation = Irp->AssociatedIrp.SystemBuffer;
1271 
1272  /* Validate the length */
1273  if (IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GET_LENGTH_INFORMATION))
1274  {
1275  /* Invalid length */
1277  break;
1278  }
1279 
1280  /* Fill it out */
1281  LengthInformation->Length = DriveExtension->DiskLength;
1282 
1283  /* We are done */
1286  break;
1287  }
1289  {
1291 
1292  /* Validate the length */
1293  if (IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION))
1294  {
1295  /* Invalid length */
1297  break;
1298  }
1299 
1300  /* Fill it out */
1301  GptInformation = Irp->AssociatedIrp.SystemBuffer;
1302  GptInformation->GptAttributes = 0;
1303 
1304  /* Translate the Attributes */
1305  if (DriveExtension->DiskOptions.Readonly)
1306  GptInformation->GptAttributes |= GPT_BASIC_DATA_ATTRIBUTE_READ_ONLY;
1307  if (DriveExtension->DiskOptions.Hidden)
1308  GptInformation->GptAttributes |= GPT_BASIC_DATA_ATTRIBUTE_HIDDEN;
1309  if (DriveExtension->DiskOptions.NoDriveLetter)
1310  GptInformation->GptAttributes |= GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER;
1311 
1312  /* We are done */
1315  break;
1316  }
1317 
1320  case IOCTL_SCSI_MINIPORT:
1326  case IOCTL_VOLUME_OFFLINE:
1327  {
1328  UNIMPLEMENTED_DBGBREAK("IOCTL: 0x%lx is UNIMPLEMENTED!\n",
1329  IoStackLocation->Parameters.DeviceIoControl.IoControlCode);
1330  break;
1331  }
1332 
1333  default:
1334  {
1335  /* Drive code not emulated */
1336  DPRINT1("IOCTL: 0x%lx is UNSUPPORTED!\n",
1337  IoStackLocation->Parameters.DeviceIoControl.IoControlCode);
1338  break;
1339  }
1340  }
1341 
1342  /* If requests drop down here, we just return them complete them */
1343  goto CompleteRequest;
1344  }
1345 
1346  /* Queue the request to our worker thread */
1347 CallWorker:
1349 
1351  /* Release the lock */
1352  IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
1353  if (Status != STATUS_PENDING)
1354  {
1355  /* Complete the request */
1356  Irp->IoStatus.Status = Status;
1357  Irp->IoStatus.Information = Information;
1359  }
1360 
1361  /* Return status */
1362  return Status;
1363 }
1364 
1365 NTSTATUS
1366 NTAPI
1369  IN PIRP Irp)
1370 {
1371  PRAMDISK_BUS_EXTENSION DeviceExtension;
1372  PRAMDISK_DRIVE_EXTENSION DriveExtension;
1373  PDEVICE_RELATIONS DeviceRelations, OurDeviceRelations;
1374  ULONG Count, DiskCount, FinalCount;
1375  PLIST_ENTRY ListHead, NextEntry;
1376  PDEVICE_OBJECT* DriveDeviceObject;
1378 
1379  /* Get the device extension and check if this is a drive */
1380  DeviceExtension = DeviceObject->DeviceExtension;
1381  if (DeviceExtension->Type == RamdiskDrive)
1382  {
1383  NTSTATUS Status;
1384  PDEVICE_RELATIONS DeviceRelations;
1385 
1386  /* We're a child device, only handle target device relations */
1387  if (Type != TargetDeviceRelation)
1388  {
1389  Status = Irp->IoStatus.Status;
1391  return Status;
1392  }
1393 
1394  /* Allocate a buffer big enough to contain only one DO */
1395  DeviceRelations = ExAllocatePoolWithTag(PagedPool,
1396  sizeof(*DeviceRelations),
1397  'dmaR');
1398  if (DeviceRelations != NULL)
1399  {
1400  /* Reference the DO and add it to the buffer */
1402  DeviceRelations->Objects[0] = DeviceObject;
1403  DeviceRelations->Count = 1;
1405  }
1406  else
1407  {
1409  }
1410 
1411  /* Return our processing & complete */
1412  Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
1413  Irp->IoStatus.Status = Status;
1415  return Status;
1416  }
1417 
1418  /* We don't handle anything but bus relations */
1419  if (Type != BusRelations) goto PassToNext;
1420 
1421  /* Acquire the disk list lock */
1423  ExAcquireFastMutex(&DeviceExtension->DiskListLock);
1424 
1425  /* Did a device already fill relations? */
1426  DeviceRelations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
1427  if (DeviceRelations)
1428  {
1429  /* Use the data */
1430  Count = DeviceRelations->Count;
1431  }
1432  else
1433  {
1434  /* We're the first */
1435  Count = 0;
1436  }
1437 
1438  /* Now loop our drives */
1439  DiskCount = 0;
1440  ListHead = &DeviceExtension->DiskList;
1441  NextEntry = ListHead->Flink;
1442  while (NextEntry != ListHead)
1443  {
1444  /* As long as it wasn't removed, count it in */
1445  DriveExtension = CONTAINING_RECORD(NextEntry,
1447  DiskList);
1448  if (DriveExtension->State < RamdiskStateBusRemoved) DiskCount++;
1449 
1450  /* Move to the next one */
1451  NextEntry = NextEntry->Flink;
1452  }
1453 
1454  /* Now we know our final count */
1455  FinalCount = Count + DiskCount;
1456 
1457  /* Allocate the structure */
1458  OurDeviceRelations = ExAllocatePoolWithTag(PagedPool,
1460  Objects) +
1461  FinalCount *
1462  sizeof(PDEVICE_OBJECT),
1463  'dmaR');
1464  if (!OurDeviceRelations)
1465  {
1466  /* Fail */
1467  ExReleaseFastMutex(&DeviceExtension->DiskListLock);
1469  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1472  }
1473 
1474  /* Check if we already had some relations */
1475  if (Count)
1476  {
1477  /* Copy them in */
1478  RtlCopyMemory(OurDeviceRelations->Objects,
1479  DeviceRelations->Objects,
1480  Count * sizeof(PDEVICE_OBJECT));
1481  }
1482 
1483  /* Save the count */
1484  OurDeviceRelations->Count = FinalCount;
1485 
1486  /* Now loop our drives again */
1487  ListHead = &DeviceExtension->DiskList;
1488  NextEntry = ListHead->Flink;
1489  while (NextEntry != ListHead)
1490  {
1491  /* Go to the end of the list */
1492  DriveDeviceObject = &OurDeviceRelations->Objects[Count];
1493 
1494  /* Get the drive state */
1495  DriveExtension = CONTAINING_RECORD(NextEntry,
1497  DiskList);
1498  State = DriveExtension->State;
1499 
1500  /* If it was removed or enumerated, we don't touch the device object */
1502  {
1503  /* If it was removed, we still have to keep track of this though */
1505  {
1506  /* Mark it as enumerated now, but don't actually reference it */
1507  DriveExtension->State = RamdiskStateEnumerated;
1508  }
1509  }
1510  else
1511  {
1512  /* First time it's enumerated, reference the device object */
1513  ObReferenceObject(DriveExtension->DeviceObject);
1514 
1515  /* Save the object pointer and move on */
1516  *DriveDeviceObject++ = DriveExtension->PhysicalDeviceObject;
1517  }
1518 
1519  if (DriveExtension->State < RamdiskStateBusRemoved) DiskCount++;
1520 
1521  /* Move to the next one */
1522  NextEntry = NextEntry->Flink;
1523  }
1524 
1525  /* Release the lock */
1526  ExReleaseFastMutex(&DeviceExtension->DiskListLock);
1528 
1529  /* Cleanup old relations */
1530  if (DeviceRelations) ExFreePool(DeviceRelations);
1531 
1532  /* Complete our IRP */
1533  Irp->IoStatus.Information = (ULONG_PTR)OurDeviceRelations;
1534  Irp->IoStatus.Status = STATUS_SUCCESS;
1535 
1536  /* Pass to the next driver */
1537 PassToNext:
1539  return IoCallDriver(DeviceExtension->AttachedDevice, Irp);
1540 }
1541 
1542 NTSTATUS
1543 NTAPI
1545  IN PIRP Irp)
1546 {
1548  return STATUS_SUCCESS;
1549 }
1550 
1551 NTSTATUS
1552 NTAPI
1554  IN PIRP Irp)
1555 {
1556  NTSTATUS Status;
1557  PLIST_ENTRY ListHead, NextEntry;
1558  PRAMDISK_BUS_EXTENSION DeviceExtension;
1559  PRAMDISK_DRIVE_EXTENSION DriveExtension;
1560 
1561  DeviceExtension = DeviceObject->DeviceExtension;
1562 
1563  /* Acquire disks list lock */
1565  ExAcquireFastMutex(&DeviceExtension->DiskListLock);
1566 
1567  /* Loop over drives */
1568  ListHead = &DeviceExtension->DiskList;
1569  NextEntry = ListHead->Flink;
1570  while (NextEntry != ListHead)
1571  {
1572  DriveExtension = CONTAINING_RECORD(NextEntry,
1574  DiskList);
1575 
1576  /* Delete the disk */
1577  IoAcquireRemoveLock(&DriveExtension->RemoveLock, NULL);
1578  RamdiskDeleteDiskDevice(DriveExtension->PhysicalDeviceObject, NULL);
1579 
1580  /* RamdiskDeleteDiskDevice releases list lock, so reacquire it */
1582  ExAcquireFastMutex(&DeviceExtension->DiskListLock);
1583  }
1584 
1585  /* Release disks list lock */
1586  ExReleaseFastMutex(&DeviceExtension->DiskListLock);
1588 
1589  /* Prepare to pass to the lower driver */
1591  /* Here everything went fine */
1592  Irp->IoStatus.Status = STATUS_SUCCESS;
1593 
1594  /* Call lower driver */
1595  Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
1596 
1597  /* Update state */
1598  DeviceExtension->State = RamdiskStateBusRemoved;
1599 
1600  /* Release the lock and ensure that everyone has finished its job before
1601  * we continue. The lock has been acquired by the dispatcher */
1602  IoReleaseRemoveLockAndWait(&DeviceExtension->RemoveLock, Irp);
1603 
1604  /* If there's a drive name */
1605  if (DeviceExtension->DriveDeviceName.Buffer)
1606  {
1607  /* Inform it's going to be disabled and free the drive name */
1608  IoSetDeviceInterfaceState(&DeviceExtension->DriveDeviceName, FALSE);
1609  RtlFreeUnicodeString(&DeviceExtension->DriveDeviceName);
1610  }
1611 
1612  /* Part from the stack, detach from lower device */
1613  IoDetachDevice(DeviceExtension->AttachedDevice);
1614 
1615  /* Finally, delete device */
1616  RamdiskBusFdo = NULL;
1618 
1619  /* Return status from lower driver */
1620  return Status;
1621 }
1622 
1623 NTSTATUS
1624 NTAPI
1626  IN PIRP Irp)
1627 {
1628  NTSTATUS Status;
1629  PIO_STACK_LOCATION IoStackLocation;
1630  PWSTR OutputString = NULL;
1631  ULONG StringLength;
1632 
1634  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
1635 
1636  /* Get what is being queried */
1637  switch (IoStackLocation->Parameters.QueryId.IdType)
1638  {
1639  case BusQueryDeviceID:
1640  {
1641  /* Allocate a buffer long enough to receive Ramdisk\RamDisk in any case
1642  * In case we don't have RAMDISK_REGISTRY_DISK, we then need two more
1643  * chars to store Ramdisk\RamVolume instead */
1644  StringLength = 4 * (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK) + sizeof(L"Ramdisk\\RamDisk");
1645  OutputString = ExAllocatePoolWithTag(PagedPool, StringLength, 'dmaR');
1646  if (OutputString == NULL)
1647  {
1649  break;
1650  }
1651 
1652  wcsncpy(OutputString, L"Ramdisk\\", StringLength / sizeof(WCHAR));
1653  if (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK)
1654  {
1655  wcsncat(OutputString, L"RamVolume", StringLength / sizeof(WCHAR));
1656  }
1657  else
1658  {
1659  wcsncat(OutputString, L"RamDisk", StringLength / sizeof(WCHAR));
1660  }
1661 
1662  break;
1663  }
1664 
1665  case BusQueryHardwareIDs:
1666  {
1667  /* Allocate a buffer long enough to receive Ramdisk\RamDisk in any case
1668  * In case we don't have RAMDISK_REGISTRY_DISK, we then need two more
1669  * chars to store Ramdisk\RamVolume instead
1670  * We also need an extra char, because it is required that the string
1671  * is null-terminated twice */
1672  StringLength = 4 * (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK) +
1673  sizeof(UNICODE_NULL) + sizeof(L"Ramdisk\\RamDisk");
1674  OutputString = ExAllocatePoolWithTag(PagedPool, StringLength, 'dmaR');
1675  if (OutputString == NULL)
1676  {
1678  break;
1679  }
1680 
1681  wcsncpy(OutputString, L"Ramdisk\\", StringLength / sizeof(WCHAR));
1682  if (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK)
1683  {
1684  wcsncat(OutputString, L"RamVolume", StringLength / sizeof(WCHAR));
1685  }
1686  else
1687  {
1688  wcsncat(OutputString, L"RamDisk", StringLength / sizeof(WCHAR));
1689  }
1690  OutputString[(StringLength / sizeof(WCHAR)) - 1] = UNICODE_NULL;
1691 
1692  break;
1693  }
1694 
1695  case BusQueryCompatibleIDs:
1696  {
1697  if (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK)
1698  {
1700  break;
1701  }
1702 
1703  StringLength = sizeof(L"GenDisk");
1704  OutputString = ExAllocatePoolWithTag(PagedPool, StringLength, 'dmaR');
1705  if (OutputString == NULL)
1706  {
1708  break;
1709  }
1710 
1711  wcsncpy(OutputString, L"GenDisk", StringLength / sizeof(WCHAR));
1712  OutputString[(StringLength / sizeof(WCHAR)) - 1] = UNICODE_NULL;
1713 
1714  break;
1715  }
1716 
1717  case BusQueryInstanceID:
1718  {
1719  OutputString = ExAllocatePoolWithTag(PagedPool,
1720  DriveExtension->GuidString.MaximumLength,
1721  'dmaR');
1722  if (OutputString == NULL)
1723  {
1725  break;
1726  }
1727 
1728  wcsncpy(OutputString,
1729  DriveExtension->GuidString.Buffer,
1730  DriveExtension->GuidString.MaximumLength / sizeof(WCHAR));
1731 
1732  break;
1733  }
1734 
1736  {
1737  /* Nothing to do */
1738  break;
1739  }
1740  }
1741 
1742  Irp->IoStatus.Status = Status;
1743  Irp->IoStatus.Information = (ULONG_PTR)OutputString;
1745  return Status;
1746 }
1747 
1748 NTSTATUS
1749 NTAPI
1751  IN PIRP Irp)
1752 {
1753  NTSTATUS Status;
1754  PIO_STACK_LOCATION IoStackLocation;
1756  PRAMDISK_DRIVE_EXTENSION DriveExtension;
1757 
1758  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
1759  DeviceCapabilities = IoStackLocation->Parameters.DeviceCapabilities.Capabilities;
1760  DriveExtension = DeviceObject->DeviceExtension;
1761 
1762  /* Validate our input buffer */
1763  if (DeviceCapabilities->Version != 1 ||
1764  DeviceCapabilities->Size < sizeof(DEVICE_CAPABILITIES))
1765  {
1767  }
1768  else
1769  {
1770  /* And set everything we know about our capabilities */
1772  DeviceCapabilities->UniqueID = TRUE;
1773  DeviceCapabilities->SilentInstall = TRUE;
1774  DeviceCapabilities->RawDeviceOK = TRUE;
1775  DeviceCapabilities->SurpriseRemovalOK = (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK);
1776  DeviceCapabilities->NoDisplayInUI = TRUE;
1778  }
1779 
1780  Irp->IoStatus.Status = Status;
1782  return Status;
1783 }
1784 
1785 NTSTATUS
1786 NTAPI
1788  IN PIRP Irp)
1789 {
1790  NTSTATUS Status;
1791  PIO_STACK_LOCATION IoStackLocation;
1792  DEVICE_TEXT_TYPE DeviceTextType;
1793  PWSTR OutputString = NULL;
1794 
1795  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
1796  DeviceTextType = IoStackLocation->Parameters.QueryDeviceText.DeviceTextType;
1798 
1799  /* Just copy our constants, according to the input */
1800  switch (DeviceTextType)
1801  {
1802  case DeviceTextDescription:
1803  {
1804  OutputString = ExAllocatePoolWithTag(PagedPool, sizeof(L"RamDisk"), 'dmaR');
1805  if (OutputString == NULL)
1806  {
1808  break;
1809  }
1810 
1811  wcsncpy(OutputString, L"RamDisk", sizeof(L"RamDisk") / sizeof(WCHAR));
1812 
1813  break;
1814  }
1815 
1817  {
1818  OutputString = ExAllocatePoolWithTag(PagedPool, sizeof(L"RamDisk\\0"), 'dmaR');
1819  if (OutputString == NULL)
1820  {
1822  break;
1823  }
1824 
1825  wcsncpy(OutputString, L"RamDisk\\0", sizeof(L"RamDisk\\0") / sizeof(WCHAR));
1826 
1827  break;
1828  }
1829  }
1830 
1831  Irp->IoStatus.Status = Status;
1832  Irp->IoStatus.Information = (ULONG_PTR)OutputString;
1834  return Status;
1835 }
1836 
1837 NTSTATUS
1838 NTAPI
1840  IN PIRP Irp)
1841 {
1842  PPNP_BUS_INFORMATION PnpBusInfo;
1844 
1845  /* Allocate output memory */
1846  PnpBusInfo = ExAllocatePoolWithTag(PagedPool, sizeof(*PnpBusInfo), 'dmaR');
1847  if (PnpBusInfo == NULL)
1848  {
1850  }
1851  else
1852  {
1853  /* Copy our bus GUID and set our legacy type */
1854  RtlCopyMemory(&PnpBusInfo->BusTypeGuid, &GUID_BUS_TYPE_RAMDISK, sizeof(GUID));
1855  PnpBusInfo->LegacyBusType = PNPBus;
1856  PnpBusInfo->BusNumber = 0;
1857  }
1858 
1859  Irp->IoStatus.Status = Status;
1860  Irp->IoStatus.Information = (ULONG_PTR)PnpBusInfo;
1862  return Status;
1863 }
1864 
1865 NTSTATUS
1866 NTAPI
1868  IN PIRP Irp,
1869  IN PVOID Context)
1870 
1871 {
1872  /* Just set the event to unlock caller */
1874 
1876 }
1877 
1878 NTSTATUS
1879 NTAPI
1881  IN PIRP Irp)
1882 {
1883  PIO_STACK_LOCATION IoStackLocation;
1884  PRAMDISK_BUS_EXTENSION DeviceExtension;
1885  NTSTATUS Status;
1886  UCHAR Minor;
1887  KEVENT Event;
1888 
1889  /* Get the device extension and stack location */
1890  DeviceExtension = DeviceObject->DeviceExtension;
1891  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
1892  Minor = IoStackLocation->MinorFunction;
1893 
1894  /* Check if the bus is removed */
1895  if (DeviceExtension->State == RamdiskStateBusRemoved)
1896  {
1897  /* Only remove-device and query-id are allowed */
1899  {
1900  /* Fail anything else */
1902  Irp->IoStatus.Status = Status;
1904  return Status;
1905  }
1906  }
1907 
1908  /* Acquire the remove lock */
1909  Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
1910  if (!NT_SUCCESS(Status))
1911  {
1912  /* Fail the IRP */
1913  Irp->IoStatus.Information = 0;
1914  Irp->IoStatus.Status = Status;
1916  return Status;
1917  }
1918 
1919  /* Query the IRP type */
1920  switch (Minor)
1921  {
1922  case IRP_MN_START_DEVICE:
1923  {
1924  if (DeviceExtension->Type == RamdiskDrive)
1925  {
1927  DEVICE_INSTALL_STATE InstallState;
1928  PRAMDISK_DRIVE_EXTENSION DriveExtension = (PRAMDISK_DRIVE_EXTENSION)DeviceExtension;
1929 
1930  /* If we already have a drive name, free it */
1931  if (DriveExtension->DriveDeviceName.Buffer)
1932  {
1933  ExFreePool(DriveExtension->DriveDeviceName.Buffer);
1934  }
1935 
1936  /* Register our device interface */
1937  if (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK)
1938  {
1940  &GUID_DEVINTERFACE_VOLUME,
1941  NULL,
1942  &DriveExtension->DriveDeviceName);
1943  }
1944  else
1945  {
1947  &RamdiskDiskInterface,
1948  NULL,
1949  &DriveExtension->DriveDeviceName);
1950  }
1951 
1952  /* If we were asked not to assign a drive letter or if getting
1953  * a name failed, just return saying we're now started */
1954  if (DriveExtension->DiskOptions.NoDriveLetter ||
1955  DriveExtension->DriveDeviceName.Buffer == NULL)
1956  {
1957  DriveExtension->State = RamdiskStateStarted;
1958  Irp->IoStatus.Status = Status;
1959  break;
1960  }
1961 
1962  /* Now get our installation state */
1965  sizeof(InstallState),
1966  &InstallState,
1967  &ResultLength);
1968  /* If querying the information failed, assume success */
1969  if (!NT_SUCCESS(Status))
1970  {
1971  InstallState = InstallStateInstalled;
1972  }
1973 
1974  /* If we were properly installed, then, enable the interface */
1975  if (InstallState == InstallStateInstalled)
1976  {
1977  Status = IoSetDeviceInterfaceState(&DriveExtension->DriveDeviceName, TRUE);
1978  }
1979 
1980  /* We're fine & up */
1981  DriveExtension->State = RamdiskStateStarted;
1982  Irp->IoStatus.Status = Status;
1983  break;
1984  }
1985 
1986  /* Prepare next stack to pass it down */
1988 
1989  /* Initialize our notification event & our completion routine */
1992 
1993  /* Call lower driver */
1994  Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
1995  if (Status == STATUS_PENDING)
1996  {
1998  Status = Irp->IoStatus.Status;
1999  }
2000 
2001  /* If it succeed to start then enable ourselves and we're up! */
2002  if (NT_SUCCESS(Status))
2003  {
2004  Status = IoSetDeviceInterfaceState(&DeviceExtension->DriveDeviceName, TRUE);
2005  DeviceExtension->State = RamdiskStateStarted;
2006  }
2007 
2008  Irp->IoStatus.Status = Status;
2009  break;
2010  }
2011 
2014  case IRP_MN_STOP_DEVICE:
2017  {
2018  UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
2019  break;
2020  }
2021 
2022  case IRP_MN_REMOVE_DEVICE:
2023  {
2024  /* Remove the proper device */
2025  if (DeviceExtension->Type == RamdiskBus)
2026  {
2028 
2029  /* Return here, lower device has already been called
2030  * And remove lock released. This is needed by the function. */
2031  return Status;
2032  }
2033  else
2034  {
2036 
2037  /* Complete the IRP here and return
2038  * Here again we don't have to release remove lock
2039  * This has already been done by the function. */
2040  Irp->IoStatus.Status = Status;
2042  return Status;
2043  }
2044  }
2045 
2047  UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
2048  break;
2049 
2050  case IRP_MN_QUERY_ID:
2051  {
2052  /* Are we a drive? */
2053  if (DeviceExtension->Type == RamdiskDrive)
2054  {
2055  Status = RamdiskQueryId((PRAMDISK_DRIVE_EXTENSION)DeviceExtension, Irp);
2056  }
2057  break;
2058  }
2059 
2061  {
2062  /* Are we a drive? */
2063  if (DeviceExtension->Type == RamdiskDrive)
2064  {
2066  }
2067  break;
2068  }
2069 
2070  case IRP_MN_EJECT:
2071  UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
2072  break;
2073 
2075  {
2076  /* Are we a drive? */
2077  if (DeviceExtension->Type == RamdiskDrive)
2078  {
2080  }
2081  break;
2082  }
2083 
2085  {
2086  /* Call our main routine */
2087  Status = RamdiskQueryDeviceRelations(IoStackLocation->
2088  Parameters.
2089  QueryDeviceRelations.Type,
2090  DeviceObject,
2091  Irp);
2092  goto ReleaseAndReturn;
2093  }
2094 
2096  {
2097  /* Are we a drive? */
2098  if (DeviceExtension->Type == RamdiskDrive)
2099  {
2101  }
2102  break;
2103  }
2104 
2107  {
2108  /* Complete immediately without touching it */
2110  goto ReleaseAndReturn;
2111  }
2112 
2113  default:
2114  DPRINT1("Illegal IRP: %lx\n", Minor);
2115  break;
2116  }
2117 
2118  /* Are we the bus? */
2119  if (DeviceExtension->Type == RamdiskBus)
2120  {
2121  /* Do we have an attached device? */
2122  if (DeviceExtension->AttachedDevice)
2123  {
2124  /* Forward the IRP */
2126  Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
2127  }
2128  }
2129 
2130  /* Release the lock and return status */
2131 ReleaseAndReturn:
2132  IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
2133  return Status;
2134 }
2135 
2136 NTSTATUS
2137 NTAPI
2139  IN PIRP Irp)
2140 {
2141  NTSTATUS Status;
2142  PIO_STACK_LOCATION IoStackLocation;
2143  PRAMDISK_BUS_EXTENSION DeviceExtension;
2144 
2145  DeviceExtension = DeviceObject->DeviceExtension;
2146 
2147  /* If we have a device extension, take extra caution with the lower driver */
2148  if (DeviceExtension != NULL)
2149  {
2151 
2152  /* Device has not been removed yet, so pass to the attached/lower driver */
2153  if (DeviceExtension->State < RamdiskStateBusRemoved)
2154  {
2156  return PoCallDriver(DeviceExtension->AttachedDevice, Irp);
2157  }
2158  /* Otherwise, simply complete the IRP notifying that deletion is pending */
2159  else
2160  {
2161  Irp->IoStatus.Status = STATUS_DELETE_PENDING;
2163  return STATUS_DELETE_PENDING;
2164  }
2165  }
2166 
2167  /* Get stack and deal with minor functions */
2168  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
2169  switch (IoStackLocation->MinorFunction)
2170  {
2171  case IRP_MN_SET_POWER:
2172  {
2173  /* If setting device power state it's all fine and return success */
2174  if (DevicePowerState)
2175  {
2176  Irp->IoStatus.Status = STATUS_SUCCESS;
2177  }
2178 
2179  /* Get appropriate status for return */
2180  Status = Irp->IoStatus.Status;
2183  break;
2184  }
2185 
2186  case IRP_MN_QUERY_POWER:
2187  {
2188  /* We can obviously accept all states so just return success */
2189  Status = Irp->IoStatus.Status = STATUS_SUCCESS;
2192  break;
2193  }
2194 
2195  default:
2196  {
2197  /* Just complete and save status for return */
2198  Status = Irp->IoStatus.Status;
2201  break;
2202  }
2203  }
2204 
2205  return Status;
2206 }
2207 
2208 NTSTATUS
2209 NTAPI
2211  IN PIRP Irp)
2212 {
2213  NTSTATUS Status;
2214  PRAMDISK_BUS_EXTENSION DeviceExtension;
2215 
2216  DeviceExtension = DeviceObject->DeviceExtension;
2217 
2218  /* If we have a device extension, forward the IRP to the attached device */
2219  if (DeviceExtension != NULL)
2220  {
2222  Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
2223  }
2224  /* Otherwise just complete the request
2225  * And return the status with which we complete it */
2226  else
2227  {
2228  Status = Irp->IoStatus.Status;
2230  }
2231 
2232  return Status;
2233 }
2234 
2235 NTSTATUS
2236 NTAPI
2238  IN PIRP Irp)
2239 {
2240  NTSTATUS Status;
2241  PRAMDISK_BUS_EXTENSION DeviceExtension;
2242 
2243  DeviceExtension = DeviceObject->DeviceExtension;
2244 
2245  /* Having a proper device is mandatory */
2246  if (DeviceExtension->State > RamdiskStateStopped)
2247  {
2249  goto CompleteIRP;
2250  }
2251 
2252  /* Acquire the remove lock */
2253  Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
2254  if (!NT_SUCCESS(Status))
2255  {
2256  goto CompleteIRP;
2257  }
2258 
2259  /* Queue the IRP for worker */
2261  if (Status != STATUS_PENDING)
2262  {
2263  goto CompleteIRP;
2264  }
2265 
2266  /* Release the remove lock */
2267  IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
2268  goto Quit;
2269 
2270 CompleteIRP:
2271  Irp->IoStatus.Information = 0;
2272  Irp->IoStatus.Status = Status;
2274 
2275 Quit:
2276  return Status;
2277 }
2278 
2279 NTSTATUS
2280 NTAPI
2282  IN PIRP Irp)
2283 {
2284  NTSTATUS Status;
2285  PRAMDISK_DRIVE_EXTENSION DeviceExtension;
2286 
2287  DeviceExtension = DeviceObject->DeviceExtension;
2288 
2289  /* Ensure we have drive extension
2290  * Only perform flush on disks that have been created
2291  * from registry entries */
2292  if (DeviceExtension->Type != RamdiskDrive ||
2293  DeviceExtension->DiskType > RAMDISK_MEMORY_MAPPED_DISK)
2294  {
2295  Irp->IoStatus.Information = 0;
2296  Irp->IoStatus.Status = STATUS_SUCCESS;
2298  return STATUS_SUCCESS;
2299  }
2300 
2301  /* Queue the IRP for worker */
2303  if (Status != STATUS_PENDING)
2304  {
2305  /* Queuing failed - complete the IRP and return failure */
2306  Irp->IoStatus.Information = 0;
2307  Irp->IoStatus.Status = Status;
2309  }
2310 
2311  return Status;
2312 }
2313 
2314 VOID
2315 NTAPI
2317 {
2318  /* Just release registry path if previously allocated */
2320  {
2322  }
2323 }
2324 
2325 NTSTATUS
2326 NTAPI
2329 {
2330  PRAMDISK_BUS_EXTENSION DeviceExtension;
2331  PDEVICE_OBJECT AttachedDevice;
2332  NTSTATUS Status;
2335 
2336  /* Only create the bus FDO once */
2338 
2339  /* Create the bus FDO */
2340  RtlInitUnicodeString(&DeviceName, L"\\Device\\Ramdisk");
2342  sizeof(RAMDISK_BUS_EXTENSION),
2343  &DeviceName,
2346  0,
2347  &DeviceObject);
2348  if (NT_SUCCESS(Status))
2349  {
2350  /* Initialize the bus FDO extension */
2351  DeviceExtension = DeviceObject->DeviceExtension;
2352  RtlZeroMemory(DeviceExtension, sizeof(*DeviceExtension));
2353 
2354  /* Set bus FDO flags */
2356 
2357  /* Setup the bus FDO extension */
2358  DeviceExtension->Type = RamdiskBus;
2359  ExInitializeFastMutex(&DeviceExtension->DiskListLock);
2360  IoInitializeRemoveLock(&DeviceExtension->RemoveLock, 'dmaR', 1, 0);
2361  InitializeListHead(&DeviceExtension->DiskList);
2362  DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
2363  DeviceExtension->DeviceObject = DeviceObject;
2364 
2365  /* Register the RAM disk device interface */
2367  &RamdiskBusInterface,
2368  NULL,
2369  &DeviceExtension->BusDeviceName);
2370  if (!NT_SUCCESS(Status))
2371  {
2372  /* Fail */
2374  return Status;
2375  }
2376 
2377  /* Attach us to the device stack */
2378  AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject,
2380  DeviceExtension->AttachedDevice = AttachedDevice;
2381  if (!AttachedDevice)
2382  {
2383  /* Fail */
2384  IoSetDeviceInterfaceState(&DeviceExtension->BusDeviceName, 0);
2385  RtlFreeUnicodeString(&DeviceExtension->BusDeviceName);
2387  return STATUS_NO_SUCH_DEVICE;
2388  }
2389 
2390  /* Bus FDO is initialized */
2392 
2393  /* Loop for loader block */
2394  if (KeLoaderBlock)
2395  {
2396  /* Are we being booted from setup? Not yet supported */
2398  DPRINT1("FIXME: RamdiskAddDevice is UNSUPPORTED when being started from SETUPLDR!\n");
2399  // ASSERT(!KeLoaderBlock->SetupLdrBlock);
2400  }
2401 
2402  /* All done */
2405  }
2406 
2407  /* Return status */
2408  return Status;
2409 }
2410 
2411 NTSTATUS
2412 NTAPI
2415 {
2416  PCHAR BootDeviceName, CommandLine;
2418  NTSTATUS Status;
2419  DPRINT("RAM Disk Driver Initialized\n");
2420 
2421  /* Query ramdisk parameters */
2423 
2424  /* Save the registry path */
2427  RegistryPath->Length +
2428  sizeof(UNICODE_NULL),
2429  'dmaR');
2432 
2433  /* Set device routines */
2446 
2447  /* Check for a loader block */
2448  if (KeLoaderBlock)
2449  {
2450  /* Get the boot device name */
2451  BootDeviceName = KeLoaderBlock->ArcBootDeviceName;
2452  if (BootDeviceName)
2453  {
2454  /* Check if we're booting from ramdisk */
2455  if ((strlen(BootDeviceName) >= 10) &&
2456  !(_strnicmp(BootDeviceName, "ramdisk(0)", 10)))
2457  {
2458  /* We'll have to tell the PnP Manager */
2460 
2461  /* Check for a command line */
2462  CommandLine = KeLoaderBlock->LoadOptions;
2463  if (CommandLine)
2464  {
2465  /* Check if this is an ISO boot */
2466  if (strstr(CommandLine, "RDEXPORTASCD"))
2467  {
2468  /* Remember for later */
2470  }
2471 
2472  /* Check if this is PE boot */
2473  if (strstr(CommandLine, "MININT"))
2474  {
2475  /* Remember for later */
2476  IsWinPEBoot = TRUE;
2477  }
2478  }
2479  }
2480 
2481  }
2482  }
2483 
2484  /* Installing from Ramdisk isn't supported yet */
2486  DPRINT1("FIXME: Installing from RamDisk is UNSUPPORTED!\n");
2487  // ASSERT(!KeLoaderBlock->SetupLdrBlock);
2488 
2489  /* Are we reporting the device */
2491  {
2492  /* Do it */
2495  0xFFFFFFFF,
2496  0xFFFFFFFF,
2497  NULL,
2498  NULL,
2499  0,
2501  if (NT_SUCCESS(Status))
2502  {
2503  /* Create the device object */
2505  if (NT_SUCCESS(Status))
2506  {
2507  /* We are done */
2510  }
2511  }
2512  }
2513  else
2514  {
2515  /* Done */
2517  }
2518 
2519  /* Done */
2520  return Status;
2521 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
struct _RAMDISK_EXTENSION RAMDISK_EXTENSION
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define STATUS_DEVICE_ALREADY_ATTACHED
Definition: ntstatus.h:278
signed char * PCHAR
Definition: retypes.h:7
ULONG ReportDetectedDevice
Definition: ramdisk.c:117
ULONG MaximumPerDiskViewLength
Definition: ramdisk.c:116
_Out_opt_ PULONG Minor
Definition: cmfuncs.h:44
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define DO_POWER_PAGABLE
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:414
NTSTATUS NTAPI RamdiskQueryDeviceRelations(IN DEVICE_RELATION_TYPE Type, IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:1367
DEFINE_GUID(RamdiskBusInterface, 0x5DC52DF0, 0x2F8A, 0x410F, 0x80, 0xE4, 0x05, 0xF8, 0x10, 0xE7, 0xA8, 0x8A)
static PWSTR GuidString
Definition: apphelp.c:91
BOOLEAN ExportBootDiskAsCd
Definition: ramdisk.c:125
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4004
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:38
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:308
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
RAMDISK_DEVICE_TYPE Type
Definition: ramdisk.c:74
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define FSCTL_CREATE_RAM_DISK
Definition: ntddrdsk.h:45
VOID NTAPI QueryParameters(IN PUNICODE_STRING RegistryPath)
Definition: ramdisk.c:133
UNICODE_STRING DriveDeviceName
Definition: ramdisk.c:80
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MN_QUERY_RESOURCES
UCHAR Length[2]
Definition: ntddcdrm.h:163
PDEVICE_OBJECT AttachedDevice
Definition: ramdisk.c:78
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PSTR ArcBootDeviceName
Definition: arc.h:503
#define IRP_MN_QUERY_ID
ULONG MaximumViewCount
Definition: ramdisk.c:121
ULONG MarkRamdisksAsRemovable
Definition: ramdisk.c:118
NTSTATUS NTAPI RamdiskQueryId(IN PRAMDISK_DRIVE_EXTENSION DriveExtension, IN PIRP Irp)
Definition: ramdisk.c:1625
Type
Definition: Type.h:6
PDEVICE_OBJECT PhysicalDeviceObject
Definition: ramdisk.c:77
enum _RAMDISK_DEVICE_STATE RAMDISK_DEVICE_STATE
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_MN_QUERY_POWER
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
UCHAR FirstTrack
Definition: ntddcdrm.h:164
NTSTATUS NTAPI PoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: power.c:485
UNICODE_STRING SymbolicLinkName
Definition: ramdisk.c:99
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
ULONG MinimumViewCount
Definition: ramdisk.c:119
#define IOCTL_SCSI_MINIPORT
Definition: scsi_port.h:48
_In_ PIRP Irp
Definition: csq.h:116
#define IoInitializeRemoveLock(Lock, AllocateTag, MaxLockedMinutes, HighWatermark)
Definition: iofuncs.h:2785
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS NTAPI RamdiskDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:1111
#define IOCTL_CDROM_CHECK_VERIFY
Definition: ntddcdrm.h:34
uint16_t * PWSTR
Definition: typedefs.h:54
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
ULONG MaximumViewLength
Definition: ramdisk.c:115
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
VOID NTAPI RamdiskUnload(IN PDRIVER_OBJECT DriverObject)
Definition: ramdisk.c:2316
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2055
struct _RAMDISK_DRIVE_EXTENSION RAMDISK_DRIVE_EXTENSION
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2716
Definition: arc.h:84
NTSTATUS NTAPI RamdiskReadWriteReal(IN PIRP Irp, IN PRAMDISK_DRIVE_EXTENSION DeviceExtension)
Definition: ramdisk.c:939
#define RAMDISK_REGISTRY_DISK
Definition: ntddrdsk.h:50
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG _In_ ULONG OutputBufferLength
Definition: fltkernel.h:1374
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
LARGE_INTEGER DiskLength
Definition: ramdisk.c:102
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
DEVICE_CAPABILITIES
Definition: iotypes.h:928
ULONG BytesPerSector
Definition: ntdddisk.h:381
PVOID NTAPI RamdiskMapPages(IN PRAMDISK_DRIVE_EXTENSION DeviceExtension, IN LARGE_INTEGER Offset, IN ULONG Length, OUT PULONG OutputLength)
Definition: ramdisk.c:269
#define IRP_MN_EJECT
ULONG TracksPerCylinder
Definition: ntdddisk.h:379
uint16_t * PWCHAR
Definition: typedefs.h:54
_RAMDISK_DEVICE_TYPE
Definition: ramdisk.c:43
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1122
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define InsertTailList(ListHead, Entry)
NTSTATUS NTAPI RamdiskQueryDeviceText(IN PRAMDISK_DRIVE_EXTENSION DriveExtension, IN PIRP Irp)
Definition: ramdisk.c:1787
struct _PARTITION_INFORMATION PARTITION_INFORMATION
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
VOID NTAPI RamdiskUnmapPages(IN PRAMDISK_DRIVE_EXTENSION DeviceExtension, IN PVOID BaseAddress, IN LARGE_INTEGER Offset, IN ULONG Length)
Definition: ramdisk.c:316
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
enum _DEVICE_TEXT_TYPE DEVICE_TEXT_TYPE
#define RAMDISK_WIM_DISK
Definition: ntddrdsk.h:53
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
LARGE_INTEGER Length
Definition: imports.h:232
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
USHORT Heads
Definition: fat.h:113
RAMDISK_DEVICE_STATE State
Definition: ramdisk.c:75
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define IRP_MJ_SCSI
struct _BootSector BootSector
Definition: vfat.h:108
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:107
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
NTSTATUS NTAPI RamdiskQueryCapabilities(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:1750
NTSTATUS NTAPI IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, IN INTERFACE_TYPE LegacyBusType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PCM_RESOURCE_LIST ResourceList, IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL, IN BOOLEAN ResourceAssigned, IN OUT PDEVICE_OBJECT *DeviceObject OPTIONAL)
Definition: pnpreport.c:162
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
struct _SETUP_LOADER_BLOCK * SetupLdrBlock
Definition: arc.h:511
_In_ ULONG _In_ ULONG SectorsPerTrack
Definition: iofuncs.h:2066
#define IOCTL_VOLUME_OFFLINE
Definition: ntddvol.h:65
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define UNICODE_NULL
#define IRP_MN_QUERY_REMOVE_DEVICE
long LONG
Definition: pedump.c:60
UNICODE_STRING GuidString
Definition: ramdisk.c:98
struct _RAMDISK_BUS_EXTENSION RAMDISK_BUS_EXTENSION
IO_REMOVE_LOCK RemoveLock
Definition: ramdisk.c:79
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2174
_Check_return_ _CRTIMP int __cdecl _strnicmp(_In_reads_or_z_(_MaxCount) const char *_Str1, _In_reads_or_z_(_MaxCount) const char *_Str2, _In_ size_t _MaxCount)
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
struct _GET_LENGTH_INFORMATION GET_LENGTH_INFORMATION
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI RamdiskFlushBuffers(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:2281
#define MDL_SOURCE_IS_NONPAGED_POOL
Definition: mmtypes.h:20
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
#define DeviceCapabilities
Definition: wingdi.h:4448
NTSTATUS NTAPI IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
Definition: pnpmgr.c:4228
void DPRINT(...)
Definition: polytest.cpp:61
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define IOCTL_DISK_GET_MEDIA_TYPES
Definition: cdrw_usr.h:182
#define IOCTL_VOLUME_SET_GPT_ATTRIBUTES
Definition: ntddvol.h:53
Definition: bufpool.h:45
NTSTATUS NTAPI RamdiskRemoveBusDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:1553
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
#define RTL_REGISTRY_OPTIONAL
Definition: nt_native.h:169
void * PVOID
Definition: retypes.h:9
NTSTATUS NTAPI RamdiskAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: ramdisk.c:2327
#define IOCTL_DISK_SET_PARTITION_INFO
Definition: ntdddisk.h:176
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
#define RAMDISK_BOOT_DISK
Definition: ntddrdsk.h:52
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
enum _DEVICE_RELATION_TYPE DEVICE_RELATION_TYPE
#define PCHAR
Definition: match.c:90
#define IOCTL_MOUNTDEV_QUERY_STABLE_GUID
Definition: imports.h:255
#define IRP_MN_QUERY_STOP_DEVICE
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:87
FAST_MUTEX
Definition: extypes.h:17
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
FAST_MUTEX DiskListLock
Definition: ramdisk.c:82
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG DefaultViewCount
Definition: ramdisk.c:120
#define IOCTL_STORAGE_QUERY_PROPERTY
Definition: ntddstor.h:167
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define DO_XIP
Definition: ramdisk.c:31
#define RAMDISK_TOC_SIZE
Definition: ramdisk.c:38
UNICODE_STRING BusDeviceName
Definition: ramdisk.c:81
NTSTATUS NTAPI SendIrpToThread(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:913
#define IRP_MN_STOP_DEVICE
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY
Definition: ntddcdrm.h:46
NTSTATUS NTAPI RamdiskPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:1880
struct _RAMDISK_DRIVE_EXTENSION * PRAMDISK_DRIVE_EXTENSION
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:377
ULONG MinimumViewLength
Definition: ramdisk.c:122
ULONG SectorsPerTrack
Definition: ntdddisk.h:380
#define TOC_DATA_TRACK
Definition: ramdisk.c:41
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:276
#define IRP_MN_START_DEVICE
_RAMDISK_DEVICE_STATE
Definition: ramdisk.c:49
USHORT BytesPerSector
Definition: fat.h:104
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2101
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: ramdisk.c:2413
MEDIA_TYPE MediaType
Definition: ntdddisk.h:378
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2891
#define IRP_MN_QUERY_DEVICE_TEXT
PDEVICE_OBJECT DeviceObject
Definition: ramdisk.c:76
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSTATUS NTAPI CompleteRequest(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: dispatch.c:19
VOID NTAPI RamdiskWorkerThread(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: ramdisk.c:813
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
struct _RAMDISK_EXTENSION * PRAMDISK_EXTENSION
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IRP_MN_QUERY_BUS_INFORMATION
struct _RAMDISK_CREATE_INPUT * PRAMDISK_CREATE_INPUT
NTSTATUS NTAPI RamdiskPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:2138
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1061
UCHAR LastTrack
Definition: ntddcdrm.h:165
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IRP_MJ_POWER
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:88
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:872
static const WCHAR L[]
Definition: oid.c:1250
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2180
NTSTATUS NTAPI RamdiskQueryBusInformation(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:1839
UCHAR Control
Definition: ntddcdrm.h:104
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
ULONG LowPart
Definition: typedefs.h:104
NTSTATUS NTAPI RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension, IN PRAMDISK_CREATE_INPUT Input, IN BOOLEAN ValidateOnly, OUT PRAMDISK_DRIVE_EXTENSION *NewDriveExtension)
Definition: ramdisk.c:349
#define IRP_MN_SET_POWER
#define IOCTL_STORAGE_CHECK_VERIFY2
Definition: ntddk_ex.h:212
NTSTATUS NTAPI RamdiskSystemControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:2210
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Definition: ntddvol.h:41
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:117
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
_CRTIMP wchar_t *__cdecl wcsncat(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
#define IRP_MJ_SYSTEM_CONTROL
* PDEVICE_CAPABILITIES
Definition: iotypes.h:928
NTSTATUS NTAPI RamdiskCreateRamdisk(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN BOOLEAN ValidateOnly)
Definition: ramdisk.c:636
Status
Definition: gdiplustypes.h:24
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:76
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
ULONG_PTR SIZE_T
Definition: typedefs.h:78
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2112
struct _DISK_GEOMETRY DISK_GEOMETRY
struct _PARTITION_INFORMATION * PPARTITION_INFORMATION
enum State_ State
Definition: pofuncs.h:54
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:5111
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
#define IOCTL_STORAGE_GET_MEDIA_TYPES
Definition: ntddstor.h:120
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:626
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
NTSTATUS NTAPI RamdiskReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:1047
PVOID NTAPI MmMapLockedPagesSpecifyCache(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN MEMORY_CACHING_TYPE CacheType, IN PVOID BaseAddress, IN ULONG BugCheckOnFailure, IN MM_PAGE_PRIORITY Priority)
Definition: mdlsup.c:664
UCHAR TrackNumber
Definition: ntddcdrm.h:106
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MN_QUERY_DEVICE_RELATIONS
RAMDISK_CREATE_OPTIONS DiskOptions
Definition: ramdisk.c:101
enum _DEVICE_INSTALL_STATE DEVICE_INSTALL_STATE
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
NTSTATUS NTAPI RamdiskScsi(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:2237
enum _RAMDISK_DEVICE_TYPE RAMDISK_DEVICE_TYPE
LIST_ENTRY DiskList
Definition: ramdisk.c:83
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:402
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define DPRINT1
Definition: precomp.h:8
#define IRP_MJ_READ
Definition: rdpdr.c:46
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:493
NTSTATUS NTAPI RamdiskSetPartitionInfo(IN PIRP Irp, IN PRAMDISK_DRIVE_EXTENSION DeviceExtension)
Definition: ramdisk.c:771
NTSTATUS NTAPI RamdiskOpenClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:1035
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
CHAR PartitionType
Definition: part_xbox.c:33
NTSTATUS NTAPI RamdiskGetPartitionInfo(IN PIRP Irp, IN PRAMDISK_DRIVE_EXTENSION DeviceExtension)
Definition: ramdisk.c:711
struct tagContext Context
Definition: acpixf.h:1030
TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS]
Definition: ntddcdrm.h:166
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
struct _VOLUME_GET_GPT_ATTRIBUTES_INFORMATION VOLUME_GET_GPT_ATTRIBUTES_INFORMATION
BOOLEAN IsWinPEBoot
Definition: ramdisk.c:126
#define FatUnpackBios(Bios, Pbios)
Definition: fat.h:136
PDEVICE_OBJECT RamdiskBusFdo
Definition: ramdisk.c:127
#define IoReleaseRemoveLockAndWait(_RemoveLock, _Tag)
Definition: iofuncs.h:2726
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
struct _RAMDISK_CREATE_INPUT RAMDISK_CREATE_INPUT
#define IOCTL_CDROM_READ_TOC
Definition: ntddcdrm.h:73
#define IRP_MN_CANCEL_STOP_DEVICE
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
ULONG DefaultViewLength
Definition: ramdisk.c:123
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define FILE_DEVICE_BUS_EXTENDER
Definition: winioctl.h:147
IoMarkIrpPending(Irp)
PACKED_BOOT_SECTOR * PPACKED_BOOT_SECTOR
Definition: fat.h:174
#define IOCTL_VOLUME_GET_GPT_ATTRIBUTES
Definition: ntddvol.h:56
#define RAMDISK_MEMORY_MAPPED_DISK
Definition: ntddrdsk.h:51
NTSTATUS NTAPI RamdiskDeleteDiskDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ramdisk.c:1544
struct _RAMDISK_BUS_EXTENSION * PRAMDISK_BUS_EXTENSION
#define IoAcquireRemoveLock(RemoveLock, Tag)
#define BYTE_OFFSET(Va)
INTERFACE_TYPE LegacyBusType
Definition: cmtypes.h:363
UNICODE_STRING DriverRegistryPath
Definition: ramdisk.c:124
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
Iosb Information
Definition: create.c:4377
USHORT SectorsPerTrack
Definition: fat.h:112
LONGLONG QuadPart
Definition: typedefs.h:112
NTSTATUS NTAPI RamdiskIoCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: ramdisk.c:1867
#define IRP_MN_QUERY_CAPABILITIES
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
UCHAR Adr
Definition: ntddcdrm.h:105