📄 asyncapi.c
字号:
while (TRUE) {
bFailed = FALSE;
// lets see what type of loopback this is. we'll go through and
// process and reads, writes, or locks...
// lets get our buffer size...
if (pLoopbackParams->ulLoopFlag & ASYNC_LOOPBACK_RANDOM_LENGTH) {
// generate a random value between 1 and nMaxBytes
ulBufferSize = rand() % pLoopbackParams->nMaxBytes;
ulBufferSize++;
}
else {
ulBufferSize = pLoopbackParams->nMaxBytes;
}
// write...
if ((!pLoopbackParams->bKill) && (pLoopbackParams->ulLoopFlag & ACCESS_FLAGS_TYPE_WRITE)) {
ULONG i;
// set the size/data buffer for our write
pAsyncWrite->nNumberOfBytesToWrite = ulBufferSize;
for (i=0; i<pAsyncWrite->nNumberOfBytesToWrite/sizeof(ULONG); i++) {
CopyMemory((ULONG *)&pAsyncWrite->Data+i, (ULONG *)&i, sizeof(ULONG));
}
dwRet = DeviceIoControl( hDevice,
IOCTL_ASYNC_WRITE,
pAsyncWrite,
sizeof(ASYNC_WRITE) + ulBufferSize,
pAsyncWrite,
sizeof(ASYNC_WRITE) + ulBufferSize,
&dwBytesRet,
NULL
);
if (!dwRet) {
dwRet = GetLastError();
TRACE(TL_ERROR, (pLoopbackParams->hWnd, "Error = 0x%x\r\n", dwRet));
TRACE(TL_ERROR, (pLoopbackParams->hWnd, "Write Failed\r\n"));
TRACE(TL_ERROR, (pLoopbackParams->hWnd, "pAsyncWrite = 0x%p\r\n", pAsyncWrite));
// test code, hard code debug spew here...
TRACE(TL_FATAL, (NULL, "Async Read Failed Error = 0x%x\r\n", dwRet));
TRACE(TL_FATAL, (NULL, "Bytes to write = 0x%x, offset high = 0x%x, offset low = 0x%x\r\n",
pAsyncWrite->nNumberOfBytesToWrite,
pAsyncWrite->DestinationAddress.IA_Destination_Offset.Off_High,
pAsyncWrite->DestinationAddress.IA_Destination_Offset.Off_Low));
// see if this is a generation error, if so, we'll assume
// a bus reset and continue
if (dwRet != ERROR_MR_MID_NOT_FOUND) {
// we had a failure, up the fail count...
if (dwRet != ERROR_OPERATION_ABORTED)
bFailed = TRUE;
}
else {
TRACE(TL_WARNING, (pLoopbackParams->hWnd, "Write - Invalid Generation!\r\n"));
}
}
} // write
// read
if ((!bFailed) && (!pLoopbackParams->bKill) && (pLoopbackParams->ulLoopFlag & ACCESS_FLAGS_TYPE_READ)) {
// set the size/data buffer for our read
pAsyncRead->nNumberOfBytesToRead = ulBufferSize;
FillMemory(&pAsyncRead->Data, ulBufferSize, 0);
dwRet = DeviceIoControl( hDevice,
IOCTL_ASYNC_READ,
pAsyncRead,
sizeof(ASYNC_READ) + ulBufferSize,
pAsyncRead,
sizeof(ASYNC_READ) + ulBufferSize,
&dwBytesRet,
NULL
);
if (!dwRet) {
dwRet = GetLastError();
TRACE(TL_ERROR, (pLoopbackParams->hWnd, "Error = 0x%x\r\n", dwRet));
TRACE(TL_ERROR, (pLoopbackParams->hWnd, "Read Failed\r\n"));
TRACE(TL_ERROR, (pLoopbackParams->hWnd, "pAsyncRead = 0x%p\r\n", pAsyncRead));
// test code, hard code debug spew here...
TRACE(TL_FATAL, (NULL, "Async Write Failed Error = 0x%x\r\n", dwRet));
TRACE(TL_FATAL, (NULL, "Bytes to write = 0x%x, offset high = 0x%x, offset low = 0x%x\r\n",
pAsyncRead->nNumberOfBytesToRead,
pAsyncRead->DestinationAddress.IA_Destination_Offset.Off_High,
pAsyncRead->DestinationAddress.IA_Destination_Offset.Off_Low));
// see if this is a generation error, if so, we'll assume
// a bus reset and continue
if (dwRet != ERROR_MR_MID_NOT_FOUND) {
// we had a failure, up the fail count...
if (dwRet != ERROR_OPERATION_ABORTED)
bFailed = TRUE;
}
else {
TRACE(TL_WARNING, (pLoopbackParams->hWnd, "Read - Invalid Generation!\r\n"));
}
}
else {
if (pLoopbackParams->ulLoopFlag & ACCESS_FLAGS_TYPE_WRITE) {
ULONG ulResult;
ulResult = memcmp(pAsyncWrite->Data, pAsyncRead->Data, ulBufferSize);
if (ulResult != 0)
bFailed = TRUE;
else
bFailed = FALSE;
if (bFailed) {
TRACE(TL_ERROR, (pLoopbackParams->hWnd, "ulResult = 0x%x\r\n", ulResult));
TRACE(TL_ERROR, (pLoopbackParams->hWnd, "bFailed = 0x%x\r\n", bFailed));
TRACE(TL_ERROR, (pLoopbackParams->hWnd, "pAsyncWrite = 0x%p\r\n", pAsyncWrite));
TRACE(TL_ERROR, (pLoopbackParams->hWnd, "pAsyncRead = 0x%p\r\n", pAsyncRead));
}
}
}
} // read
// lock
if ((!pLoopbackParams->bKill) && (pLoopbackParams->ulLoopFlag & ACCESS_FLAGS_TYPE_LOCK)) {
} // lock
// increment our counters...
if (!pLoopbackParams->bKill) {
if (bFailed)
pLoopbackParams->ulFail++;
else
pLoopbackParams->ulPass++;
pLoopbackParams->ulIterations++;
// if we reached our iteration count, then lets exit...
if (pLoopbackParams->ulIterations == pLoopbackParams->nIterations)
pLoopbackParams->bKill = TRUE;
}
// see if we have been shut down
if (pLoopbackParams->bKill) {
// we've been shutdown
break;
}
} // while
Exit_AsyncLoopbackThread:
// free up all resources
CloseHandle(hDevice);
if (pAsyncWrite)
LocalFree(pAsyncWrite);
if (pAsyncRead)
LocalFree(pAsyncRead);
// if (pAsyncLock)
// LocalFree(pAsyncLock);
} // if
// that's it, shut this thread down
ExitThread(0);
return(0);
} // AsyncLoopbackThread
void
WINAPI
AsyncStreamStartLoopback(
HWND hWnd,
PSTR szDeviceName,
PASYNC_STREAM_LOOPBACK_PARAMS streamLoopbackParams
)
{
streamLoopbackParams->szDeviceName = szDeviceName;
streamLoopbackParams->hWnd = hWnd;
streamLoopbackParams->bKill = FALSE;
streamLoopbackParams->hThread = CreateThread( NULL,
0,
AsyncStreamLoopbackThread,
(LPVOID)streamLoopbackParams,
0,
&streamLoopbackParams->ThreadId
);
} // AsyncStreamStartLoopback
void
WINAPI
AsyncStreamStopLoopback(
PASYNC_STREAM_LOOPBACK_PARAMS streamLoopbackParams
)
{
// close the handle
CloseHandle(streamLoopbackParams->hThread);
if (streamLoopbackParams->bKill)
return;
// kill the thread
streamLoopbackParams->bKill = TRUE;
} // AsyncStreamStopLoopback
DWORD
WINAPI
AsyncStreamLoopbackThread(
LPVOID lpParameter
)
{
PASYNC_STREAM_LOOPBACK_PARAMS pStreamLoopbackParams;
PASYNC_STREAM pAsyncStream;
HANDLE hDevice;
DWORD dwRet, dwBytesRet;
ULONG ulBufferSize;
OVERLAPPED overLapped;
ULONG i;
TRACE(TL_TRACE, (NULL, "Enter AsyncStreamLoopbackThread\r\n"));
// get pointer to our thread parameters
pStreamLoopbackParams = (PASYNC_STREAM_LOOPBACK_PARAMS)lpParameter;
// try to open the device
hDevice = OpenDevice(pStreamLoopbackParams->hWnd, pStreamLoopbackParams->szDeviceName, TRUE);
// device opened, so let's do loopback
if (hDevice != INVALID_HANDLE_VALUE) {
//
// if the bAutoAlloc flag is set, that means that we allocate according to
// the first descriptor. we assume there's only one configured descriptor
//
if (pStreamLoopbackParams->bAutoAlloc) {
// lets calculate the buffer size
ulBufferSize = sizeof(ASYNC_STREAM) +
pStreamLoopbackParams->asyncStream.nNumberOfBytesToStream;
pAsyncStream = (PASYNC_STREAM)LocalAlloc(LPTR, ulBufferSize);
if (!pAsyncStream) {
pStreamLoopbackParams->bKill = TRUE;
goto Exit_AsyncStreamLoopbackThread;
}
ZeroMemory(pAsyncStream, ulBufferSize);
*pAsyncStream = pStreamLoopbackParams->asyncStream;
}
else {
// we have already received an allocated buffer, let's just map it into
// our attach struct and pass it down.
pAsyncStream = &pStreamLoopbackParams->asyncStream;
ulBufferSize = sizeof(ASYNC_STREAM) + pAsyncStream->nNumberOfBytesToStream;
}
if (pAsyncStream) {
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 (pStreamLoopbackParams->bAutoFill) {
for (i=0; i < (pAsyncStream->nNumberOfBytesToStream/sizeof(ULONG)); i++) {
CopyMemory((ULONG *)&pAsyncStream->Data+i, (ULONG *)&i, sizeof(ULONG));
}
}
DeviceIoControl( hDevice,
IOCTL_ASYNC_STREAM,
pAsyncStream,
ulBufferSize,
pAsyncStream,
ulBufferSize,
&dwBytesRet,
&overLapped
);
dwRet = GetLastError();
TRACE(TL_TRACE, (NULL, "DeviceIoControl: dwRet = %d\r\n", dwRet));
if (dwRet != ERROR_SUCCESS) {
pStreamLoopbackParams->bKill = TRUE;
pStreamLoopbackParams->ulFail++;
}
else {
// we're doing a loopback test, so we need to increment our
// test values
if (!pStreamLoopbackParams->bKill) {
// any check here??
pStreamLoopbackParams->ulPass++;
}
pStreamLoopbackParams->ulIterations++;
}
// if we reached our iteration count, then lets exit...
if (pStreamLoopbackParams->ulIterations == pStreamLoopbackParams->nIterations)
pStreamLoopbackParams->bKill = TRUE;
// see if we have been shut down
if (pStreamLoopbackParams->bKill) {
break;
}
} // while
} // if
// free up all resources
CloseHandle(hDevice);
CloseHandle(overLapped.hEvent);
Exit_AsyncStreamLoopbackThread:
if ((pStreamLoopbackParams->bAutoAlloc) && (pAsyncStream))
LocalFree(pAsyncStream);
} // if hDevice
TRACE(TL_TRACE, (NULL, "Exit AsyncStreamLoopbackThread\r\n"));
// that's it, shut this thread down
ExitThread(0);
return(0);
} // AsyncStreamLoopbackThread
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -