ReactOS  0.4.15-dev-1384-g878186b
vfdimg.c File Reference
#include "imports.h"
#include "vfddrv.h"
#include "vfddbg.h"
Include dependency graph for vfdimg.c:

Go to the source code of this file.

Functions

NTSTATUS VfdOpenCheck (PDEVICE_EXTENSION DeviceExtension, PVFD_IMAGE_INFO ImageInfo, ULONG InputLength)
 
NTSTATUS VfdOpenImage (IN PDEVICE_EXTENSION DeviceExtension, IN PVFD_IMAGE_INFO ImageInfo)
 
VOID VfdCloseImage (IN PDEVICE_EXTENSION DeviceExtension)
 
NTSTATUS VfdQueryImage (IN PDEVICE_EXTENSION DeviceExtension, OUT PVFD_IMAGE_INFO ImageInfo, IN ULONG BufferLength, OUT PULONG ReturnLength)
 

Function Documentation

◆ VfdCloseImage()

VOID VfdCloseImage ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 435 of file vfdimg.c.

437 {
438  VFDTRACE(0, ("[VFD] VfdCloseImage - IN\n"));
439 
440  ASSERT(DeviceExtension);
441 
442  DeviceExtension->MediaType = VFD_MEDIA_NONE;
443  DeviceExtension->MediaFlags = 0;
444  DeviceExtension->FileType = 0;
445  DeviceExtension->ImageSize = 0;
446  DeviceExtension->FileName.Length = 0;
447  DeviceExtension->Sectors = 0;
448 
449  if (DeviceExtension->FileHandle) {
450  ZwClose(DeviceExtension->FileHandle);
451  DeviceExtension->FileHandle = NULL;
452  }
453 
454  if (DeviceExtension->FileBuffer) {
455  ExFreePool(DeviceExtension->FileBuffer);
456  DeviceExtension->FileBuffer = NULL;
457  }
458 
459  VFDTRACE(0, ("[VFD] VfdCloseImage - OUT\n"));
460 }
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define ASSERT(a)
Definition: mode.c:45
#define VFDTRACE(LEVEL, STRING)
Definition: vfddbg.h:72
#define NULL
Definition: types.h:112
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by Close(), VfdGuiClose(), and VfdIoCtlThread().

◆ VfdOpenCheck()

NTSTATUS VfdOpenCheck ( PDEVICE_EXTENSION  DeviceExtension,
PVFD_IMAGE_INFO  ImageInfo,
ULONG  InputLength 
)

Definition at line 25 of file vfdimg.c.

29 {
30  // Check media status
31 
32  if (DeviceExtension->FileHandle ||
33  DeviceExtension->FileBuffer) {
34 
35  VFDTRACE(VFDWARN, ("[VFD] image already opened.\n"));
36 
37  return STATUS_DEVICE_BUSY;
38  }
39 
40  // Check input parameter length
41 
42  if (InputLength < sizeof(VFD_IMAGE_INFO) ||
43  InputLength < sizeof(VFD_IMAGE_INFO) + ImageInfo->NameLength)
44  {
46  }
47 
48  // Check input parameters
49 
50  if (ImageInfo->MediaType == VFD_MEDIA_NONE ||
51  ImageInfo->MediaType >= VFD_MEDIA_MAX) {
52 
53  VFDTRACE(VFDWARN, ("[VFD] invalid MediaType - %u.\n",
54  ImageInfo->MediaType));
55 
57  }
58 
59  if (ImageInfo->DiskType == VFD_DISKTYPE_FILE &&
60  ImageInfo->NameLength == 0) {
61 
62  VFDTRACE(VFDWARN,
63  ("[VFD] File name required for VFD_DISKTYPE_FILE.\n"));
64 
66  }
67 
68  // create a security context to match the calling process' context
69  // the driver thread uses this context to impersonate the client
70  // to open the specified image file
71 
72 // if (ImageInfo->DiskType == VFD_DISKTYPE_FILE)
73  {
75 
76  if (DeviceExtension->SecurityContext != NULL) {
77  SeDeleteClientSecurity(DeviceExtension->SecurityContext);
78  }
79  else {
80  DeviceExtension->SecurityContext =
83  }
84 
86 
87  sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
90  sqos.EffectiveOnly = FALSE;
91 
93  PsGetCurrentThread(), &sqos, FALSE,
94  DeviceExtension->SecurityContext);
95  }
96 
97  return STATUS_SUCCESS;
98 }
VFD_DISKTYPE DiskType
Definition: vfdio.h:64
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
VFD_MEDIA MediaType
Definition: vfdio.h:65
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
#define FALSE
Definition: types.h:117
#define SeDeleteClientSecurity(C)
Definition: imports.h:320
struct _SECURITY_CLIENT_CONTEXT * PSECURITY_CLIENT_CONTEXT
NTKERNELAPI NTSTATUS NTAPI SeCreateClientSecurity(IN PETHREAD Thread, IN PSECURITY_QUALITY_OF_SERVICE QualityOfService, IN BOOLEAN RemoteClient, OUT PSECURITY_CLIENT_CONTEXT ClientContext)
Definition: access.c:506
#define VFDTRACE(LEVEL, STRING)
Definition: vfddbg.h:72
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define VFD_POOL_TAG
Definition: vfddrv.h:25
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
#define SECURITY_STATIC_TRACKING
Definition: setypes.h:104
struct _SECURITY_QUALITY_OF_SERVICE SECURITY_QUALITY_OF_SERVICE
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
#define NULL
Definition: types.h:112
USHORT NameLength
Definition: vfdio.h:69
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65

◆ VfdOpenImage()

NTSTATUS VfdOpenImage ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PVFD_IMAGE_INFO  ImageInfo 
)

Definition at line 104 of file vfdimg.c.

107 {
110  const DISK_GEOMETRY *geometry;
111  ULONG sectors;
112  ULONG alignment;
113 
114  VFDTRACE(0, ("[VFD] VfdOpenImage - IN\n"));
115 
116  //
117  // Store file name in the device extension
118  //
119  if (ImageInfo->NameLength) {
120 
121  if (ImageInfo->NameLength + 1 >
122  DeviceExtension->FileName.MaximumLength) {
123 
124  // expand the filename buffer
125 
126  if (DeviceExtension->FileName.Buffer) {
127  ExFreePool(DeviceExtension->FileName.Buffer);
129  &DeviceExtension->FileName,
130  sizeof(ANSI_STRING));
131  }
132 
133  DeviceExtension->FileName.Buffer = (PCHAR)ExAllocatePoolWithTag(
134  NonPagedPool, ImageInfo->NameLength + 1, VFD_POOL_TAG);
135 
136  if (!DeviceExtension->FileName.Buffer) {
137  VFDTRACE(0, ("[VFD] Can't allocate memory for image path\n"));
139  }
140 
141  DeviceExtension->FileName.MaximumLength
142  = (USHORT)(ImageInfo->NameLength + 1);
143 
145  DeviceExtension->FileName.Buffer,
146  DeviceExtension->FileName.MaximumLength);
147  }
148 
149  if (DeviceExtension->FileName.Buffer) {
151  DeviceExtension->FileName.Buffer,
152  ImageInfo->FileName,
153  ImageInfo->NameLength);
154 
155  DeviceExtension->FileName.Buffer[ImageInfo->NameLength] = '\0';
156  }
157  }
158 
159  DeviceExtension->FileName.Length = ImageInfo->NameLength;
160 
161  //
162  // Get DISK_GEOMETRY and calculate the media capacity
163  // -- validity of the ImageInfo->MediaType value is assured in
164  // the VfdOpenCheck function
165  //
166  geometry = &geom_tbl[ImageInfo->MediaType];
167 
168  sectors =
169  geometry->Cylinders.LowPart *
170  geometry->TracksPerCylinder *
171  geometry->SectorsPerTrack;
172 
173  if (ImageInfo->ImageSize != 0 &&
174  ImageInfo->ImageSize < VFD_SECTOR_TO_BYTE(sectors)) {
175 
176  VFDTRACE(0, ("[VFD] Image is smaller than the media\n"));
178  }
179 
180  //
181  // Prepare a virtual media according to the ImageInfo
182  //
183  if (ImageInfo->DiskType == VFD_DISKTYPE_FILE) {
184  //
185  // open an existing image file
186  //
188  OBJECT_ATTRIBUTES attributes;
189  UNICODE_STRING unicode_name;
190  FILE_STANDARD_INFORMATION file_standard;
191  FILE_BASIC_INFORMATION file_basic;
192  FILE_ALIGNMENT_INFORMATION file_alignment;
193  PFILE_OBJECT file_object;
194  BOOLEAN network_drive;
195 
196  // convert the filename into a unicode string
197 
199  &unicode_name, &DeviceExtension->FileName, TRUE);
200 
201  if (!NT_SUCCESS(status)) {
202  VFDTRACE(0, ("[VFD] Failed to convert filename to UNICODE\n"));
203  return status;
204  }
205 
206  VFDTRACE(VFDINFO,
207  ("[VFD] Opening %s\n", DeviceExtension->FileName.Buffer));
208 
209  // prepare an object attribute to open
210 
212  &attributes,
213  &unicode_name,
215  NULL,
216  NULL);
217 
218  // open the target file
219 
220  status = ZwCreateFile(
221  &file_handle,
223  &attributes,
224  &io_status,
225  NULL,
227  0,
228  FILE_OPEN,
233  NULL,
234  0);
235 
236  RtlFreeUnicodeString(&unicode_name);
237 
238  if (!NT_SUCCESS(status)) {
239  VFDTRACE(0, ("[VFD] ZwCreateFile - %s\n",
240  GetStatusName(status)));
241  return status;
242  }
243 
244  // Check the file size
245 
246  status = ZwQueryInformationFile(
247  file_handle,
248  &io_status,
249  &file_standard,
252 
253  if (!NT_SUCCESS(status)) {
254  VFDTRACE(0,
255  ("[VFD] ZwQueryInformationFile - FILE_STANDARD_INFORMATION\n"));
256 
258  goto exit_func;
259  }
260 
261  // Actual file size can be larger than the media capacity
262 
263  if (file_standard.EndOfFile.QuadPart < VFD_SECTOR_TO_BYTE(sectors)) {
264 
265  VFDTRACE(0, ("[VFD] file is smaller than the media.\n"));
266 
268 
270  goto exit_func;
271  }
272 
273  DeviceExtension->ImageSize = file_standard.EndOfFile.LowPart;
274 
275  // Find out whether the file is on a local disk or a network drive
276 
277  network_drive = FALSE;
278 
280  file_handle,
281  GENERIC_READ,
282  NULL,
283  KernelMode,
284 #ifndef __REACTOS__
285  &file_object,
286 #else
287  (PVOID *)&file_object,
288 #endif
289  NULL);
290 
291  if (NT_SUCCESS(status)) {
292  if (file_object && file_object->DeviceObject) {
293  VFDTRACE(VFDINFO, ("[VFD] Device type is 0x%08x\n",
294  file_object->DeviceObject->DeviceType));
295 
296  if (file_object->DeviceObject->DeviceType
298  network_drive = TRUE;
299  }
300 
301  // how about these types ?
302  // FILE_DEVICE_NETWORK
303  // FILE_DEVICE_NETWORK_BROWSER
304  // FILE_DEVICE_NETWORK_REDIRECTOR
305  }
306  else {
307  VFDTRACE(VFDWARN, ("[VFD Cannot decide the device type\n"));
308  }
309  ObDereferenceObject(file_object);
310  }
311  else {
312  VFDTRACE(0, ("[VFD] ObReferenceObjectByHandle - %s\n",
313  GetStatusName(status)));
314  }
315 
316  if (!network_drive) {
317  // The NT cache manager can deadlock if a filesystem that is using
318  // the cache manager is used in a virtual disk that stores its file
319  // on a file systemthat is also using the cache manager, this is
320  // why we open the file with FILE_NO_INTERMEDIATE_BUFFERING above,
321  // however if the file is compressed or encrypted NT will not honor
322  // this request and cache it anyway since it need to store the
323  // decompressed/unencrypted data somewhere, therefor we put an
324  // extra check here and don't alow disk images to be compressed/
325  // encrypted.
326 
327  status = ZwQueryInformationFile(
328  file_handle,
329  &io_status,
330  &file_basic,
331  sizeof(FILE_BASIC_INFORMATION),
333 
334  if (!NT_SUCCESS(status)) {
335  VFDTRACE(0,
336  ("[VFD] ZwQueryInformationFile - FILE_BASIC_INFORMATION\n"));
337 
339  goto exit_func;
340  }
341 
342  if (file_basic.FileAttributes
344  {
345  VFDTRACE(0,
346  ("[VFD] Image file is compressed and/or encrypted\n"));
347 
349 
351  goto exit_func;
352  }
353  }
354 
355  // Retrieve the file alignment requirement
356 
357  status = ZwQueryInformationFile(
358  file_handle,
359  &io_status,
360  &file_alignment,
363 
364  if (!NT_SUCCESS(status)) {
365  VFDTRACE(0,
366  ("[VFD] ZwQueryInformationFile - FILE_ALIGNMENT_INFORMATION\n"));
367 
369  goto exit_func;
370  }
371 
372  DeviceExtension->FileHandle = file_handle;
373 
374  alignment = file_alignment.AlignmentRequirement;
375 
376  VFDTRACE(0, ("[VFD] Opened an image file\n"));
377  }
378  else {
379  //
380  // Create an empty RAM disk
381  //
382  DeviceExtension->FileBuffer = (PUCHAR)ExAllocatePoolWithTag(
383  NonPagedPool,
385  VFD_POOL_TAG);
386 
387  if (!DeviceExtension->FileBuffer) {
388  VFDTRACE(0, ("[VFD] Can't allocate memory for RAM disk\n"));
390  }
391 
393  DeviceExtension->FileBuffer,
395 
396  if (ImageInfo->ImageSize) {
397  DeviceExtension->ImageSize = ImageInfo->ImageSize;
398  }
399  else {
400  DeviceExtension->ImageSize = VFD_SECTOR_TO_BYTE(sectors);
401  }
402 
403  alignment = FILE_WORD_ALIGNMENT;
404 
405  VFDTRACE(0, ("[VFD] Created an empty RAM disk\n"));
406  }
407 
408  DeviceExtension->MediaChangeCount++;
409 
410  DeviceExtension->MediaType = ImageInfo->MediaType;
411  DeviceExtension->MediaFlags = ImageInfo->MediaFlags;
412  DeviceExtension->FileType = ImageInfo->FileType;
413  DeviceExtension->Geometry = geometry;
414  DeviceExtension->Sectors = sectors;
415 
416  VFDTRACE(0, ("[VFD] Media:%d Flag:0x%02x Size:%lu Capacity:%lu\n",
417  DeviceExtension->MediaType,
418  DeviceExtension->MediaFlags,
419  DeviceExtension->ImageSize,
420  DeviceExtension->Sectors));
421 
422  DeviceExtension->DeviceObject->AlignmentRequirement
423  = alignment;
424 
425 exit_func:
426  VFDTRACE(0, ("[VFD] VfdOpenImage - %s\n", GetStatusName(status)));
427 
428  return status;
429 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#define VFD_SECTOR_TO_BYTE(s)
Definition: vfdio.h:45
static HANDLE PIO_APC_ROUTINE void PIO_STATUS_BLOCK io_status
Definition: comm.c:54
ULONG TracksPerCylinder
Definition: ntdddisk.h:440
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
#define FALSE
Definition: types.h:117
#define GENERIC_WRITE
Definition: nt_native.h:90
unsigned char BOOLEAN
#define PCHAR
Definition: match.c:90
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:438
ULONG SectorsPerTrack
Definition: ntdddisk.h:441
#define ObDereferenceObject
Definition: obfuncs.h:203
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define VFDTRACE(LEVEL, STRING)
Definition: vfddbg.h:72
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
* PFILE_OBJECT
Definition: iotypes.h:1978
#define FILE_ATTRIBUTE_COMPRESSED
Definition: nt_native.h:711
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
const DISK_GEOMETRY geom_tbl[VFD_MEDIA_MAX]
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
ULONG LowPart
Definition: typedefs.h:106
#define GENERIC_READ
Definition: compat.h:135
#define FILE_WORD_ALIGNMENT
Definition: nt_native.h:787
#define FILE_OPEN
Definition: from_kernel.h:54
#define VFD_POOL_TAG
Definition: vfddrv.h:25
#define FILE_ATTRIBUTE_ENCRYPTED
Definition: ntifs_ex.h:385
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define FILE_RANDOM_ACCESS
Definition: from_kernel.h:38
#define FILE_DEVICE_NETWORK_FILE_SYSTEM
Definition: winioctl.h:125
#define NULL
Definition: types.h:112
__u8 sectors[2]
Definition: mkdosfs.c:366
#define FileStandardInformation
Definition: propsheet.cpp:61
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
static FILE * file_handle
Definition: regtests2xml.c:45
LONGLONG QuadPart
Definition: typedefs.h:114
Definition: ps.c:97

Referenced by CVfdShExt::DoVfdDrop(), OnOK(), Open(), and VfdIoCtlThread().

◆ VfdQueryImage()

NTSTATUS VfdQueryImage ( IN PDEVICE_EXTENSION  DeviceExtension,
OUT PVFD_IMAGE_INFO  ImageInfo,
IN ULONG  BufferLength,
OUT PULONG  ReturnLength 
)

Definition at line 466 of file vfdimg.c.

475 {
476  // Check output buffer length
477 
478  if (BufferLength < sizeof(VFD_IMAGE_INFO)) {
480  }
481 
482  RtlZeroMemory(ImageInfo, BufferLength);
483 
484  // Store fixed length image information
485 
486  ImageInfo->MediaType = DeviceExtension->MediaType;
487 
488  if (DeviceExtension->MediaType == VFD_MEDIA_NONE) {
489  *ReturnLength = sizeof(VFD_IMAGE_INFO);
490  return STATUS_SUCCESS;
491  }
492 
493  if (DeviceExtension->FileBuffer) {
494  ImageInfo->DiskType = VFD_DISKTYPE_RAM;
495  }
496  else {
497  ImageInfo->DiskType = VFD_DISKTYPE_FILE;
498  }
499 
500  ImageInfo->MediaFlags = DeviceExtension->MediaFlags;
501  ImageInfo->FileType = DeviceExtension->FileType;
502  ImageInfo->ImageSize = DeviceExtension->ImageSize;
503 
504  ImageInfo->NameLength = DeviceExtension->FileName.Length;
505 
506  // output buffer is large enough to hold the file name?
507 
508  if (BufferLength < sizeof(VFD_IMAGE_INFO) +
509  DeviceExtension->FileName.Length)
510  {
511  *ReturnLength = sizeof(VFD_IMAGE_INFO);
512  return STATUS_BUFFER_OVERFLOW;
513  }
514 
515  // copy file name
516 
517  if (DeviceExtension->FileName.Length &&
518  DeviceExtension->FileName.Buffer) {
519 
520  RtlCopyMemory(ImageInfo->FileName,
521  DeviceExtension->FileName.Buffer,
522  DeviceExtension->FileName.Length);
523  }
524 
525  // store the actually returned data length
526 
527  *ReturnLength = sizeof(VFD_IMAGE_INFO) +
528  DeviceExtension->FileName.Length;
529 
530  return STATUS_SUCCESS;
531 }
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
struct _VFD_IMAGE_INFO VFD_IMAGE_INFO
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by VfdDeviceControl().