ReactOS  0.4.15-dev-1201-gb2cf5a4
create.c File Reference
#include "classp.h"
#include "debug.h"
Include dependency graph for create.c:

Go to the source code of this file.

Macros

#define CLASS_INIT_GUID   0
 

Functions

VOID ClasspCleanupDisableMcn (IN PFILE_OBJECT_EXTENSION FsContext)
 
NTSTATUS NTAPI ClassCreateClose (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS ClasspCreateClose (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID ClasspCleanupProtectedLocks (IN PFILE_OBJECT_EXTENSION FsContext)
 
NTSTATUS ClasspEjectionControl (IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN MEDIA_LOCK_TYPE LockType, IN BOOLEAN Lock)
 
 _IRQL_requires_max_ (PASSIVE_LEVEL)
 

Variables

ULONG BreakOnClose = 0
 
const PCSZ LockTypeStrings []
 

Macro Definition Documentation

◆ CLASS_INIT_GUID

#define CLASS_INIT_GUID   0

Definition at line 24 of file create.c.

Function Documentation

◆ _IRQL_requires_max_()

_IRQL_requires_max_ ( PASSIVE_LEVEL  )

Definition at line 1011 of file create.c.

1018 {
1019  PAGED_CODE();
1020  return GetDictionaryEntry(&(CommonExtension->FileObjectDictionary),
1021  (ULONGLONG) FileObject);
1022 }
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT FileObject
Definition: create.c:4137
PAGED_CODE()
PVOID GetDictionaryEntry(IN PDICTIONARY Dictionary, IN ULONGLONG Key)
Definition: dictlib.c:157
uint64_t ULONGLONG
Definition: typedefs.h:67

◆ ClassCreateClose()

NTSTATUS NTAPI ClassCreateClose ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 57 of file create.c.

81 {
82  PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
83  ULONG removeState;
85 
86  PAGED_CODE();
87 
88  //
89  // If we're getting a close request then we know the device object hasn't
90  // been completely destroyed. Let the driver cleanup if necessary.
91  //
92 
93  removeState = ClassAcquireRemoveLock(DeviceObject, Irp);
94 
95  //
96  // Invoke the device-specific routine, if one exists. Otherwise complete
97  // with SUCCESS
98  //
99 
100  if((removeState == NO_REMOVE) ||
102 
104 
105  if((NT_SUCCESS(status)) &&
106  (commonExtension->DevInfo->ClassCreateClose)) {
107 
108  return commonExtension->DevInfo->ClassCreateClose(DeviceObject, Irp);
109  }
110 
111  } else {
113  }
114 
115  Irp->IoStatus.Status = status;
118  return status;
119 }
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
NTSTATUS ClasspCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: create.c:123
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:100
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
PCLASS_CREATE_CLOSE ClassCreateClose
Definition: classpnp.h:526
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
PAGED_CODE()
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NO_REMOVE
Definition: classpnp.h:96
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
PCLASS_DEV_INFO DevInfo
Definition: classpnp.h:620
#define IS_CLEANUP_REQUEST(majorFunction)
Definition: classpnp.h:30
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
VOID NTAPI ClassCompleteRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ CCHAR PriorityBoost)
Definition: lock.c:401
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by ClassInitializeDispatchTables().

◆ ClasspCleanupDisableMcn()

VOID ClasspCleanupDisableMcn ( IN PFILE_OBJECT_EXTENSION  FsContext)

Definition at line 434 of file create.c.

437 {
438  PCOMMON_DEVICE_EXTENSION commonExtension =
439  FsContext->DeviceObject->DeviceExtension;
440 
441  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension =
442  commonExtension->PartitionZeroExtension;
443 
444  PAGED_CODE();
445 
446  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_MCN,
447  "ClasspCleanupDisableMcn called for %p\n",
448  FsContext->DeviceObject));
449  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_MCN,
450  "ClasspCleanupDisableMcn - FsContext %p is disabled "
451  "%d times\n", FsContext, FsContext->McnDisableCount));
452 
453  //
454  // For each secure lock on this handle decrement the secured lock count
455  // for the FDO. Keep track of the new value.
456  //
457 
458  while(FsContext->McnDisableCount != 0) {
459  FsContext->McnDisableCount--;
460  ClassEnableMediaChangeDetection(fdoExtension);
461  }
462 
463  return;
464 }
_Inout_ PLIST_ENTRY _In_ PVOID FsContext
Definition: fltkernel.h:2239
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
PAGED_CODE()

Referenced by ClasspCreateClose().

◆ ClasspCleanupProtectedLocks()

VOID ClasspCleanupProtectedLocks ( IN PFILE_OBJECT_EXTENSION  FsContext)

Definition at line 296 of file create.c.

299 {
300  PCOMMON_DEVICE_EXTENSION commonExtension =
301  FsContext->DeviceObject->DeviceExtension;
302 
303  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension =
304  commonExtension->PartitionZeroExtension;
305 
306  ULONG newDeviceLockCount = 1;
307 
308  PAGED_CODE();
309 
310  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
311  "ClasspCleanupProtectedLocks called for %p\n",
312  FsContext->DeviceObject));
313  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
314  "ClasspCleanupProtectedLocks - FsContext %p is locked "
315  "%d times\n", FsContext, FsContext->LockCount));
316 
318 
319  //
320  // Synchronize with ejection and ejection control requests.
321  //
322 
325  UserRequest,
326  KernelMode,
327  FALSE,
328  NULL);
329 
330  //
331  // For each secure lock on this handle decrement the secured lock count
332  // for the FDO. Keep track of the new value.
333  //
334 
335  if (FsContext->LockCount != 0) {
336 
337  do {
338 
339  InterlockedDecrement((volatile LONG *)&FsContext->LockCount);
340 
341  newDeviceLockCount =
343 
344  } while (FsContext->LockCount > 0);
345 
346  //
347  // If the new lock count has been dropped to zero then issue a lock
348  // command to the device.
349  //
350 
351  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
352  "ClasspCleanupProtectedLocks: FDO secured lock count = %d "
353  "lock count = %d\n",
354  fdoExtension->ProtectedLockCount,
355  fdoExtension->LockCount));
356 
357  if ((newDeviceLockCount == 0) && (fdoExtension->LockCount == 0)) {
358 
359  SCSI_REQUEST_BLOCK srb = {0};
360  UCHAR srbExBuffer[CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE] = {0};
361  PSTORAGE_REQUEST_BLOCK srbEx = (PSTORAGE_REQUEST_BLOCK)srbExBuffer;
362  PCDB cdb = NULL;
364  PSCSI_REQUEST_BLOCK srbPtr;
365 
366  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
367  "ClasspCleanupProtectedLocks: FDO lock count dropped "
368  "to zero\n"));
369 
370  if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
371 #ifdef _MSC_VER
372  #pragma prefast(suppress:26015, "InitializeStorageRequestBlock ensures buffer access is bounded")
373 #endif
376  sizeof(srbExBuffer),
377  1,
379  if (NT_SUCCESS(status)) {
380  srbEx->TimeOutValue = fdoExtension->TimeOutValue;
381  SrbSetCdbLength(srbEx, 6);
382  cdb = SrbGetCdb(srbEx);
383  srbPtr = (PSCSI_REQUEST_BLOCK)srbEx;
384  } else {
385  //
386  // Should not happen. Revert to legacy SRB.
387  //
388  NT_ASSERT(FALSE);
389  srb.TimeOutValue = fdoExtension->TimeOutValue;
390  srb.CdbLength = 6;
391  cdb = (PCDB) &(srb.Cdb);
392  srbPtr = &srb;
393  }
394 
395  } else {
396 
397  srb.TimeOutValue = fdoExtension->TimeOutValue;
398  srb.CdbLength = 6;
399  cdb = (PCDB) &(srb.Cdb);
400  srbPtr = &srb;
401 
402  }
403 
404  cdb->MEDIA_REMOVAL.OperationCode = SCSIOP_MEDIUM_REMOVAL;
405 
406  //
407  // TRUE - prevent media removal.
408  // FALSE - allow media removal.
409  //
410 
411  cdb->MEDIA_REMOVAL.Prevent = FALSE;
412 
414  srbPtr,
415  NULL,
416  0,
417  FALSE);
418 
419  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
420  "ClasspCleanupProtectedLocks: unlock request to drive "
421  "returned status %lx\n", status));
422  }
423  }
424 
425  KeSetEvent(&fdoExtension->EjectSynchronizationEvent,
427  FALSE);
429  return;
430 }
_Inout_ PLIST_ENTRY _In_ PVOID FsContext
Definition: fltkernel.h:2239
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
UCHAR Cdb[16]
Definition: srb.h:271
struct _CDB::_MEDIA_REMOVAL MEDIA_REMOVAL
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
NTSTATUS InitializeStorageRequestBlock(_Inout_bytecount_(ByteSize) PSTORAGE_REQUEST_BLOCK Srb, _In_ USHORT AddressType, _In_ ULONG ByteSize, _In_ ULONG NumSrbExData,...)
Definition: srblib.c:206
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
UCHAR CdbLength
Definition: srb.h:250
FORCEINLINE PCDB SrbGetCdb(_In_ PVOID Srb)
Definition: srbhelper.h:583
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
ULONG TimeOutValue
Definition: srb.h:254
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
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
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
#define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE
Definition: classpnp.h:695
smooth NULL
Definition: ftsmooth.c:416
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
union _CDB * PCDB
PAGED_CODE()
FORCEINLINE VOID SrbSetCdbLength(_In_ PVOID Srb, _In_ UCHAR CdbLength)
Definition: srbhelper.h:1093
NTSTATUS NTAPI ClassSendSrbSynchronous(_In_ PDEVICE_OBJECT Fdo, _Inout_ PSCSI_REQUEST_BLOCK _Srb, _In_reads_bytes_opt_(BufferLength) PVOID BufferAddress, _In_ ULONG BufferLength, _In_ BOOLEAN WriteToDevice)
Definition: class.c:4042
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG BreakOnClose
Definition: create.c:32
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
#define STORAGE_ADDRESS_TYPE_BTL8
Definition: srb.h:657
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:871
unsigned char UCHAR
Definition: xmlstorage.h:181
#define InterlockedDecrement
Definition: armddk.h:52
#define SCSIOP_MEDIUM_REMOVAL
Definition: cdrw_hw.h:902
#define VOID
Definition: acefi.h:82
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
static SERVICE_STATUS status
Definition: service.c:31
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

Referenced by ClasspCreateClose().

◆ ClasspCreateClose()

NTSTATUS ClasspCreateClose ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 123 of file create.c.

148 {
149  PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
151 
152  PFILE_OBJECT fileObject = irpStack->FileObject;
153 
155 
156  PAGED_CODE();
157 
158 
159  //
160  // ISSUE-2000/3/28-henrygab - if lower stack fails create/close, we end up
161  // in an inconsistent state. re-write to verify all args and allocate all
162  // required resources, then pass the irp down, then complete the
163  // transaction. this is because we also cannot forward the irp, then fail
164  // it after it has succeeded a lower-level driver.
165  //
166 
167  if(irpStack->MajorFunction == IRP_MJ_CREATE) {
168 
169  PIO_SECURITY_CONTEXT securityContext =
170  irpStack->Parameters.Create.SecurityContext;
171  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
172  "ClasspCREATEClose: create received for device %p\n",
173  DeviceObject));
174  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
175  "ClasspCREATEClose: desired access %lx\n",
176  securityContext->DesiredAccess));
177  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
178  "ClasspCREATEClose: file object %p\n",
179  irpStack->FileObject));
180 
182 
183  if(irpStack->FileObject != NULL) {
184 
185  PFILE_OBJECT_EXTENSION fsContext;
186 
187  //
188  // Allocate our own file object extension for this device object.
189  //
190 
192  &commonExtension->FileObjectDictionary,
193  (ULONGLONG) irpStack->FileObject,
194  sizeof(FILE_OBJECT_EXTENSION),
196  (PVOID *)&fsContext);
197 
198  if(NT_SUCCESS(status)) {
199 
200  RtlZeroMemory(fsContext,
201  sizeof(FILE_OBJECT_EXTENSION));
202 
203  fsContext->FileObject = irpStack->FileObject;
204  fsContext->DeviceObject = DeviceObject;
205  } else if (status == STATUS_OBJECT_NAME_COLLISION) {
207  }
208  }
209 
210  } else {
211 
212  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
213  "ClasspCreateCLOSE: close received for device %p\n",
214  DeviceObject));
215  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
216  "ClasspCreateCLOSE: file object %p\n",
217  fileObject));
218 
219  if(irpStack->FileObject != NULL) {
220 
221  PFILE_OBJECT_EXTENSION fsContext =
222  ClassGetFsContext(commonExtension, irpStack->FileObject);
223 
224  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
225  "ClasspCreateCLOSE: file extension %p\n",
226  fsContext));
227 
228  if(fsContext != NULL) {
229 
230  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
231  "ClasspCreateCLOSE: extension is ours - "
232  "freeing\n"));
234 
235  ClasspCleanupProtectedLocks(fsContext);
236 
237  ClasspCleanupDisableMcn(fsContext);
238 
239  FreeDictionaryEntry(&(commonExtension->FileObjectDictionary),
240  fsContext);
241  }
242  }
243  }
244 
245  //
246  // Notify the lower levels about the create or close operation - give them
247  // a chance to cleanup too.
248  //
249 
250  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
251  "ClasspCreateClose: %s for devobj %p\n",
252  (NT_SUCCESS(status) ? "Success" : "FAILED"),
253  DeviceObject));
254 
255 
256  if(NT_SUCCESS(status)) {
257 
258  KEVENT event;
259 
260  //
261  // Set up the event to wait on
262  //
263 
265 
268  TRUE, TRUE, TRUE);
269 
270  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
271 
272  if(status == STATUS_PENDING) {
274  Executive,
275  KernelMode,
276  FALSE,
277  NULL);
278  status = Irp->IoStatus.Status;
279  }
280 
281  if (!NT_SUCCESS(status)) {
282  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_INIT,
283  "ClasspCreateClose: Lower driver failed, but we "
284  "succeeded. This is a problem, lock counts will be "
285  "out of sync between levels.\n"));
286  }
287 
288  }
289 
290 
291  return status;
292 }
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
VOID ClasspCleanupProtectedLocks(IN PFILE_OBJECT_EXTENSION FsContext)
Definition: create.c:296
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
VOID FreeDictionaryEntry(IN PDICTIONARY Dictionary, IN PVOID Entry)
Definition: dictlib.c:189
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
ACCESS_MASK DesiredAccess
Definition: iotypes.h:2847
IO_COMPLETION_ROUTINE ClassSignalCompletion
Definition: classpnp.h:1330
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS AllocateDictionaryEntry(IN PDICTIONARY Dictionary, IN ULONGLONG Key, IN ULONG Size, IN ULONG Tag, OUT PVOID *Entry)
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:550
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
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2864
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
PAGED_CODE()
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
ULONG BreakOnClose
Definition: create.c:32
uint64_t ULONGLONG
Definition: typedefs.h:67
* PFILE_OBJECT
Definition: iotypes.h:1978
#define CLASS_TAG_FILE_OBJECT_EXTENSION
Definition: classpnp.h:78
#define VOID
Definition: acefi.h:82
struct _cl_event * event
Definition: glext.h:7739
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
PFILE_OBJECT FileObject
Definition: iotypes.h:3148
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:598
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
DICTIONARY FileObjectDictionary
Definition: classpnp.h:631
VOID ClasspCleanupDisableMcn(IN PFILE_OBJECT_EXTENSION FsContext)
Definition: create.c:434
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
PFILE_OBJECT FileObject
Definition: classpnp.h:549
static SERVICE_STATUS status
Definition: service.c:31
HRESULT Create([out]ITransactionReceiver **ppReceiver)
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

Referenced by ClassCreateClose().

◆ ClasspEjectionControl()

NTSTATUS ClasspEjectionControl ( IN PDEVICE_OBJECT  Fdo,
IN PIRP  Irp,
IN MEDIA_LOCK_TYPE  LockType,
IN BOOLEAN  Lock 
)

Definition at line 474 of file create.c.

480 {
481  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension = Fdo->DeviceExtension;
482  PCOMMON_DEVICE_EXTENSION commonExtension =
484 
485  PFILE_OBJECT_EXTENSION fsContext = NULL;
488  BOOLEAN countChanged = FALSE;
489 
490  PAGED_CODE();
491 
492  /*
493  * Ensure that the user thread is not suspended while we are holding EjectSynchronizationEvent.
494  */
496 
498  &(FdoExtension->EjectSynchronizationEvent),
499  UserRequest,
500  KernelMode,
501  FALSE,
502  NULL);
503 
505 
506  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
507  "ClasspEjectionControl: "
508  "Received request for %s lock type\n",
510  ));
511 
512  _SEH2_TRY {
513  PCDB cdb = NULL;
514 
515  //
516  // Determine if this is a "secured" request.
517  //
518 
519  if (LockType == SecureMediaLock) {
520 
522  PFILE_OBJECT fileObject = irpStack->FileObject;
523 
524  //
525  // Make sure that the file object we are supplied has a
526  // proper FsContext before we try doing a secured lock.
527  //
528 
529  if (fileObject != NULL) {
530  fsContext = ClassGetFsContext(commonExtension, fileObject);
531  }
532 
533  if (fsContext == NULL) {
534 
535  //
536  // This handle isn't setup correctly. We can't let the
537  // operation go.
538  //
539 
541  _SEH2_LEAVE;
542  }
543  }
544 
545  if (Lock) {
546 
547  //
548  // This is a lock command. Reissue the command in case bus or
549  // device was reset and the lock was cleared.
550  // note: may need to decrement count if actual lock operation
551  // failed....
552  //
553 
554  switch (LockType) {
555 
556  case SimpleMediaLock: {
557  FdoExtension->LockCount++;
558  countChanged = TRUE;
559  break;
560  }
561 
562  case SecureMediaLock: {
563  fsContext->LockCount++;
564  FdoExtension->ProtectedLockCount++;
565  countChanged = TRUE;
566  break;
567  }
568 
569  case InternalMediaLock: {
570  FdoExtension->InternalLockCount++;
571  countChanged = TRUE;
572  break;
573  }
574  }
575 
576  } else {
577 
578  //
579  // This is an unlock command. If it's a secured one then make sure
580  // the caller has a lock outstanding or return an error.
581  // note: may need to re-increment the count if actual unlock
582  // operation fails....
583  //
584 
585  switch (LockType) {
586 
587  case SimpleMediaLock: {
588  if(FdoExtension->LockCount != 0) {
589  FdoExtension->LockCount--;
590  countChanged = TRUE;
591  }
592  break;
593  }
594 
595  case SecureMediaLock: {
596  if(fsContext->LockCount == 0) {
598  _SEH2_LEAVE;
599  }
600  fsContext->LockCount--;
601  FdoExtension->ProtectedLockCount--;
602  countChanged = TRUE;
603  break;
604  }
605 
606  case InternalMediaLock: {
607  NT_ASSERT(FdoExtension->InternalLockCount != 0);
608  FdoExtension->InternalLockCount--;
609  countChanged = TRUE;
610  break;
611  }
612  }
613 
614  //
615  // We only send an unlock command to the drive if both the
616  // secured and unsecured lock counts have dropped to zero.
617  //
618 
619  if ((FdoExtension->ProtectedLockCount != 0) ||
620  (FdoExtension->InternalLockCount != 0) ||
621  (FdoExtension->LockCount != 0)) {
622 
624  _SEH2_LEAVE;
625  }
626  }
627 
629  if (TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
630 
632 
633  if (srb == NULL) {
635  _SEH2_LEAVE;
636  }
637 
638  if (FdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
639 
640  //
641  // NOTE - this is based on size used in ClasspAllocateSrb
642  //
643 
647  1,
649  if (!NT_SUCCESS(status)) {
650  NT_ASSERT(FALSE);
651  _SEH2_LEAVE;
652  }
653 
654  } else {
655  RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
656  }
657 
658  SrbSetCdbLength(srb, 6);
659  cdb = SrbGetCdb(srb);
660  NT_ASSERT(cdb != NULL);
661 
662  cdb->MEDIA_REMOVAL.OperationCode = SCSIOP_MEDIUM_REMOVAL;
663 
664  //
665  // TRUE - prevent media removal.
666  // FALSE - allow media removal.
667  //
668 
669  cdb->MEDIA_REMOVAL.Prevent = Lock;
670 
671  //
672  // Set timeout value.
673  //
674 
675  SrbSetTimeOutValue(srb, FdoExtension->TimeOutValue);
676 
677  //
678  // The actual lock operation on the device isn't so important
679  // as the internal lock counts. Ignore failures.
680  //
681 
683  srb,
684  NULL,
685  0,
686  FALSE);
687  }
688 
689  } _SEH2_FINALLY {
690 
691  if (!NT_SUCCESS(status)) {
692  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
693  "ClasspEjectionControl: FAILED status %x -- "
694  "reverting lock counts\n", status));
695 
696  if (countChanged) {
697 
698  //
699  // have to revert to previous counts if the
700  // lock/unlock operation actually failed.
701  //
702 
703  if (Lock) {
704 
705  switch (LockType) {
706 
707  case SimpleMediaLock: {
708  FdoExtension->LockCount--;
709  break;
710  }
711 
712  case SecureMediaLock: {
713  fsContext->LockCount--;
714  FdoExtension->ProtectedLockCount--;
715  break;
716  }
717 
718  case InternalMediaLock: {
719  FdoExtension->InternalLockCount--;
720  break;
721  }
722  }
723 
724  } else {
725 
726  switch (LockType) {
727 
728  case SimpleMediaLock: {
729  FdoExtension->LockCount++;
730  break;
731  }
732 
733  case SecureMediaLock: {
734  fsContext->LockCount++;
735  FdoExtension->ProtectedLockCount++;
736  break;
737  }
738 
739  case InternalMediaLock: {
740  FdoExtension->InternalLockCount++;
741  break;
742  }
743  }
744  }
745 
746  }
747 
748  } else {
749 
750  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
751  "ClasspEjectionControl: Succeeded\n"));
752 
753  }
754 
755  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
756  "ClasspEjectionControl: "
757  "Current Counts: Internal: %x Secure: %x Simple: %x\n",
758  FdoExtension->InternalLockCount,
759  FdoExtension->ProtectedLockCount,
760  FdoExtension->LockCount
761  ));
762 
763  KeSetEvent(&(FdoExtension->EjectSynchronizationEvent),
765  FALSE);
767 
768  if (srb) {
770  }
771 
772  } _SEH2_END;
773  return status;
774 }
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _CDB::_MEDIA_REMOVAL MEDIA_REMOVAL
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS InitializeStorageRequestBlock(_Inout_bytecount_(ByteSize) PSTORAGE_REQUEST_BLOCK Srb, _In_ USHORT AddressType, _In_ ULONG ByteSize, _In_ ULONG NumSrbExData,...)
Definition: srblib.c:206
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE PCDB SrbGetCdb(_In_ PVOID Srb)
Definition: srbhelper.h:583
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
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
_SEH2_TRY
Definition: create.c:4226
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define FALSE
Definition: types.h:117
#define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE
Definition: classpnp.h:695
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
PAGED_CODE()
FORCEINLINE VOID SrbSetCdbLength(_In_ PVOID Srb, _In_ UCHAR CdbLength)
Definition: srbhelper.h:1093
NTSTATUS NTAPI ClassSendSrbSynchronous(_In_ PDEVICE_OBJECT Fdo, _Inout_ PSCSI_REQUEST_BLOCK _Srb, _In_reads_bytes_opt_(BufferLength) PVOID BufferAddress, _In_ ULONG BufferLength, _In_ BOOLEAN WriteToDevice)
Definition: class.c:4042
#define ClasspAllocateSrb(ext)
Definition: classpnp.h:146
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FORCEINLINE VOID SrbSetTimeOutValue(_In_ PVOID Srb, _In_ ULONG TimeOutValue)
Definition: srbhelper.h:821
struct _COMMON_DEVICE_EXTENSION * PCOMMON_DEVICE_EXTENSION
_In_ WDFREQUEST _In_ MEDIA_LOCK_TYPE LockType
Definition: cdrom.h:1334
#define STORAGE_ADDRESS_TYPE_BTL8
Definition: srb.h:657
* PFILE_OBJECT
Definition: iotypes.h:1978
#define SCSIOP_MEDIUM_REMOVAL
Definition: cdrw_hw.h:902
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
PFILE_OBJECT FileObject
Definition: iotypes.h:3148
_SEH2_END
Definition: create.c:4400
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
VOID ClassFreeOrReuseSrb(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN __drv_freesMem(mem) PSCSI_REQUEST_BLOCK Srb)
Definition: obsolete.c:882
_SEH2_FINALLY
Definition: create.c:4371
const PCSZ LockTypeStrings[]
Definition: create.c:34
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define _SEH2_LEAVE
Definition: filesup.c:20
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

Referenced by ClassDeviceControl(), and ClassDispatchPnp().

Variable Documentation

◆ BreakOnClose

ULONG BreakOnClose = 0

Definition at line 32 of file create.c.

Referenced by ClasspCleanupProtectedLocks(), and ClasspCreateClose().

◆ LockTypeStrings

const PCSZ LockTypeStrings[]
Initial value:
= {
"Simple",
"Secure",
"Internal"
}

Definition at line 34 of file create.c.

Referenced by ClasspEjectionControl().