Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenirpstream.cpp
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Kernel Streaming 00004 * FILE: drivers/wdm/audio/backpln/portcls/irpstream.cpp 00005 * PURPOSE: IRP Stream handling 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 #include "private.hpp" 00010 00011 00012 class CIrpQueue : public IIrpQueue 00013 { 00014 public: 00015 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); 00016 00017 STDMETHODIMP_(ULONG) AddRef() 00018 { 00019 InterlockedIncrement(&m_Ref); 00020 return m_Ref; 00021 } 00022 STDMETHODIMP_(ULONG) Release() 00023 { 00024 InterlockedDecrement(&m_Ref); 00025 00026 if (!m_Ref) 00027 { 00028 delete this; 00029 return 0; 00030 } 00031 return m_Ref; 00032 } 00033 IMP_IIrpQueue; 00034 CIrpQueue(IUnknown *OuterUnknown){} 00035 virtual ~CIrpQueue(){} 00036 00037 protected: 00038 00039 PKSPIN_CONNECT m_ConnectDetails; 00040 PKSPIN_DESCRIPTOR m_Descriptor; 00041 00042 KSPIN_LOCK m_IrpListLock; 00043 LIST_ENTRY m_IrpList; 00044 LIST_ENTRY m_FreeIrpList; 00045 00046 BOOLEAN m_OutOfMapping; 00047 ULONG m_MaxFrameSize; 00048 ULONG m_Alignment; 00049 ULONG m_TagSupportEnabled; 00050 ULONG m_NumDataAvailable; 00051 volatile ULONG m_CurrentOffset; 00052 00053 PIRP m_Irp; 00054 00055 00056 LONG m_Ref; 00057 00058 }; 00059 00060 typedef struct 00061 { 00062 ULONG StreamHeaderCount; 00063 ULONG StreamHeaderIndex; 00064 ULONG TotalStreamData; 00065 00066 PKSSTREAM_HEADER CurStreamHeader; 00067 PVOID * Data; 00068 PVOID * Tags; 00069 }KSSTREAM_DATA, *PKSSTREAM_DATA; 00070 00071 #define STREAM_DATA_OFFSET (0) 00072 00073 00074 NTSTATUS 00075 NTAPI 00076 CIrpQueue::QueryInterface( 00077 IN REFIID refiid, 00078 OUT PVOID* Output) 00079 { 00080 if (IsEqualGUIDAligned(refiid, IID_IUnknown)) 00081 { 00082 *Output = PVOID(PUNKNOWN(this)); 00083 PUNKNOWN(*Output)->AddRef(); 00084 return STATUS_SUCCESS; 00085 } 00086 00087 return STATUS_UNSUCCESSFUL; 00088 } 00089 00090 NTSTATUS 00091 NTAPI 00092 CIrpQueue::Init( 00093 IN PKSPIN_CONNECT ConnectDetails, 00094 IN PKSPIN_DESCRIPTOR Descriptor, 00095 IN ULONG FrameSize, 00096 IN ULONG Alignment, 00097 IN ULONG TagSupportEnabled) 00098 { 00099 m_ConnectDetails = ConnectDetails; 00100 m_Descriptor = Descriptor; 00101 m_MaxFrameSize = FrameSize; 00102 m_Alignment = Alignment; 00103 m_TagSupportEnabled = TagSupportEnabled; 00104 00105 InitializeListHead(&m_IrpList); 00106 InitializeListHead(&m_FreeIrpList); 00107 KeInitializeSpinLock(&m_IrpListLock); 00108 00109 return STATUS_SUCCESS; 00110 } 00111 00112 NTSTATUS 00113 NTAPI 00114 CIrpQueue::AddMapping( 00115 IN PIRP Irp, 00116 OUT PULONG Data) 00117 { 00118 PKSSTREAM_HEADER Header; 00119 NTSTATUS Status = STATUS_UNSUCCESSFUL; 00120 PIO_STACK_LOCATION IoStack; 00121 ULONG Index, Length; 00122 PMDL Mdl; 00123 PKSSTREAM_DATA StreamData; 00124 00125 PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 00126 00127 // allocate stream data 00128 StreamData = (PKSSTREAM_DATA)AllocateItem(NonPagedPool, sizeof(KSSTREAM_DATA), TAG_PORTCLASS); 00129 if (!StreamData) 00130 { 00131 // not enough memory 00132 return STATUS_INSUFFICIENT_RESOURCES; 00133 } 00134 00135 // get current irp stack location 00136 IoStack = IoGetCurrentIrpStackLocation(Irp); 00137 00138 // lets probe the irp 00139 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM) 00140 { 00141 // probe IOCTL_KS_WRITE_STREAM 00142 Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, 0); 00143 } 00144 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM) 00145 { 00146 // probe IOCTL_KS_READ_STREAM 00147 Status = KsProbeStreamIrp(Irp, KSSTREAM_READ | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, 0); 00148 } 00149 00150 // check for success 00151 if (!NT_SUCCESS(Status)) 00152 { 00153 // irp probing failed 00154 FreeItem(StreamData, TAG_PORTCLASS); 00155 return Status; 00156 } 00157 00158 // get first stream header 00159 Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; 00160 00161 // store header 00162 StreamData->CurStreamHeader = Header; 00163 00164 // sanity check 00165 PC_ASSERT(Header); 00166 00167 // first calculate the numbers of stream headers 00168 Length = IoStack->Parameters.DeviceIoControl.OutputBufferLength; 00169 00170 do 00171 { 00172 /* subtract size */ 00173 Length -= Header->Size; 00174 00175 /* increment header count */ 00176 StreamData->StreamHeaderCount++; 00177 00178 if (m_Descriptor->DataFlow == KSPIN_DATAFLOW_IN) 00179 { 00180 // irp sink 00181 StreamData->TotalStreamData += Header->DataUsed; 00182 } 00183 else 00184 { 00185 // irp source 00186 StreamData->TotalStreamData += Header->FrameExtent; 00187 } 00188 00189 /* move to next header */ 00190 Header = (PKSSTREAM_HEADER)((ULONG_PTR)Header + Header->Size); 00191 00192 }while(Length); 00193 00194 // sanity check 00195 ASSERT(StreamData->StreamHeaderCount); 00196 00197 // allocate array for storing the pointers of the data */ 00198 StreamData->Data = (PVOID*)AllocateItem(NonPagedPool, sizeof(PVOID) * StreamData->StreamHeaderCount, TAG_PORTCLASS); 00199 if (!StreamData->Data) 00200 { 00201 // out of memory 00202 FreeItem(StreamData, TAG_PORTCLASS); 00203 00204 // done 00205 return STATUS_INSUFFICIENT_RESOURCES; 00206 } 00207 00208 if (m_TagSupportEnabled) 00209 { 00210 // allocate array for storing the pointers of the data */ 00211 StreamData->Tags = (PVOID*)AllocateItem(NonPagedPool, sizeof(PVOID) * StreamData->StreamHeaderCount, TAG_PORTCLASS); 00212 if (!StreamData->Data) 00213 { 00214 // out of memory 00215 FreeItem(StreamData->Data, TAG_PORTCLASS); 00216 FreeItem(StreamData, TAG_PORTCLASS); 00217 00218 // done 00219 return STATUS_INSUFFICIENT_RESOURCES; 00220 } 00221 } 00222 00223 00224 // now get a system address for the user buffers 00225 Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; 00226 Mdl = Irp->MdlAddress; 00227 00228 for(Index = 0; Index < StreamData->StreamHeaderCount; Index++) 00229 { 00230 /* get system address */ 00231 StreamData->Data[Index] = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority); 00232 00233 /* check for success */ 00234 if (!StreamData->Data[Index]) 00235 { 00236 // out of resources 00237 FreeItem(StreamData->Data, TAG_PORTCLASS); 00238 00239 if (m_TagSupportEnabled) 00240 { 00241 // free tag array 00242 FreeItem(StreamData->Tags, TAG_PORTCLASS); 00243 } 00244 00245 FreeItem(StreamData, TAG_PORTCLASS); 00246 // done 00247 return STATUS_INSUFFICIENT_RESOURCES; 00248 } 00249 00250 if (m_Descriptor->DataFlow == KSPIN_DATAFLOW_IN) 00251 { 00252 // increment available data 00253 InterlockedExchangeAdd((PLONG)&m_NumDataAvailable, Header->DataUsed); 00254 } 00255 else if (m_Descriptor->DataFlow == KSPIN_DATAFLOW_OUT) 00256 { 00257 // increment available data 00258 InterlockedExchangeAdd((PLONG)&m_NumDataAvailable, Header->FrameExtent); 00259 } 00260 00261 // move to next header / mdl 00262 Mdl = Mdl->Next; 00263 Header = (PKSSTREAM_HEADER)((ULONG_PTR)Header + Header->Size); 00264 00265 } 00266 00267 // store stream data 00268 Irp->Tail.Overlay.DriverContext[STREAM_DATA_OFFSET] = (PVOID)StreamData; 00269 00270 *Data = StreamData->TotalStreamData; 00271 00272 // mark irp as pending 00273 IoMarkIrpPending(Irp); 00274 00275 // add irp to cancelable queue 00276 KsAddIrpToCancelableQueue(&m_IrpList, &m_IrpListLock, Irp, KsListEntryTail, NULL); 00277 00278 // disable mapping failed status 00279 m_OutOfMapping = FALSE; 00280 00281 // done 00282 return STATUS_SUCCESS; 00283 } 00284 00285 NTSTATUS 00286 NTAPI 00287 CIrpQueue::GetMapping( 00288 OUT PUCHAR * Buffer, 00289 OUT PULONG BufferSize) 00290 { 00291 PIRP Irp; 00292 ULONG Offset; 00293 PKSSTREAM_DATA StreamData; 00294 00295 // check if there is an irp in the partially processed 00296 if (m_Irp) 00297 { 00298 // use last irp 00299 if (m_Irp->Cancel == FALSE) 00300 { 00301 Irp = m_Irp; 00302 Offset = m_CurrentOffset; 00303 } 00304 else 00305 { 00306 // irp has been cancelled 00307 m_Irp->IoStatus.Status = STATUS_CANCELLED; 00308 IoCompleteRequest(m_Irp, IO_NO_INCREMENT); 00309 m_Irp = Irp = NULL; 00310 m_CurrentOffset = 0; 00311 } 00312 } 00313 else 00314 { 00315 // get a fresh new irp from the queue 00316 m_Irp = Irp = KsRemoveIrpFromCancelableQueue(&m_IrpList, &m_IrpListLock, KsListEntryHead, KsAcquireAndRemoveOnlySingleItem); 00317 m_CurrentOffset = Offset = 0; 00318 } 00319 00320 if (!Irp) 00321 { 00322 // no irp buffer available 00323 return STATUS_UNSUCCESSFUL; 00324 } 00325 00326 // get stream data 00327 StreamData = (PKSSTREAM_DATA)Irp->Tail.Overlay.DriverContext[STREAM_DATA_OFFSET]; 00328 00329 // sanity check 00330 PC_ASSERT(StreamData); 00331 00332 // get buffer size 00333 if (m_Descriptor->DataFlow == KSPIN_DATAFLOW_IN) 00334 { 00335 // sink pin 00336 *BufferSize = StreamData->CurStreamHeader->DataUsed - Offset; 00337 } 00338 else 00339 { 00340 // source pin 00341 *BufferSize = StreamData->CurStreamHeader->FrameExtent - Offset; 00342 } 00343 00344 // sanity check 00345 PC_ASSERT(*BufferSize); 00346 00347 // store buffer 00348 *Buffer = &((PUCHAR)StreamData->Data[StreamData->StreamHeaderIndex])[Offset]; 00349 00350 // unset flag that no irps are available 00351 m_OutOfMapping = FALSE; 00352 00353 return STATUS_SUCCESS; 00354 } 00355 00356 VOID 00357 NTAPI 00358 CIrpQueue::UpdateMapping( 00359 IN ULONG BytesWritten) 00360 { 00361 PKSSTREAM_DATA StreamData; 00362 ULONG Size; 00363 PIO_STACK_LOCATION IoStack; 00364 00365 // sanity check 00366 ASSERT(m_Irp); 00367 00368 // get stream data 00369 StreamData = (PKSSTREAM_DATA)m_Irp->Tail.Overlay.DriverContext[STREAM_DATA_OFFSET]; 00370 00371 // sanity check 00372 ASSERT(StreamData); 00373 00374 // add to current offset 00375 InterlockedExchangeAdd((PLONG)&m_CurrentOffset, (LONG)BytesWritten); 00376 00377 if (m_Descriptor->DataFlow == KSPIN_DATAFLOW_OUT) 00378 { 00379 // store written bytes (source pin) 00380 StreamData->CurStreamHeader->DataUsed += BytesWritten; 00381 } 00382 00383 // decrement available data counter 00384 m_NumDataAvailable -= BytesWritten; 00385 00386 // get audio buffer size 00387 if (m_Descriptor->DataFlow == KSPIN_DATAFLOW_OUT) 00388 Size = StreamData->CurStreamHeader->FrameExtent; 00389 else 00390 Size = StreamData->CurStreamHeader->DataUsed; 00391 00392 // sanity check 00393 PC_ASSERT(Size); 00394 00395 if (m_CurrentOffset >= Size) 00396 { 00397 // sanity check 00398 PC_ASSERT(Size == m_CurrentOffset); 00399 00400 if (StreamData->StreamHeaderIndex + 1 < StreamData->StreamHeaderCount) 00401 { 00402 // move to next stream header 00403 StreamData->CurStreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamData->CurStreamHeader + StreamData->CurStreamHeader->Size); 00404 00405 // increment stream header index 00406 StreamData->StreamHeaderIndex++; 00407 00408 // reset offset 00409 m_CurrentOffset = 0; 00410 00411 // done 00412 return; 00413 } 00414 00415 // 00416 // all stream buffers have been played 00417 // check if this is a looped buffer 00418 // 00419 if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) 00420 { 00421 // looped streaming repeat the buffers untill 00422 // the caller decides to stop the streams 00423 00424 // reset stream header index 00425 StreamData->StreamHeaderIndex = 0; 00426 00427 // reset stream header 00428 StreamData->CurStreamHeader = (PKSSTREAM_HEADER)m_Irp->AssociatedIrp.SystemBuffer; 00429 00430 // increment available data 00431 InterlockedExchangeAdd((PLONG)&m_NumDataAvailable, StreamData->TotalStreamData); 00432 00433 // re-insert irp 00434 KsAddIrpToCancelableQueue(&m_IrpList, &m_IrpListLock, m_Irp, KsListEntryTail, NULL); 00435 00436 // clear current irp 00437 m_Irp = NULL; 00438 00439 // reset offset 00440 m_CurrentOffset = 0; 00441 00442 // done 00443 return; 00444 } 00445 00446 // free stream data array 00447 FreeItem(StreamData->Data, TAG_PORTCLASS); 00448 00449 if (m_TagSupportEnabled) 00450 { 00451 // free tag array 00452 FreeItem(StreamData->Tags, TAG_PORTCLASS); 00453 } 00454 00455 // free stream data 00456 FreeItem(StreamData, TAG_PORTCLASS); 00457 00458 // get io stack 00459 IoStack = IoGetCurrentIrpStackLocation(m_Irp); 00460 00461 // store operation status 00462 m_Irp->IoStatus.Status = STATUS_SUCCESS; 00463 00464 // store operation length 00465 m_Irp->IoStatus.Information = IoStack->Parameters.DeviceIoControl.OutputBufferLength; 00466 00467 // complete the request 00468 IoCompleteRequest(m_Irp, IO_SOUND_INCREMENT); 00469 00470 // remove irp as it is complete 00471 m_Irp = NULL; 00472 00473 // reset offset 00474 m_CurrentOffset = 0; 00475 } 00476 } 00477 00478 ULONG 00479 NTAPI 00480 CIrpQueue::NumData() 00481 { 00482 // returns the amount of audio stream data available 00483 return m_NumDataAvailable; 00484 } 00485 00486 BOOL 00487 NTAPI 00488 CIrpQueue::CancelBuffers() 00489 { 00490 //TODO: own cancel routine 00491 00492 // is there an active irp 00493 if (m_Irp) 00494 { 00495 // re-insert it to cancelable queue 00496 KsAddIrpToCancelableQueue(&m_IrpList, &m_IrpListLock, m_Irp, KsListEntryTail, NULL); 00497 //set it to zero 00498 m_Irp = NULL; 00499 } 00500 00501 // cancel all irps 00502 KsCancelIo(&m_IrpList, &m_IrpListLock); 00503 00504 // reset number of data available 00505 m_NumDataAvailable = 0; 00506 00507 // done 00508 return TRUE; 00509 } 00510 00511 NTSTATUS 00512 NTAPI 00513 CIrpQueue::GetMappingWithTag( 00514 IN PVOID Tag, 00515 OUT PPHYSICAL_ADDRESS PhysicalAddress, 00516 OUT PVOID *VirtualAddress, 00517 OUT PULONG ByteCount, 00518 OUT PULONG Flags) 00519 { 00520 PKSSTREAM_DATA StreamData; 00521 00522 /* sanity checks */ 00523 PC_ASSERT(Tag != NULL); 00524 PC_ASSERT(PhysicalAddress); 00525 PC_ASSERT(VirtualAddress); 00526 PC_ASSERT(ByteCount); 00527 PC_ASSERT(Flags); 00528 00529 if (!m_Irp) 00530 { 00531 // get an irp from the queue 00532 m_Irp = KsRemoveIrpFromCancelableQueue(&m_IrpList, &m_IrpListLock, KsListEntryHead, KsAcquireAndRemoveOnlySingleItem); 00533 } 00534 00535 // check if there is an irp 00536 if (!m_Irp) 00537 { 00538 // no irp available 00539 m_OutOfMapping = TRUE; 00540 return STATUS_NOT_FOUND; 00541 } 00542 00543 // get stream data 00544 StreamData = (PKSSTREAM_DATA)m_Irp->Tail.Overlay.DriverContext[STREAM_DATA_OFFSET]; 00545 00546 // sanity check 00547 PC_ASSERT(StreamData->StreamHeaderIndex < StreamData->StreamHeaderCount); 00548 00549 // setup mapping 00550 *PhysicalAddress = MmGetPhysicalAddress(StreamData->Data[StreamData->StreamHeaderIndex]); 00551 *VirtualAddress = StreamData->Data[StreamData->StreamHeaderIndex]; 00552 00553 // store tag in irp 00554 StreamData->Tags[StreamData->StreamHeaderIndex] = Tag; 00555 00556 // mapping size 00557 if (m_Descriptor->DataFlow == KSPIN_DATAFLOW_IN) 00558 { 00559 // sink pin 00560 *ByteCount = StreamData->CurStreamHeader->DataUsed; 00561 00562 // decrement num data available 00563 m_NumDataAvailable -= StreamData->CurStreamHeader->DataUsed; 00564 } 00565 else 00566 { 00567 // source pin 00568 *ByteCount = StreamData->CurStreamHeader->FrameExtent; 00569 00570 // decrement num data available 00571 m_NumDataAvailable -= StreamData->CurStreamHeader->FrameExtent; 00572 } 00573 00574 if (StreamData->StreamHeaderIndex + 1 == StreamData->StreamHeaderCount) 00575 { 00576 // last mapping 00577 *Flags = 1; 00578 00579 // insert mapping into free list 00580 ExInterlockedInsertTailList(&m_FreeIrpList, &m_Irp->Tail.Overlay.ListEntry, &m_IrpListLock); 00581 00582 // clear irp 00583 m_Irp = NULL; 00584 00585 } 00586 else 00587 { 00588 // one more mapping in the irp 00589 *Flags = 0; 00590 00591 // increment header index 00592 StreamData->StreamHeaderIndex++; 00593 00594 // move to next header 00595 StreamData->CurStreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamData->CurStreamHeader + StreamData->CurStreamHeader->Size); 00596 } 00597 00598 // done 00599 return STATUS_SUCCESS; 00600 } 00601 00602 NTSTATUS 00603 NTAPI 00604 CIrpQueue::ReleaseMappingWithTag( 00605 IN PVOID Tag) 00606 { 00607 PIRP Irp; 00608 PLIST_ENTRY CurEntry; 00609 PKSSTREAM_DATA StreamData; 00610 PIO_STACK_LOCATION IoStack; 00611 ULONG Index; 00612 00613 // first check if there is an active irp 00614 if (m_Irp) 00615 { 00616 // now check if there are already used mappings 00617 StreamData = (PKSSTREAM_DATA)m_Irp->Tail.Overlay.DriverContext[STREAM_DATA_OFFSET]; 00618 00619 if (StreamData->StreamHeaderIndex) 00620 { 00621 // check if the released mapping is one current processed irps 00622 for(Index = 0; Index < StreamData->StreamHeaderIndex; Index++) 00623 { 00624 // check if it is the same tag 00625 if (StreamData->Tags[Index] == Tag) 00626 { 00627 // mark mapping as released 00628 StreamData->Tags[Index] = NULL; 00629 00630 // done 00631 return STATUS_SUCCESS; 00632 } 00633 00634 } 00635 } 00636 } 00637 00638 // remove irp from used list 00639 CurEntry = ExInterlockedRemoveHeadList(&m_FreeIrpList, &m_IrpListLock); 00640 00641 // sanity check 00642 PC_ASSERT(CurEntry); 00643 00644 // get irp from list entry 00645 Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry); 00646 00647 // get stream data 00648 StreamData = (PKSSTREAM_DATA)Irp->Tail.Overlay.DriverContext[STREAM_DATA_OFFSET]; 00649 00650 // sanity check 00651 PC_ASSERT(StreamData->StreamHeaderIndex + 1 == StreamData->StreamHeaderCount); 00652 00653 // check if the released mapping is one of these 00654 for(Index = 0; Index < StreamData->StreamHeaderCount; Index++) 00655 { 00656 if (StreamData->Tags[Index] == Tag) 00657 { 00658 // mark mapping as released 00659 StreamData->Tags[Index] = NULL; 00660 00661 // done 00662 break; 00663 } 00664 else 00665 { 00666 // 00667 // we assume that mappings are released in the same order as they have been acquired 00668 // therefore if the current mapping is not the searched one, it must have been already 00669 // released 00670 // 00671 PC_ASSERT(StreamData->Tags[Index] == NULL); 00672 } 00673 } 00674 00675 // check if this is the last one released mapping 00676 if (Index + 1 == StreamData->StreamHeaderCount) 00677 { 00678 // last mapping released 00679 // now check if this is a looped buffer 00680 if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) 00681 { 00682 // looped buffers are not completed when they have been played 00683 // they are completed when the stream is set to stop 00684 00685 // reset stream header index 00686 StreamData->StreamHeaderIndex = 0; 00687 00688 // reset stream header 00689 StreamData->CurStreamHeader = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; 00690 00691 // increment available data 00692 InterlockedExchangeAdd((PLONG)&m_NumDataAvailable, StreamData->TotalStreamData); 00693 00694 // re-insert irp 00695 KsAddIrpToCancelableQueue(&m_IrpList, &m_IrpListLock, Irp, KsListEntryTail, NULL); 00696 00697 // done 00698 return STATUS_SUCCESS; 00699 } 00700 00701 // 00702 // time to complete non looped buffer 00703 // 00704 00705 // free stream data array 00706 FreeItem(StreamData->Data, TAG_PORTCLASS); 00707 00708 // free stream tags array 00709 FreeItem(StreamData->Tags, TAG_PORTCLASS); 00710 00711 // free stream data 00712 FreeItem(StreamData, TAG_PORTCLASS); 00713 00714 // get io stack 00715 IoStack = IoGetCurrentIrpStackLocation(Irp); 00716 00717 // store operation status 00718 Irp->IoStatus.Status = STATUS_SUCCESS; 00719 00720 // store operation length 00721 Irp->IoStatus.Information = IoStack->Parameters.DeviceIoControl.OutputBufferLength; 00722 00723 // complete the request 00724 IoCompleteRequest(Irp, IO_SOUND_INCREMENT); 00725 } 00726 00727 return STATUS_SUCCESS; 00728 } 00729 00730 BOOLEAN 00731 NTAPI 00732 CIrpQueue::HasLastMappingFailed() 00733 { 00734 return m_OutOfMapping; 00735 } 00736 00737 ULONG 00738 NTAPI 00739 CIrpQueue::GetCurrentIrpOffset() 00740 { 00741 00742 return m_CurrentOffset; 00743 } 00744 00745 BOOLEAN 00746 NTAPI 00747 CIrpQueue::GetAcquiredTagRange( 00748 IN PVOID * FirstTag, 00749 IN PVOID * LastTag) 00750 { 00751 KIRQL OldLevel; 00752 BOOLEAN Ret = FALSE; 00753 //PIRP Irp; 00754 //PLIST_ENTRY CurEntry; 00755 //PKSSTREAM_DATA StreamData; 00756 00757 // lock list 00758 KeAcquireSpinLock(&m_IrpListLock, &OldLevel); 00759 00760 // initialize to zero 00761 *FirstTag = NULL; 00762 *LastTag = NULL; 00763 00764 UNIMPLEMENTED; 00765 00766 // release lock 00767 KeReleaseSpinLock(&m_IrpListLock, OldLevel); 00768 // done 00769 return Ret; 00770 } 00771 00772 NTSTATUS 00773 NTAPI 00774 NewIrpQueue( 00775 IN IIrpQueue **Queue) 00776 { 00777 CIrpQueue *This = new(NonPagedPool, TAG_PORTCLASS)CIrpQueue(NULL); 00778 if (!This) 00779 return STATUS_INSUFFICIENT_RESOURCES; 00780 00781 This->AddRef(); 00782 00783 *Queue = (IIrpQueue*)This; 00784 return STATUS_SUCCESS; 00785 } 00786 Generated on Fri May 25 2012 04:26:50 for ReactOS by
1.7.6.1
|