⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isochapi.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 4 页
字号:

                *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 + -