ReactOS  0.4.15-dev-1203-g0e5a4d5
create.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (C) Microsoft Corporation, 1991 - 2010
4 
5 Module Name:
6 
7  class.c
8 
9 Abstract:
10 
11  SCSI class driver routines
12 
13 Environment:
14 
15  kernel mode only
16 
17 Notes:
18 
19 
20 Revision History:
21 
22 --*/
23 
24 #define CLASS_INIT_GUID 0
25 #include "classp.h"
26 #include "debug.h"
27 
28 #ifdef DEBUG_USE_WPP
29 #include "create.tmh"
30 #endif
31 
33 
34 const PCSZ LockTypeStrings[] = {
35  "Simple",
36  "Secure",
37  "Internal"
38 };
39 
40 
41 VOID
44  );
45 
46 #ifdef ALLOC_PRAGMA
47 #pragma alloc_text(PAGE, ClassCreateClose)
48 #pragma alloc_text(PAGE, ClasspCreateClose)
49 #pragma alloc_text(PAGE, ClasspCleanupProtectedLocks)
50 #pragma alloc_text(PAGE, ClasspEjectionControl)
51 #pragma alloc_text(PAGE, ClasspCleanupDisableMcn)
52 #pragma alloc_text(PAGE, ClassGetFsContext)
53 #endif
54 
56 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
59  IN PIRP Irp
60  )
61 
62 /*++
63 
64 Routine Description:
65 
66  SCSI class driver create and close routine. This is called by the I/O system
67  when the device is opened or closed.
68 
69 Arguments:
70 
71  DriverObject - Pointer to driver object created by system.
72 
73  Irp - IRP involved.
74 
75 Return Value:
76 
77  Device-specific drivers return value or STATUS_SUCCESS.
78 
79 --*/
80 
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 }
120 
121 
122 NTSTATUS
125  IN PIRP Irp
126  )
127 /*++
128 
129 Routine Description:
130 
131  This routine will handle create/close operations for a given classpnp
132  device if the class driver doesn't supply it's own handler. If there
133  is a file object supplied for our driver (if it's a FO_DIRECT_DEVICE_OPEN
134  file object) then it will initialize a file extension on create or destroy
135  the extension on a close.
136 
137 Arguments:
138 
139  DeviceObject - the device object being opened or closed.
140 
141  Irp - the create/close irp
142 
143 Return Value:
144 
145  status
146 
147 --*/
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 }
293 
294 
295 VOID
298  )
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 }
431 
432 
433 VOID
436  )
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 }
465 
466 
467 #if 1
468 /*
469  * ISSUE: REMOVE this old function implementation as soon as the
470  * boottime pagefile problems with the new one (below)
471  * are resolved.
472  */
473 NTSTATUS
475  IN PDEVICE_OBJECT Fdo,
476  IN PIRP Irp,
478  IN BOOLEAN Lock
479  )
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 }
775 
776 #else
777 
778 /*
779  * ISSUE: RESTORE this (see above)
780  * This is a new implementation of the function that doesn't thrash memory
781  * or depend on the srbLookasideList.
782  * HOWEVER, it seems to cause pagefile initialization to fail during boot
783  * for some reason. Need to resolve this before switching to this function.
784  */
785 NTSTATUS
787  IN PDEVICE_OBJECT Fdo,
788  IN PIRP Irp,
790  IN BOOLEAN Lock
791  )
792 {
793  PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
794  PFILE_OBJECT_EXTENSION fsContext;
795  BOOLEAN fileHandleOk = TRUE;
796  BOOLEAN countChanged = FALSE;
798 
799  PAGED_CODE();
800 
802  &fdoExt->EjectSynchronizationEvent,
803  UserRequest,
804  KernelMode,
805  FALSE,
806  NULL);
808 
809  /*
810  * If this is a "secured" request, we have to make sure
811  * that the file handle is valid.
812  */
813  if (LockType == SecureMediaLock){
815 
816  /*
817  * Make sure that the file object we are supplied has a
818  * proper FsContext before we try doing a secured lock.
819  */
820  if (thisSp->FileObject){
822  fsContext = ClassGetFsContext(commonExt, thisSp->FileObject);
823  }
824  else {
825  fsContext = NULL;
826  }
827 
828  if (!fsContext){
829  NT_ASSERT(fsContext);
830  fileHandleOk = FALSE;
831  }
832  }
833 
834  if (fileHandleOk){
835 
836  /*
837  * Adjust the lock counts and make sure they make sense.
838  */
840  if (Lock){
841  switch(LockType) {
842  case SimpleMediaLock:
843  fdoExt->LockCount++;
844  countChanged = TRUE;
845  break;
846  case SecureMediaLock:
847  fsContext->LockCount++;
848  fdoExt->ProtectedLockCount++;
849  countChanged = TRUE;
850  break;
851  case InternalMediaLock:
852  fdoExt->InternalLockCount++;
853  countChanged = TRUE;
854  break;
855  }
856  }
857  else {
858  /*
859  * This is an unlock command. If it's a secured one then make sure
860  * the caller has a lock outstanding or return an error.
861  */
862  switch (LockType){
863  case SimpleMediaLock:
864  if (fdoExt->LockCount > 0){
865  fdoExt->LockCount--;
866  countChanged = TRUE;
867  }
868  else {
869  NT_ASSERT(fdoExt->LockCount > 0);
871  }
872  break;
873  case SecureMediaLock:
874  if (fsContext->LockCount > 0){
875  NT_ASSERT(fdoExt->ProtectedLockCount > 0);
876  fsContext->LockCount--;
877  fdoExt->ProtectedLockCount--;
878  countChanged = TRUE;
879  }
880  else {
881  NT_ASSERT(fsContext->LockCount > 0);
883  }
884  break;
885  case InternalMediaLock:
886  NT_ASSERT(fdoExt->InternalLockCount > 0);
887  fdoExt->InternalLockCount--;
888  countChanged = TRUE;
889  break;
890  }
891  }
892 
893  if (NT_SUCCESS(status)){
894  /*
895  * We only send an unlock command to the drive if
896  * all the lock counts have dropped to zero.
897  */
898  if (!Lock &&
899  (fdoExt->ProtectedLockCount ||
900  fdoExt->InternalLockCount ||
901  fdoExt->LockCount)){
902 
903  /*
904  * The lock count is still positive, so don't unlock yet.
905  */
907  }
908  else if (!TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
909  /*
910  * The device isn't removable media. don't send a cmd.
911  */
913  }
914  else {
915  TRANSFER_PACKET *pkt;
916 
917  pkt = DequeueFreeTransferPacket(Fdo, TRUE);
918  if (pkt){
919  KEVENT event;
920 
921  /*
922  * Store the number of packets servicing the irp (one)
923  * inside the original IRP. It will be used to counted down
924  * to zero when the packet completes.
925  * Initialize the original IRP's status to success.
926  * If the packet fails, we will set it to the error status.
927  */
928  Irp->Tail.Overlay.DriverContext[0] = LongToPtr(1);
929  Irp->IoStatus.Status = STATUS_SUCCESS;
930 
931  /*
932  * Set this up as a SYNCHRONOUS transfer, submit it,
933  * and wait for the packet to complete. The result
934  * status will be written to the original irp.
935  */
940  status = Irp->IoStatus.Status;
941  }
942  else {
944  }
945  }
946  }
947  }
948  else {
950  }
951 
952  if (!NT_SUCCESS(status) && countChanged) {
953 
954  //
955  // have to revert to previous counts if the
956  // lock/unlock operation actually failed.
957  //
958 
959  if(Lock) {
960 
961  switch(LockType) {
962 
963  case SimpleMediaLock: {
964  FdoExtension->LockCount--;
965  break;
966  }
967 
968  case SecureMediaLock: {
969  fsContext->LockCount--;
970  FdoExtension->ProtectedLockCount--;
971  break;
972  }
973 
974  case InternalMediaLock: {
975  FdoExtension->InternalLockCount--;
976  break;
977  }
978  }
979 
980  } else {
981 
982  switch(LockType) {
983 
984  case SimpleMediaLock: {
985  FdoExtension->LockCount++;
986  break;
987  }
988 
989  case SecureMediaLock: {
990  fsContext->LockCount++;
991  FdoExtension->ProtectedLockCount++;
992  break;
993  }
994 
995  case InternalMediaLock: {
996  FdoExtension->InternalLockCount++;
997  break;
998  }
999  }
1000  }
1001  }
1002 
1003 
1004 
1006 
1007  return status;
1008 }
1009 #endif
1010 
1013 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1014 ClassGetFsContext(
1015  _In_ PCOMMON_DEVICE_EXTENSION CommonExtension,
1017  )
1018 {
1019  PAGED_CODE();
1020  return GetDictionaryEntry(&(CommonExtension->FileObjectDictionary),
1021  (ULONGLONG) FileObject);
1022 }
_Inout_ PLIST_ENTRY _In_ PVOID FsContext
Definition: fltkernel.h:2239
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
VOID ClasspCleanupProtectedLocks(IN PFILE_OBJECT_EXTENSION FsContext)
Definition: create.c:296
CONST char * PCSZ
Definition: umtypes.h:125
_IRQL_requires_max_(PASSIVE_LEVEL)
Definition: create.c:1011
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
NTSTATUS ClasspCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: create.c:123
#define IN
Definition: typedefs.h:39
NTSTATUS SubmitTransferPacket(PTRANSFER_PACKET Pkt)
Definition: xferpkt.c:850
#define LongToPtr(l)
Definition: basetsd.h:91
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:100
NTSTATUS NTAPI ClassCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: create.c:57
UCHAR Cdb[16]
Definition: srb.h:271
VOID FreeDictionaryEntry(IN PDICTIONARY Dictionary, IN PVOID Entry)
Definition: dictlib.c:189
struct _CDB::_MEDIA_REMOVAL MEDIA_REMOVAL
PTRANSFER_PACKET DequeueFreeTransferPacket(PDEVICE_OBJECT Fdo, BOOLEAN AllocIfNeeded)
Definition: xferpkt.c:656
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
ACCESS_MASK DesiredAccess
Definition: iotypes.h:2847
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
IO_COMPLETION_ROUTINE ClassSignalCompletion
Definition: classpnp.h:1330
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
UCHAR CdbLength
Definition: srb.h:250
NTSTATUS AllocateDictionaryEntry(IN PDICTIONARY Dictionary, IN ULONGLONG Key, IN ULONG Size, IN ULONG Tag, OUT PVOID *Entry)
VOID SetupEjectionTransferPacket(TRANSFER_PACKET *Pkt, BOOLEAN PreventMediaRemoval, PKEVENT SyncEventPtr, PIRP OriginalIrp)
Definition: xferpkt.c:1310
FORCEINLINE PCDB SrbGetCdb(_In_ PVOID Srb)
Definition: srbhelper.h:583
PCLASS_CREATE_CLOSE ClassCreateClose
Definition: classpnp.h:526
#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
_SEH2_TRY
Definition: create.c:4226
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2864
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
#define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE
Definition: classpnp.h:695
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT FileObject
Definition: create.c:4137
unsigned char BOOLEAN
MEDIA_LOCK_TYPE
Definition: cdromp.h:288
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
smooth NULL
Definition: ftsmooth.c:416
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
union _CDB * PCDB
#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
PVOID GetDictionaryEntry(IN PDICTIONARY Dictionary, IN ULONGLONG Key)
Definition: dictlib.c:157
#define ClasspAllocateSrb(ext)
Definition: classpnp.h:146
#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
FORCEINLINE VOID SrbSetTimeOutValue(_In_ PVOID Srb, _In_ ULONG TimeOutValue)
Definition: srbhelper.h:821
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
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
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:871
#define NO_REMOVE
Definition: classpnp.h:96
#define CLASS_TAG_FILE_OBJECT_EXTENSION
Definition: classpnp.h:78
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
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
struct _cl_event * event
Definition: glext.h:7739
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define _In_
Definition: no_sal2.h:158
__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
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
VOID ClassFreeOrReuseSrb(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN __drv_freesMem(mem) PSCSI_REQUEST_BLOCK Srb)
Definition: obsolete.c:882
PCLASS_DEV_INFO DevInfo
Definition: classpnp.h:620
NTSTATUS ClasspEjectionControl(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN MEDIA_LOCK_TYPE LockType, IN BOOLEAN Lock)
Definition: create.c:474
_SEH2_FINALLY
Definition: create.c:4371
#define IS_CLEANUP_REQUEST(majorFunction)
Definition: classpnp.h:30
_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
const PCSZ LockTypeStrings[]
Definition: create.c:34
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#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
#define _SEH2_LEAVE
Definition: filesup.c:20
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
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
HRESULT Create([out]ITransactionReceiver **ppReceiver)
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97