📄 isochapi.c
字号:
*pR3TempDescriptor = R3_IsochDescriptor;
pR3TempDescriptor =
(PRING3_ISOCH_DESCRIPTOR)((ULONG_PTR)pR3TempDescriptor +
pR3TempDescriptor->ulLength +
sizeof(RING3_ISOCH_DESCRIPTOR));
}
}
else {
// we have already received an allocated buffer, let's just map it into
// our attach struct and pass it down.
pIsochAttachBuffers = &pIsochLoopbackParams->isochAttachBuffers;
ulBufferSize = pIsochAttachBuffers->ulBufferSize;
}
if (pIsochAttachBuffers) {
overLapped.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
// loop until the thread is killed
while (TRUE) {
// reset our event, in case we'll be doing another attach
ResetEvent(overLapped.hEvent);
if (pIsochLoopbackParams->bAutoFill) {
// get the point to the first descriptor
pR3TempDescriptor = &pIsochAttachBuffers->R3_IsochDescriptor[0];
for (i=0; i < pIsochAttachBuffers->nNumberOfDescriptors; i++) {
// if we're listening, fill it with 0's
// if we're talking, fill it incrementally
if (pIsochLoopbackParams->ulLoopFlag & RESOURCE_USED_IN_LISTENING) {
FillMemory(&pR3TempDescriptor->Data, pR3TempDescriptor->ulLength, 0);
}
else {
for (n=0; n < (pR3TempDescriptor->ulLength/sizeof(ULONG)); n++) {
CopyMemory((ULONG *)&pR3TempDescriptor->Data+n, (ULONG *)&n, sizeof(ULONG));
}
}
pR3TempDescriptor =
(PRING3_ISOCH_DESCRIPTOR)((ULONG_PTR)pR3TempDescriptor +
pR3TempDescriptor->ulLength +
sizeof(RING3_ISOCH_DESCRIPTOR));
}
}
DeviceIoControl( hDevice,
IOCTL_ISOCH_ATTACH_BUFFERS,
pIsochAttachBuffers,
ulBufferSize,
pIsochAttachBuffers,
ulBufferSize,
&dwBytesRet,
&overLapped
);
dwRet = GetLastError();
if ((dwRet != ERROR_IO_PENDING) && (dwRet != ERROR_SUCCESS)) {
pIsochLoopbackParams->bKill = TRUE;
// if we fail, up the isoch fail counter and stop this thread gracefully...
if ((dwRet != ERROR_OPERATION_ABORTED) && (pIsochLoopbackParams->bLoopback)) {
pIsochLoopbackParams->ulFail++;
}
else {
TRACE(TL_ERROR, (pIsochLoopbackParams->hWnd, "IsochAttachBuffers Failed = %d\r\n", dwRet));
}
}
else {
// if we're doing a loopback, then we'll auto start talk or listen
if (pIsochLoopbackParams->bLoopback) {
if (!bIsochListen && pIsochLoopbackParams->ulLoopFlag & RESOURCE_USED_IN_LISTENING) {
ISOCH_LISTEN isochListen;
OVERLAPPED ListenOverlapped;
ListenOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
isochListen.hResource = isochAttachBuffers.hResource;
isochListen.fulFlags = 0;
isochListen.StartTime.CL_SecondCount = 0;
isochListen.StartTime.CL_CycleCount = 0;
isochListen.StartTime.CL_CycleOffset = 0;
DeviceIoControl( hDevice,
IOCTL_ISOCH_LISTEN,
&isochListen,
sizeof(ISOCH_LISTEN),
NULL,
0,
&dwBytesRet,
&ListenOverlapped
);
CloseHandle(ListenOverlapped.hEvent);
bIsochListen = TRUE;
}
else if (!bIsochTalk && pIsochLoopbackParams->ulLoopFlag & RESOURCE_USED_IN_TALKING) {
ISOCH_TALK isochTalk;
OVERLAPPED TalkOverlapped;
TalkOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
isochTalk.hResource = isochAttachBuffers.hResource;
isochTalk.fulFlags = 0;
isochTalk.StartTime.CL_SecondCount = 0;
isochTalk.StartTime.CL_CycleCount = 0;
isochTalk.StartTime.CL_CycleOffset = 0;
DeviceIoControl( hDevice,
IOCTL_ISOCH_TALK,
&isochTalk,
sizeof(ISOCH_TALK),
NULL,
0,
&dwBytesRet,
&TalkOverlapped
);
CloseHandle(TalkOverlapped.hEvent);
bIsochTalk = TRUE;
}
}
// we got a pending, so we need to wait...
if (dwRet == ERROR_IO_PENDING) {
if (!pIsochLoopbackParams->bLoopback) {
TRACE(TL_TRACE, (pIsochLoopbackParams->hWnd, "IsochAttachBuffers Pending...\r\n"));
}
Sleep(0);
if (!GetOverlappedResult(hDevice, &overLapped, &dwBytesRet, FALSE)) {
// getoverlappedresult failed, lets find out why...
dwRet = GetLastError();
TRACE(TL_ERROR, (NULL, "IsochAttachBuffers: GetOverlappedResult Failed! dwRet = %d\r\n", dwRet));
pIsochLoopbackParams->bKill = TRUE;
}
}
// we're doing a loopback test, so we need to increment our
// test values
if ((!pIsochLoopbackParams->bKill) && (pIsochLoopbackParams->bLoopback)) {
// if listen, then verify the buffer
if (pIsochLoopbackParams->ulLoopFlag & RESOURCE_USED_IN_LISTENING) {
PULONG pDescriptorData;
ULONG ulCurrData;
ULONG ulFlipValue;
BOOLEAN bValid = TRUE;
// get the point to the first descriptor
pR3TempDescriptor = &pIsochAttachBuffers->R3_IsochDescriptor[0];
for (i=0; i < pIsochAttachBuffers->nNumberOfDescriptors; i++) {
// set pDescriptorData to the first quadlet in the data packet.
// if we are not stripping quadlets on the listen, then this will
// start 2 quadlets (is this right??) into the data buffer
if ((pIsochLoopbackParams->ulLoopFlag & RESOURCE_USED_IN_LISTENING) &&
(pIsochLoopbackParams->ulLoopFlag & RESOURCE_STRIP_ADDITIONAL_QUADLETS)) {
pDescriptorData = (PULONG)&pR3TempDescriptor->Data;
}
else {
pDescriptorData = (PULONG)&pR3TempDescriptor->Data+2;
}
// set the first data byte we are looking for
ulCurrData = *(PULONG)pDescriptorData;
// we use this to determine if ulCurrData needs to be flipped to 0
ulFlipValue = pR3TempDescriptor->ulLength/sizeof(ULONG);
for (n=0; n < (pR3TempDescriptor->ulLength/sizeof(ULONG)); n++) {
if (*((PULONG)pDescriptorData+n) != ulCurrData) {
// here we need to check if we are in packet based. it is possible our
// actual data is smaller than the payload. i'm going to do a simple check
// if this quadlet equals 0. if so, then we will assume that it is correct
// and move onto the next quadlet.
if (pIsochLoopbackParams->ulLoopFlag & RESOURCE_USE_PACKET_BASED) {
// we're packet based, if quadlets doesn't equal 0, then fail...
if (*((PULONG)pDescriptorData+n)) {
bValid = FALSE;
TRACE(TL_ERROR, (pIsochLoopbackParams->hWnd, "Failed! = 0x%x\r\n", &pDescriptorData));
TRACE(TL_ERROR, (pIsochLoopbackParams->hWnd, "n = 0x%x\r\n", n));
TRACE(TL_ERROR, (pIsochLoopbackParams->hWnd, "ulCurrData = 0x%x\r\n", ulCurrData));
}
}
else {
// need to see if we are getting the header/trailer. if so, this is a real
// error, if not, then it might not be, since we're getting the header/trailer
// embedded in the packet.
if (pIsochLoopbackParams->ulLoopFlag & RESOURCE_STRIP_ADDITIONAL_QUADLETS) {
bValid = FALSE;
TRACE(TL_ERROR, (pIsochLoopbackParams->hWnd, "Failed! = 0x%x\r\n", &pDescriptorData));
TRACE(TL_ERROR, (pIsochLoopbackParams->hWnd, "n = 0x%x\r\n", n));
TRACE(TL_ERROR, (pIsochLoopbackParams->hWnd, "ulCurrData = 0x%x\r\n", ulCurrData));
}
else {
// not stripping, up the pointer by two and see if the quadlets match to
// what we expect next, if it doesn't, then we have an error
n = n+2;
if (*((PULONG)pDescriptorData+n) != ulCurrData) {
bValid = FALSE;
TRACE(TL_ERROR, (pIsochLoopbackParams->hWnd, "Failed! = 0x%x\r\n", &pDescriptorData));
TRACE(TL_ERROR, (pIsochLoopbackParams->hWnd, "n = 0x%x\r\n", n));
TRACE(TL_ERROR, (pIsochLoopbackParams->hWnd, "ulCurrData = 0x%x\r\n", ulCurrData));
}
}
}
}
if (!bValid)
break;
ulCurrData++;
if (ulCurrData == ulFlipValue)
ulCurrData = 0;
}
if (!bValid)
break;
pR3TempDescriptor =
(PRING3_ISOCH_DESCRIPTOR)((ULONG_PTR)pR3TempDescriptor +
pR3TempDescriptor->ulLength +
sizeof(RING3_ISOCH_DESCRIPTOR));
} // for
(bValid) ? pIsochLoopbackParams->ulPass++ : pIsochLoopbackParams->ulFail++;
} // if
else if (pIsochLoopbackParams->ulLoopFlag & RESOURCE_USED_IN_TALKING) {
// any check here??
pIsochLoopbackParams->ulPass++;
}
pIsochLoopbackParams->ulIterations++;
}
}
// if we reached our iteration count, then lets exit...
if (pIsochLoopbackParams->ulIterations == pIsochLoopbackParams->nIterations)
pIsochLoopbackParams->bKill = TRUE;
// see if we have been shut down
if (pIsochLoopbackParams->bKill) {
// we've been shutdown, lets see if we were in loopback mode
// if so, lets stop on this resource
if (pIsochLoopbackParams->bLoopback) {
ISOCH_STOP isochStop;
OVERLAPPED StopOverlapped;
StopOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
isochStop.hResource = isochAttachBuffers.hResource;
isochStop.fulFlags = 0;
DeviceIoControl( hDevice,
IOCTL_ISOCH_STOP,
&isochStop,
sizeof(ISOCH_STOP),
NULL,
0,
&dwBytesRet,
&StopOverlapped
);
CloseHandle(StopOverlapped.hEvent);
}
break;
}
} // while
} // if
Exit_IsochAttachThread:
// free up all resources
CloseHandle(hDevice);
CloseHandle(overLapped.hEvent);
if (pIsochAttachBuffers) {
if (!pIsochLoopbackParams->bLoopback) {
TRACE(TL_TRACE, (pIsochLoopbackParams->hWnd, "pIsochDescriptor = 0x%x\r\n", pIsochAttachBuffers->pIsochDescriptor));
}
if (pIsochLoopbackParams->bAutoAlloc)
LocalFree(pIsochAttachBuffers);
}
} // if hDevice
// if it's not loopback, then we need to free
// this buffer, since our attach allocates it
if (!pIsochLoopbackParams->bLoopback)
LocalFree(pIsochLoopbackParams);
TRACE(TL_TRACE, (NULL, "Exit IsochAttachThread\r\n"));
// that's it, shut this thread down
ExitThread(0);
return(0);
} // IsochAttachThread
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -