📄 testpdma.c
字号:
errorCode = GetLastError();
printf("GetQueuedCompletionStatus failed %d \n", errorCode);
PrintError(errorCode);
return errorCode;
}
if (!ovCompletion) {
printf("NULL value returned for overlapped structure \n");
return ERROR_GEN_FAILURE;
}
//
// Decrement the pending count.
//
pendingCount--;
//
// Since the overlapped structure is at the beginning of the
// concurrent I/O structure, we can safely cast this to get
// the total concurrent I/O structure.
//
tempBufferInfo = (PBUFFER_INFO)ovCompletion;
#ifdef OVERLY_VERBOSE
//
// Don't print this stuff unless you really, really, really (did I
// mention "really") want a lot of info displayed.
//
if (verboseMode) {
printf("I/O # %2d completed \n", tempBufferInfo->Overlapped.Offset);
}
#endif
//
// Start the I/O again.
//
if (!ReadFile(FileHandle,
tempBufferInfo->DataBuffer,
tempBufferInfo->Length,
&bytesReturned,
&tempBufferInfo->Overlapped
)) {
errorCode = GetLastError();
if (errorCode == ERROR_IO_PENDING) {
#ifdef OVERLY_VERBOSE
//
// As before...
// Don't print this stuff unless you really, really, really (did I
// mention "really") want a lot of info displayed.
//
if (verboseMode) {
printf("I/O # %2d started \n", tempBufferInfo->Overlapped.Offset);
}
#endif
pendingCount++;
} else {
printf("ReadFile for buffer %d failed \n", i);
}
} else {
printf("ReadFile completed for buffer %d \n", i);
}
//
// Count this I/O.
//
totalCount++;
if (totalCount >= 1000 && (totalCount % 1000 == 0)) {
printf("Total count %d \n", totalCount);
}
}
//
// Wait for the remainder of the I/Os to drain from the device.
//
printf("End: %d I/Os pending \n", pendingCount);
printf("Waiting for the queue to drain... \n");
while (pendingCount > 0) {
if (!GetQueuedCompletionStatus(completionPort,
&bytesReturned,
&keyCompletion,
&ovCompletion,
INFINITE
)) {
errorCode = GetLastError();
printf("GetQueuedCompletionStatus failed %d \n", errorCode);
PrintError(errorCode);
return errorCode;
}
if (!ovCompletion) {
printf("NULL value returned for overlapped structure \n");
return ERROR_GEN_FAILURE;
}
//
// Since the overlapped structure is at the beginning of the
// concurrent I/O structure, we can safely cast this to get
// the total concurrent I/O structure.
//
tempBufferInfo = (PBUFFER_INFO)ovCompletion;
if (verboseMode) {
printf("I/O # %2d completed \n", tempBufferInfo->Overlapped.Offset);
}
//
// Decrement the pending count.
//
pendingCount--;
}
printf("%d reads completed \n", totalCount);
return NO_ERROR;
} // DoAsyncIo
DWORD
FillInDataStructures(
IN PBUFFER_INFO BufferInfo,
IN USHORT NumberOfBuffers,
IN PUSER_PARMS UserParms
)
{
DWORD errorCode = NO_ERROR;
DWORD bufferSize;
USHORT i;
BOOLEAN verboseMode;
verboseMode = UserParms->Flags & FLAG_VERBOSE_MODE;
if (verboseMode) {
printf("Creating concurrent data buffers \n");
}
//
// First, clear out the data structures.
//
ZeroMemory(BufferInfo, NumberOfBuffers * sizeof(BUFFER_INFO));
//
// For each concurrent I/O structure, fill in the info.
//
bufferSize = LARGE_BUFFER_SIZE;
for (i = 0; i < NumberOfBuffers; i++) {
//
// Allocate a data buffer.
//
BufferInfo->DataBuffer = VirtualAlloc(NULL,
bufferSize,
MEM_COMMIT,
PAGE_READWRITE
);
//
// On error, break out of here.
//
if (BufferInfo->DataBuffer == NULL) {
errorCode = GetLastError();
break;
}
BufferInfo->Length = bufferSize;
if (verboseMode) {
printf("Buffer %2d at 0x%08x length 0x%08x \n",
i,
BufferInfo->DataBuffer,
BufferInfo->Length
);
}
//
// Fill the data buffer with a pattern.
//
FillMemory(BufferInfo->DataBuffer,
BufferInfo->Length,
FILL_MEMORY_BYTE
);
//
// The offset will indicate which buffer is completed, so
// it can be restarted.
//
BufferInfo->Overlapped.Offset = i;
BufferInfo->Overlapped.OffsetHigh = 0;
BufferInfo->Overlapped.hEvent = NULL;
//
// Point to the next concurrent I/O structure.
//
BufferInfo++;
//
// Use different size buffers.
//
if (LARGE_BUFFER_SIZE == bufferSize) {
bufferSize = MEDIUM_BUFFER_SIZE;
} else if (MEDIUM_BUFFER_SIZE == bufferSize) {
bufferSize = SMALL_BUFFER_SIZE;
} else {
bufferSize = LARGE_BUFFER_SIZE;
}
}
if (NO_ERROR != errorCode) {
ReleaseBuffers(BufferInfo,
NumberOfBuffers
);
}
return errorCode;
} // FillInDataStructures
DWORD
NonOverlappedTests(
IN LPCTSTR DeviceName
)
{
LPVOID dataBuffer;
HANDLE fileHandle;
DWORD errorCode;
//
// Allocate the data buffer.
//
dataBuffer = VirtualAlloc(NULL,
MAX_DATA_BUFFER,
MEM_COMMIT,
PAGE_READWRITE
);
if (!dataBuffer) {
errorCode = GetLastError();
printf("VirtualAlloc failed %d \n", errorCode);
PrintError(errorCode);
return errorCode;
}
//
// Open the device.
//
fileHandle = CreateFile(DeviceName,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (fileHandle == INVALID_HANDLE_VALUE) {
errorCode = GetLastError();
printf("Unable to open device. Error: %d \n", errorCode);
PrintError(errorCode);
//
// Free the data buffer on error.
//
if (!VirtualFree(dataBuffer,
MAX_DATA_BUFFER,
MEM_DECOMMIT
)) {
printf("VirtualFree failed \n");
PrintError(GetLastError());
}
return errorCode;
}
//
// Try an invalid read. Zero buffer size.
//
printf("Trying ReadFile with zero buffer size... \n");
printf("*** Failure is OK *** \n");
ReadTest(fileHandle,
dataBuffer,
0
);
//
// Another invalid read. The data buffer size is too large for the device
// capabilities.
//
printf("Trying ReadFile with buffer size greater than device capabilities... \n");
printf("*** Failure is OK *** \n");
ReadTest(fileHandle,
dataBuffer,
MAX_DATA_BUFFER
);
//
// Try a valid read.
//
printf("Trying a valid ReadFile... \n");
ReadTest(fileHandle,
dataBuffer,
VALID_READ_SIZE
);
//
// Close device handle.
//
CloseHandle(fileHandle);
//
// Free the data buffer.
//
if (!VirtualFree(dataBuffer,
MAX_DATA_BUFFER,
MEM_DECOMMIT
)) {
printf("VirtualFree failed \n");
PrintError(GetLastError());
}
return NO_ERROR;
} // NonOverlappedTests
VOID
PrintError(
IN DWORD ErrorCode
)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -