mirror of
https://github.com/arehnman/yttrium-virtio-gpu.git
synced 2026-11-07 02:06:32 +00:00
The current code doesn't work. If the supplied output buffer is too small, the caller does not receive the required size in lpBytesReturned as intended. Relevant blog post: http://bit.ly/1NxJik3 I am simply switching to a reasonably sized fixed buffer on the calling side, exactly what SerialPort::SerialPort() does. The IOCTL implementation is tweaked to make it clear that the buffer size is not communicated back on failure.
245 lines
4.3 KiB
C++
245 lines
4.3 KiB
C++
//#include <basetyps.h>
|
|
#include "device.h"
|
|
#include "assert.h"
|
|
|
|
#pragma warning(default:4201)
|
|
|
|
BOOL
|
|
GetInfoTest(
|
|
__in CDevice *pDev
|
|
)
|
|
{
|
|
BYTE buf[512];
|
|
PVIRTIO_PORT_INFO inf = NULL;
|
|
size_t len = sizeof(buf);
|
|
|
|
if (!pDev) return FALSE;
|
|
|
|
if (!pDev->GetInfo(buf, &len))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
inf = (PVIRTIO_PORT_INFO)buf;
|
|
printf("Id = %d\n", inf->Id);
|
|
printf("OutVqFull = %d\n", inf->OutVqFull);
|
|
printf("HostConnected = %d\n", inf->HostConnected);
|
|
printf("GuestConnected = %d\n", inf->GuestConnected);
|
|
if (len > sizeof(VIRTIO_PORT_INFO) && inf->Name[0])
|
|
{
|
|
printf("Id = %s\n", inf->Name);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
WriteTest(
|
|
__in CDevice *pDev,
|
|
__in BOOLEAN ovrl
|
|
)
|
|
{
|
|
PUCHAR buf = NULL;
|
|
BOOLEAN res = TRUE;
|
|
int i;
|
|
size_t size = 4096;
|
|
|
|
if (!pDev) return FALSE;
|
|
|
|
printf("%s.\n", __FUNCTION__);
|
|
|
|
|
|
buf = (PUCHAR)GlobalAlloc(0, size);
|
|
|
|
if( buf == NULL )
|
|
{
|
|
printf("%s: Could not allocate %d "
|
|
"bytes buf\n", __FUNCTION__, size);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
for(i = 0 ;i < (int)size; i++)
|
|
{
|
|
int ch = getchar();
|
|
|
|
buf[i] = (char)ch;
|
|
if (ch == '\n') break;
|
|
}
|
|
size = i;
|
|
res = ovrl ? pDev->WriteEx(buf, &size) : pDev->Write(buf, &size);
|
|
|
|
if (!res)
|
|
{
|
|
printf ("%s: WriteFile failed: "
|
|
"Error %d\n", __FUNCTION__, GetLastError());
|
|
}
|
|
else
|
|
{
|
|
printf ("%s: WriteFile OK: "
|
|
"snd %d bytes\n\n", __FUNCTION__, size);
|
|
printf ("%s\n", buf);
|
|
}
|
|
|
|
GlobalFree(buf);
|
|
|
|
return res;
|
|
}
|
|
|
|
BOOL
|
|
WriteTestCycl(
|
|
__in CDevice *pDev,
|
|
__in BOOLEAN ovrl
|
|
)
|
|
{
|
|
int ch;
|
|
for (;;)
|
|
{
|
|
if(!WriteTest(pDev, ovrl)) return FALSE;
|
|
ch = getchar();
|
|
if(ch == EOF) break;
|
|
putchar(ch);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
ReadTest(
|
|
__in CDevice *pDev,
|
|
__in BOOLEAN ovrl
|
|
)
|
|
{
|
|
PUCHAR buf = NULL;
|
|
BOOLEAN res = TRUE;
|
|
|
|
size_t size = 4096;
|
|
|
|
if (!pDev) return FALSE;
|
|
|
|
printf("%s.\n", __FUNCTION__);
|
|
|
|
|
|
buf = (PUCHAR)GlobalAlloc(0, size);
|
|
|
|
if( buf == NULL )
|
|
{
|
|
printf("%s: Could not allocate %d "
|
|
"bytes buf\n", __FUNCTION__, size);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
res = ovrl ? pDev->ReadEx(buf, &size) : pDev->Read(buf, &size);
|
|
|
|
if (!res)
|
|
{
|
|
printf ("%s: ReadFile failed: "
|
|
"Error %d\n", __FUNCTION__, GetLastError());
|
|
}
|
|
else
|
|
{
|
|
printf ("%s: ReadFile OK: "
|
|
"rcv %d bytes\n\n", __FUNCTION__, size);
|
|
printf ("%s\n", buf);
|
|
}
|
|
|
|
GlobalFree(buf);
|
|
|
|
return res;
|
|
}
|
|
|
|
BOOL
|
|
ReadTestCycl(
|
|
__in CDevice *pDev,
|
|
__in BOOLEAN ovrl
|
|
)
|
|
{
|
|
int ch;
|
|
for (;;)
|
|
{
|
|
if(!ReadTest(pDev, ovrl)) return FALSE;
|
|
if(_kbhit())
|
|
{
|
|
ch = getchar();
|
|
if(ch == EOF) break;
|
|
putchar(ch);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
ULONG
|
|
_cdecl
|
|
wmain(
|
|
__in ULONG argc,
|
|
__in_ecount(Argc) PWCHAR argv[]
|
|
)
|
|
{
|
|
int ch;
|
|
CDevice *m_pDev;
|
|
BOOLEAN stoptest = FALSE;
|
|
BOOLEAN ovrl = TRUE;
|
|
|
|
if(argc == 2)
|
|
{
|
|
if (_wcsicmp(L"-n", argv[1]) == 0) {
|
|
ovrl = FALSE;
|
|
}
|
|
}
|
|
|
|
if (ovrl)
|
|
{
|
|
printf("Running in non-blocking mode.\n");
|
|
}
|
|
else
|
|
{
|
|
printf("Running in blocking mode.\n");
|
|
}
|
|
|
|
m_pDev = new CDevice;
|
|
if (!m_pDev)
|
|
{
|
|
return 1;
|
|
}
|
|
if (!m_pDev->Init(ovrl))
|
|
{
|
|
delete m_pDev;
|
|
return 2;
|
|
}
|
|
|
|
while (!stoptest)
|
|
{
|
|
ch = getchar();
|
|
while(getchar()!='\n');
|
|
switch (ch)
|
|
{
|
|
case 'i':
|
|
case 'I':
|
|
GetInfoTest(m_pDev);
|
|
break;
|
|
case 'r':
|
|
case 'R':
|
|
ReadTest(m_pDev, ovrl);
|
|
break;
|
|
case 'f':
|
|
case 'F':
|
|
ReadTestCycl(m_pDev, ovrl);
|
|
break;
|
|
case 'w':
|
|
case 'W':
|
|
WriteTest(m_pDev, ovrl);
|
|
break;
|
|
case 's':
|
|
case 'S':
|
|
WriteTestCycl(m_pDev, ovrl);
|
|
break;
|
|
case 'q':
|
|
case 'Q':
|
|
stoptest = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
delete m_pDev;
|
|
return 0;
|
|
}
|