📄 asyncapi.c
字号:
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
async.c
Abstract
Author:
Peter Binder (pbinder) 5/12/98
Revision History:
Date Who What
-------- --------- ------------------------------------------------------------
5/12/98 pbinder birth
--*/
#include "pch.h"
NTSTATUS
t1394Diag_AllocateAddressRange(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG fulAllocateFlags,
IN ULONG fulFlags,
IN ULONG nLength,
IN ULONG MaxSegmentSize,
IN ULONG fulAccessType,
IN ULONG fulNotificationOptions,
IN OUT PADDRESS_OFFSET Required1394Offset,
OUT PHANDLE phAddressRange,
IN OUT PULONG Data
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PIRB pIrb;
PASYNC_ADDRESS_DATA pAsyncAddressData;
KIRQL Irql;
ULONG nPages;
ENTER("t1394Diag_AllocateAddressRange");
TRACE(TL_TRACE, ("fulAllocateFlags = 0x%x\n", fulAllocateFlags));
TRACE(TL_TRACE, ("fulFlags = 0x%x\n", fulFlags));
TRACE(TL_TRACE, ("nLength = 0x%x\n", nLength));
TRACE(TL_TRACE, ("MaxSegmentSize = 0x%x\n", MaxSegmentSize));
TRACE(TL_TRACE, ("fulAccessType = 0x%x\n", fulAccessType));
TRACE(TL_TRACE, ("fulNotificationOptions = 0x%x\n", fulNotificationOptions));
TRACE(TL_TRACE, ("Required1394Offset->Off_High = 0x%x\n", Required1394Offset->Off_High));
TRACE(TL_TRACE, ("Required1394Offset->Off_Low = 0x%x\n", Required1394Offset->Off_Low));
TRACE(TL_TRACE, ("Data = 0x%x\n", Data));
if (nLength == 0) {
TRACE(TL_ERROR, ("Invalid nLength!\n"));
TRAP;
ntStatus = STATUS_INVALID_PARAMETER;
goto Exit_AllocateAddressRange;
}
pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));
if (!pIrb) {
TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
TRAP;
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_AllocateAddressRange;
} // if
pAsyncAddressData = ExAllocatePool(NonPagedPool, sizeof(ASYNC_ADDRESS_DATA));
if (!pAsyncAddressData) {
TRACE(TL_ERROR, ("Failed to allocate pAsyncAddressData!\n"));
TRAP;
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_AllocateAddressRange;
}
pAsyncAddressData->Buffer = ExAllocatePool(NonPagedPool, nLength);
TRACE(TL_TRACE, ("pAsyncAddressData->Buffer = 0x%x\n", pAsyncAddressData->Buffer));
if (!pAsyncAddressData->Buffer) {
TRACE(TL_ERROR, ("Failed to allocate Buffer!\n"));
TRAP;
if (pAsyncAddressData)
ExFreePool(pAsyncAddressData);
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_AllocateAddressRange;
}
// we need to know how big our address range buffer will be...
nPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Data, nLength);
TRACE(TL_TRACE, ("nPages = 0x%x\n", nPages));
pAsyncAddressData->AddressRange = ExAllocatePool(NonPagedPool, sizeof(ADDRESS_RANGE)*nPages);
if (!pAsyncAddressData->AddressRange) {
TRACE(TL_ERROR, ("Failed to allocate AddressRange!\n"));
TRAP;
if (pAsyncAddressData->Buffer)
ExFreePool(pAsyncAddressData->Buffer);
if (pAsyncAddressData)
ExFreePool(pAsyncAddressData);
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_AllocateAddressRange;
}
pAsyncAddressData->pMdl = MmCreateMdl(NULL, pAsyncAddressData->Buffer, nLength);
if (!pAsyncAddressData->pMdl) {
TRACE(TL_ERROR, ("Failed to create pMdl!\n"));
TRAP;
if (pAsyncAddressData->AddressRange)
ExFreePool(pAsyncAddressData->AddressRange);
if (pAsyncAddressData->Buffer)
ExFreePool(pAsyncAddressData->Buffer);
if (pAsyncAddressData)
ExFreePool(pAsyncAddressData);
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_AllocateAddressRange;
}
MmBuildMdlForNonPagedPool(pAsyncAddressData->pMdl);
TRACE(TL_TRACE, ("pMdl = 0x%x\n", pAsyncAddressData->pMdl));
// copy over the contents of data to our driver buffer
RtlCopyMemory(pAsyncAddressData->Buffer, Data, nLength);
pAsyncAddressData->nLength = nLength;
pIrb->FunctionNumber = REQUEST_ALLOCATE_ADDRESS_RANGE;
pIrb->Flags = 0;
pIrb->u.AllocateAddressRange.Mdl = pAsyncAddressData->pMdl;
pIrb->u.AllocateAddressRange.fulFlags = fulFlags;
pIrb->u.AllocateAddressRange.nLength = nLength;
pIrb->u.AllocateAddressRange.MaxSegmentSize = MaxSegmentSize;
pIrb->u.AllocateAddressRange.fulAccessType = fulAccessType;
pIrb->u.AllocateAddressRange.fulNotificationOptions = fulNotificationOptions;
// if (bUseCallback) {
// pIrb->u.AllocateAddressRange.Callback = t1394Diag_AllocateAddressRange_Callback;
// pIrb->u.AllocateAddressRange.Context = deviceExtension;
// }
// else {
pIrb->u.AllocateAddressRange.Callback = NULL;
pIrb->u.AllocateAddressRange.Context = NULL;
// }
pIrb->u.AllocateAddressRange.Required1394Offset = *Required1394Offset;
pIrb->u.AllocateAddressRange.FifoSListHead = NULL;
pIrb->u.AllocateAddressRange.FifoSpinLock = NULL;
pIrb->u.AllocateAddressRange.AddressesReturned = 0;
pIrb->u.AllocateAddressRange.p1394AddressRange = pAsyncAddressData->AddressRange;
pIrb->u.AllocateAddressRange.DeviceExtension = deviceExtension;
ntStatus = t1394Diag_SubmitIrpSynch(deviceExtension->StackDeviceObject, Irp, pIrb);
if (NT_SUCCESS(ntStatus)) {
ULONG i;
// save off info into our struct...
pAsyncAddressData->DeviceExtension = deviceExtension;
pAsyncAddressData->nAddressesReturned = pIrb->u.AllocateAddressRange.AddressesReturned;
// pAsyncAddressData->AddressRange = pIrb->u.AllocateAddressRange.p1394AddressRange;
pAsyncAddressData->hAddressRange = pIrb->u.AllocateAddressRange.hAddressRange;
// add our struct to the list...
KeAcquireSpinLock(&deviceExtension->AsyncSpinLock, &Irql);
InsertHeadList(&deviceExtension->AsyncAddressData, &pAsyncAddressData->AsyncAddressList);
KeReleaseSpinLock(&deviceExtension->AsyncSpinLock, Irql);
*phAddressRange = pIrb->u.AllocateAddressRange.hAddressRange;
TRACE(TL_TRACE, ("AddressesReturned = 0x%x\n", pIrb->u.AllocateAddressRange.AddressesReturned));
TRACE(TL_TRACE, ("hAddressRange = 0x%x\n", *phAddressRange));
for (i=0; i < pIrb->u.AllocateAddressRange.AddressesReturned; i++) {
TRACE(TL_TRACE, ("Off_High = 0x%x\n", pAsyncAddressData->AddressRange[0].AR_Off_High));
TRACE(TL_TRACE, ("Off_Low = 0x%x\n", pAsyncAddressData->AddressRange[0].AR_Off_Low));
}
Required1394Offset->Off_High = pIrb->u.AllocateAddressRange.p1394AddressRange[0].AR_Off_High;
Required1394Offset->Off_Low = pIrb->u.AllocateAddressRange.p1394AddressRange[0].AR_Off_Low;
}
else {
TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", ntStatus));
TRAP;
// need to free a few things...
if (pAsyncAddressData->pMdl)
ExFreePool(pAsyncAddressData->pMdl);
if (pAsyncAddressData->Buffer)
ExFreePool(pAsyncAddressData->Buffer);
if (pAsyncAddressData->AddressRange)
ExFreePool(pAsyncAddressData->AddressRange);
if (pAsyncAddressData)
ExFreePool(pAsyncAddressData);
}
Exit_AllocateAddressRange:
if (pIrb)
ExFreePool(pIrb);
EXIT("t1394Diag_AllocateAddressRange", ntStatus);
return(ntStatus);
} // t1394Diag_AllocateAddressRange
NTSTATUS
t1394Diag_FreeAddressRange(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN HANDLE hAddressRange
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PIRB pIrb;
KIRQL Irql;
PASYNC_ADDRESS_DATA AsyncAddressData;
ENTER("t1394Diag_FreeAddressRange");
TRACE(TL_TRACE, ("hAddressRange = 0x%x\n", hAddressRange));
// have to find our struct...
KeAcquireSpinLock(&deviceExtension->AsyncSpinLock, &Irql);
AsyncAddressData = (PASYNC_ADDRESS_DATA) deviceExtension->AsyncAddressData.Flink;
while (AsyncAddressData) {
if (AsyncAddressData->hAddressRange == hAddressRange) {
RemoveEntryList(&AsyncAddressData->AsyncAddressList);
break;
}
else if (AsyncAddressData->AsyncAddressList.Flink == &deviceExtension->AsyncAddressData) {
AsyncAddressData = NULL;
break;
}
else
AsyncAddressData = (PASYNC_ADDRESS_DATA)AsyncAddressData->AsyncAddressList.Flink;
}
KeReleaseSpinLock(&deviceExtension->AsyncSpinLock, Irql);
// never found an entry...
if (!AsyncAddressData) {
ntStatus = STATUS_INVALID_PARAMETER;
goto Exit_FreeAddressRange;
}
// lets verify we have the right one, if not, we bail...
if (AsyncAddressData->hAddressRange == hAddressRange) {
// got it, lets free it...
pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));
if (!pIrb) {
TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
TRAP;
// we need to add this back into our list since we were
// unable to free it...
KeAcquireSpinLock(&deviceExtension->AsyncSpinLock, &Irql);
InsertHeadList(&deviceExtension->AsyncAddressData, &AsyncAddressData->AsyncAddressList);
KeReleaseSpinLock(&deviceExtension->AsyncSpinLock, Irql);
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_FreeAddressRange;
} // if
pIrb->FunctionNumber = REQUEST_FREE_ADDRESS_RANGE;
pIrb->Flags = 0;
pIrb->u.FreeAddressRange.nAddressesToFree = AsyncAddressData->nAddressesReturned;
pIrb->u.FreeAddressRange.p1394AddressRange = AsyncAddressData->AddressRange;
pIrb->u.FreeAddressRange.pAddressRange = &AsyncAddressData->hAddressRange;
pIrb->u.FreeAddressRange.DeviceExtension = (PVOID)deviceExtension;
ntStatus = t1394Diag_SubmitIrpSynch(deviceExtension->StackDeviceObject, Irp, pIrb);
if (!NT_SUCCESS(ntStatus)) {
TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", ntStatus));
TRAP;
}
if (pIrb)
ExFreePool(pIrb);
// need to free up everything associated with this allocate...
if (AsyncAddressData->pMdl)
ExFreePool(AsyncAddressData->pMdl);
if (AsyncAddressData->Buffer)
ExFreePool(AsyncAddressData->Buffer);
if (AsyncAddressData->AddressRange)
ExFreePool(AsyncAddressData->AddressRange);
if (AsyncAddressData)
ExFreePool(AsyncAddressData);
}
else {
// we couldn't match the handles!
TRACE(TL_ERROR, ("Invalid handle = 0x%x", hAddressRange));
TRAP;
ntStatus = STATUS_INVALID_PARAMETER;
goto Exit_FreeAddressRange;
}
Exit_FreeAddressRange:
EXIT("t1394Diag_FreeAddressRange", ntStatus);
return(ntStatus);
} // t1394Diag_FreeAddressRange
NTSTATUS
t1394Diag_SetAddressData(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN HANDLE hAddressRange,
IN ULONG nLength,
IN ULONG ulOffset,
IN PVOID Data
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
KIRQL Irql;
PASYNC_ADDRESS_DATA AsyncAddressData;
ENTER("t1394Diag_SetAddressData");
TRACE(TL_TRACE, ("hAddressRange = 0x%x\n", hAddressRange));
TRACE(TL_TRACE, ("nLength = 0x%x\n", nLength));
TRACE(TL_TRACE, ("ulOffset = 0x%x\n", ulOffset));
// have to find our struct...
KeAcquireSpinLock(&deviceExtension->AsyncSpinLock, &Irql);
AsyncAddressData = (PASYNC_ADDRESS_DATA) deviceExtension->AsyncAddressData.Flink;
while (AsyncAddressData) {
if (AsyncAddressData->hAddressRange == hAddressRange) {
PULONG pBuffer;
// found it, let's copy over the contents from data...
pBuffer = (PULONG)((ULONG_PTR)AsyncAddressData->Buffer + ulOffset);
TRACE(TL_TRACE, ("pBuffer = 0x%x\n", pBuffer));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -