xbox-kernel/private/ntos/dd/usb/mutest/mutest.cpp

560 lines
14 KiB
C++
Raw Normal View History

2001-01-01 00:00:00 +01:00
/*++
Copyright (c) 1996-2000 Microsoft Corporation
Module Name:
MUTEST.CPP
Abstract:
This source file contains a simple test code for the MU
Environment:
kernel mode
Revision History:
--*/
//*****************************************************************************
// I N C L U D E S
//*****************************************************************************
#include <xtl.h>
#include <xboxp.h>
#include <mutest.h>
#include <devioctl.h>
#include <ntdddisk.h>
#include <stdio.h>
#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
VOID
ReadWriteTest(
CHAR DriveLetter
);
VOID
ReadWriteScatterGatherTest(
CHAR DriveLetter
);
VOID
MUNameTest(
CHAR DriveLetter
);
VOID
DumpLogicalDriveList()
{
CHAR szDriveStrings[] = "D:\\\0F:\\\0G:\\\0H:\\\0I:\\\0J:\\\0K:\\\0L:\\\0M:\\\0T:\\\0U:\\\0X:\\";
LPSTR pszDrive;
DebugPrint("Logical drive list:");
pszDrive = szDriveStrings;
while ('\0' != *pszDrive)
{
ULARGE_INTEGER ullFreeAvail, ullFree, ullTotal;
if (GetDiskFreeSpaceEx(pszDrive, &ullFreeAvail, &ullTotal, &ullFree))
{
DebugPrint(" %s", pszDrive);
}
// Seek until next NULL:
while (L'\0' != *pszDrive)
{
pszDrive++;
}
// Skip over the NULL:
pszDrive++;
}
DebugPrint("\n");
}
VOID
WINAPI
GetDriveTypeTest()
{
CHAR szDriveStrings[] = "D:\\\0F:\\\0G:\\\0H:\\\0I:\\\0J:\\\0K:\\\0L:\\\0M:\\\0T:\\\0U:\\\0X:\\";
LPSTR pszDrive;
// GetDriveType test
DebugPrint("Logical drive list:\n");
pszDrive = szDriveStrings;
while (L'\0' != *pszDrive)
{
ULARGE_INTEGER ullFreeAvail, ullFree, ullTotal;
if (GetDiskFreeSpaceEx(pszDrive, &ullFreeAvail, &ullTotal, &ullFree))
{
CHAR szLabel[MAX_PATH], szFileSystem[MAX_PATH];
DWORD dwSerial, dwMaxNameLength, dwFSFlags;
// Shift into a dword (right shift 20 and label as MB) to we can print it out..
ullFreeAvail.LowPart = (ullFreeAvail.LowPart >> 20) | (ullFreeAvail.HighPart << 12);
ullTotal.LowPart = (ullTotal.LowPart >> 20) | (ullTotal.HighPart << 12);
ullFree.LowPart = (ullFree.LowPart >> 20) | (ullFree.HighPart << 12);
if (GetVolumeInformation(pszDrive,
szLabel,
ARRAYSIZE(szLabel),
&dwSerial,
&dwMaxNameLength,
&dwFSFlags,
szFileSystem,
ARRAYSIZE(szFileSystem)))
{
DebugPrint("Drive %s (label \"%s\", serial 0x%08x, maxname %lu, fsflags %lu, fs \"%s\")\n"
" (total %lu MB, free %lu MB, avail %lu MB)\n",
pszDrive, szLabel, dwSerial, dwMaxNameLength, dwFSFlags, szFileSystem,
ullTotal.LowPart, ullFree.LowPart, ullFreeAvail.LowPart);
}
else
{
DWORD dwErr = GetLastError();
DebugPrint("GetVolumeInformation() failed for %s: GetLastError()=0x%08x\n", pszDrive, dwErr);
}
}
// Seek until next NULL:
while (L'\0' != *pszDrive)
{
pszDrive++;
}
// Skip over the NULL:
pszDrive++;
}
DebugPrint("\n");
}
VOID
WINAPI
FindFirstFindNextTest(LPCSTR pcszFilter)
{
// FindFirstFile/FindNextFile/FindClose test
WIN32_FIND_DATA wfd;
HANDLE hFind = FindFirstFile(pcszFilter, &wfd);
if (INVALID_HANDLE_VALUE != hFind)
{
DebugPrint("Directory listing for %s\n", pcszFilter);
do
{
DebugPrint("%s, size=0x%08x, attributes=\n", wfd.cFileName,
wfd.nFileSizeLow, wfd.dwFileAttributes);
} while (FindNextFile(hFind, &wfd));
FindClose(hFind);
}
else
{
DWORD dwErr = GetLastError();
DebugPrint("FindFirstFile() failed for %s: GetLastError()=0x%08x\n", pcszFilter, dwErr);
}
DebugPrint("\n");
}
void __cdecl main()
{
DWORD err;
ULONG DeviceTypes = 0xFFFF0000;//USB_DEVICE_TYPE_MU;
CHAR szFilter[] = "C:\\*";
DWORD dwInsertions, dwRemovals;
int i;
DebugPrint("MUTEST: Built on %s at %s\n", __DATE__,__TIME__);
//Initialize core peripheral port support
XInitDevices(0,NULL);
DebugPrint("MUTEST: Polling for device insertions/removals..\n");
while (TRUE) {
if(XGetDeviceChanges(XDEVICE_TYPE_MEMORY_UNIT, &dwInsertions, &dwRemovals))
{
DebugPrint("MUTEST: Insertions 0x%08x, Removals 0x%08x\n", dwInsertions, dwRemovals);
for(i=0; i < 32; i++)
{
if(dwRemovals&(1 << i))
{
DWORD dwSlot;
DWORD dwPort;
if(i < 16)
{
dwPort = i;
dwSlot = XDEVICE_TOP_SLOT;
} else
{
dwPort = i-16;
dwSlot = XDEVICE_BOTTOM_SLOT;
}
XUnmountMU(dwPort, dwSlot);
}
//
// Handle Insertions
//
if(dwInsertions&(1 << i))
{
CHAR chDrive;
DWORD dwSlot;
DWORD dwPort;
if(i < 16)
{
dwPort = i;
dwSlot = XDEVICE_TOP_SLOT;
} else
{
dwPort = i-16;
dwSlot = XDEVICE_BOTTOM_SLOT;
}
if(dwPort >= 4)
{
DebugPrint("ERROR: MU in illegal port, p=%d, s=%s\n", dwPort, (XDEVICE_TOP_SLOT==dwSlot) ? "XDEVICE_TOP_SLOT" : "XDEVICE_BOTTOM_SLOT" );
}
LowLevelTest(dwPort, dwSlot);
DWORD dwErr = XMountMU(dwPort, dwSlot, &chDrive);
if (ERROR_SUCCESS == dwErr)
{
DebugPrint("XMountMU() succeeded, dr=%lc, p=%d, s=%d\n",
chDrive,
XMUPortFromDriveLetter(chDrive),
XMUSlotFromDriveLetter(chDrive));
GetDriveTypeTest();
szFilter[0] = chDrive;
FindFirstFindNextTest(szFilter);
ReadWriteTest(chDrive);
ReadWriteScatterGatherTest(chDrive);
FindFirstFindNextTest(szFilter);
MUNameTest(chDrive);
}
else
{
DebugPrint("XMountMU() failed, error = 0x%08x\n", dwErr);
}
}
} // for loop
DumpLogicalDriveList();
} // if
} // while
}
#define TEST_BUFFER_SIZE 8192
#define EXTRA_SIZE 8192
#define SECTOR_MASK 0xFFFFE000
VOID
ReadWriteTest(
CHAR DriveLetter
)
{
ULONG tryCount = 0;
CHAR name[64];
HRESULT hr;
HANDLE hFile;
PUCHAR buffer,buffer2;
UCHAR pattern[4] = {1,2,3,4};
ULONG i;
sprintf(name,"C:\\test.dat");
name[0] = DriveLetter;
hFile = CreateFile(name,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_FLAG_WRITE_THROUGH,
NULL,
OPEN_ALWAYS,
0,
NULL);
if(INVALID_HANDLE_VALUE == hFile) {
hr = GetLastError();
return;
}
buffer = (PUCHAR)LocalAlloc(LPTR, TEST_BUFFER_SIZE+EXTRA_SIZE);
buffer2 = (PUCHAR)LocalAlloc(LPTR, TEST_BUFFER_SIZE+EXTRA_SIZE);
//
// sector align buffers
//
buffer = (PUCHAR)((ULONG) buffer & SECTOR_MASK);
buffer += EXTRA_SIZE;
buffer2 = (PUCHAR)((ULONG) buffer2 & SECTOR_MASK);
buffer2 += EXTRA_SIZE;
//
// fill the buffer with a pattern
//
for (i=0;i<TEST_BUFFER_SIZE;i+=sizeof(pattern)) {
RtlCopyMemory(buffer+i,pattern,sizeof(pattern));
}
DebugPrint("MUTEST: Test buffer 1 at %x, 2 at %x\n",buffer,buffer2);
DebugPrint("MUTEST: Writing pattern to file\n");
//
// write the pattern to the file, close the file then read it
//
if (!WriteFile(hFile,
buffer,
TEST_BUFFER_SIZE,
&i,
NULL)) {
hr = GetLastError();
DebugPrint("MUTEST: Write Failed with %x\n",hr);
LocalFree(buffer);
LocalFree(buffer2);
}
DebugPrint("MUTEST: Closing file\n");
//
// close the file
//
CloseHandle(hFile);
DebugPrint("MUTEST: Re-opening file\n");
//
// open the file and read from it
//
hFile = CreateFile(name,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_FLAG_NO_BUFFERING,
NULL,
OPEN_ALWAYS,
0,
NULL);
if(INVALID_HANDLE_VALUE == hFile) {
hr = GetLastError();
return;
}
DebugPrint("MUTEST: Reading pattern to file\n");
if (!ReadFile(hFile,
buffer2,
TEST_BUFFER_SIZE,
&i,
NULL)) {
hr = GetLastError();
DebugPrint("MUTEST: Read Failed with %x\n",hr);
LocalFree(buffer);
LocalFree(buffer2);
}
CloseHandle(hFile);
DebugPrint("MUTEST: Success: Test buffer at %x\n",buffer);
}
#define PAGE_SIZE 4096
#define TEST_SG_BUFFER_SIZE (PAGE_SIZE * 5)
VOID
ReadWriteScatterGatherTest(
CHAR DriveLetter
)
{
ULONG tryCount = 0;
CHAR name[64];
HRESULT hr;
HANDLE hFile;
PUCHAR buffer,buffer2;
FILE_SEGMENT_ELEMENT sg1[TEST_SG_BUFFER_SIZE / PAGE_SIZE + 1];
FILE_SEGMENT_ELEMENT sg2[TEST_SG_BUFFER_SIZE / PAGE_SIZE + 1];
UCHAR pattern[4] = {1,2,3,4};
ULONG i;
OVERLAPPED ov;
sprintf(name,"C:\\testsg.dat");
name[0] = DriveLetter;
hFile = CreateFile(name,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_FLAG_WRITE_THROUGH,
NULL,
OPEN_ALWAYS,
FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING,
NULL);
if(INVALID_HANDLE_VALUE == hFile) {
hr = GetLastError();
return;
}
buffer = (PUCHAR)VirtualAlloc(NULL,TEST_SG_BUFFER_SIZE,MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
buffer2 = (PUCHAR)VirtualAlloc(NULL,TEST_SG_BUFFER_SIZE,MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
ZeroMemory(sg1, sizeof(sg1));
ZeroMemory(sg2, sizeof(sg2));
for (i = 0; i < TEST_SG_BUFFER_SIZE / PAGE_SIZE; i++) {
sg1[i].Buffer = buffer + i * PAGE_SIZE;
sg2[i].Buffer = buffer2 + i * PAGE_SIZE;
}
//
// fill the buffer with a pattern
//
for (i=0;i<TEST_SG_BUFFER_SIZE;i+=sizeof(pattern)) {
RtlCopyMemory(buffer+i,pattern,sizeof(pattern));
}
DebugPrint("MUTEST: Scatter/gather test\n");
DebugPrint("MUTEST: Test S/G buffer 1 at %x, 2 at %x\n",buffer,buffer2);
DebugPrint("MUTEST: Writing pattern to file\n");
//
// write the pattern to the file, close the file then read it
//
ZeroMemory(&ov, sizeof(ov));
if (!WriteFileGather(hFile,
sg1,
TEST_SG_BUFFER_SIZE,
NULL,
&ov)) {
hr = GetLastError();
if (hr != ERROR_IO_PENDING ||
!GetOverlappedResult(hFile, &ov, &i, TRUE)) {
hr = GetLastError();
DebugPrint("MUTEST: Write Failed with %x\n",hr);
}
}
DebugPrint("MUTEST: Closing file\n");
//
// close the file
//
CloseHandle(hFile);
DebugPrint("MUTEST: Re-opening file\n");
//
// open the file and read from it
//
hFile = CreateFile(name,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_FLAG_NO_BUFFERING,
NULL,
OPEN_ALWAYS,
FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING,
NULL);
if(INVALID_HANDLE_VALUE == hFile) {
hr = GetLastError();
return;
}
DebugPrint("MUTEST: Reading pattern to file\n");
ZeroMemory(&ov, sizeof(ov));
if (!ReadFileScatter(hFile,
sg2,
TEST_SG_BUFFER_SIZE,
NULL,
&ov)) {
hr = GetLastError();
if (hr != ERROR_IO_PENDING ||
!GetOverlappedResult(hFile, &ov, &i, TRUE)) {
hr = GetLastError();
DebugPrint("MUTEST: Read Failed with %x\n",hr);
}
}
CloseHandle(hFile);
DebugPrint("MUTEST: Success: Test S/G buffer at %x\n",buffer);
}
VOID
MUNameTest(
CHAR DriveLetter
)
{
DWORD error;
WCHAR MUName[MAX_MUNAME];
RtlFillMemory(MUName, sizeof(MUName), 0xCC);
error = XMUWriteNameToDriveLetter(DriveLetter, L"Test Name");
if (error != ERROR_SUCCESS) {
DebugPrint("MUTEST: Failed to write MU name with %x\n", error);
}
error = XMUNameFromDriveLetter(DriveLetter, MUName, MAX_MUNAME);
if (error == ERROR_SUCCESS) {
if (lstrcmpW(MUName, L"Test Name") != 0) {
DebugPrint("MUTEST: Failed to read back correct MU name\n");
}
} else {
DebugPrint("MUTEST: Failed to read MU name with %x\n", error);
}
}