summaryrefslogtreecommitdiff
path: root/spb/SpbTestTool/exe/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'spb/SpbTestTool/exe/main.cpp')
-rw-r--r--spb/SpbTestTool/exe/main.cpp633
1 files changed, 0 insertions, 633 deletions
diff --git a/spb/SpbTestTool/exe/main.cpp b/spb/SpbTestTool/exe/main.cpp
deleted file mode 100644
index ce9e994a..00000000
--- a/spb/SpbTestTool/exe/main.cpp
+++ /dev/null
@@ -1,633 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
-Module Name:
-
- main.cpp
-
-Abstract:
-
- This module contains the main entry point for the SpbTestTool
- app. It facilitates accepting input, building commands, and
- printing output.
-
-Environment:
-
- user-mode
-
-Revision History:
-
---*/
-
-#include "internal.h"
-
-DWORD WINAPI InterruptNotificationThread(
- _In_ LPVOID pvData
- );
-
-bool
-ReadCommandFromStream(
- _In_ FILE* InputStream,
- _Inout_ list<string> *Tokens
- );
-
-VOID
-PrintUsage(
- _In_ PCSTR exeName
- );
-
-DWORD
-RunCommand(
- _In_ PCCommand Command
- );
-
-HANDLE g_Peripheral = nullptr;
-HANDLE g_Event = nullptr;
-HANDLE g_InterruptNotificationThread = nullptr;
-PCCommand g_CurrentCommand = nullptr;
-bool g_WaitOnInterrupt = true;
-
-BOOL
-WINAPI
-OnControlKey(
- _In_ DWORD ControlType
- );
-
-void
-__cdecl
-main(
- _In_ ULONG ArgumentsCe,
- _In_reads_(ArgumentsCe) PCSTR Arguments[]
- )
-{
- FILE* inputStream = stdin;
- bool prompt = true;
-
- PCSTR peripheralPath = nullptr;
- PCSTR inputPath = nullptr;
-
- //
- // Parse the command line arguments.
- //
-
- ULONG arg = 1;
-
- while (arg < ArgumentsCe)
- {
- if ((Arguments[arg][0] != '/') &&
- (Arguments[arg][0] != '-'))
- {
- PrintUsage(Arguments[0]);
- goto exit;
- }
- else
- {
- if (tolower(Arguments[arg][1]) == 'p')
- {
- arg++;
- if (arg == ArgumentsCe)
- {
- PrintUsage(Arguments[0]);
- goto exit;
- }
- peripheralPath = Arguments[arg];
- }
- else if (tolower(Arguments[arg][1]) == 'i')
- {
- arg++;
- if (arg == ArgumentsCe)
- {
- PrintUsage(Arguments[0]);
- goto exit;
- }
- inputPath = Arguments[arg];
- }
- else
- {
- PrintUsage(Arguments[0]);
- goto exit;
- }
- }
-
- arg++;
- }
-
- //
- // Open the input file if specified
- //
-
- if (inputPath != nullptr)
- {
- errno_t error;
-
- printf("Opening %s as command input file\n", inputPath);
- error = fopen_s(&inputStream, inputPath, "r");
-
- if (error != 0)
- {
- printf("Error opening input file %s - %d\n", inputPath, error);
- goto exit;
- }
-
- if (inputStream == nullptr)
- {
- printf("Error opening input file %s - %d\n", inputPath, error);
- goto exit;
- }
-
- prompt = false;
- }
-
- //
- // Open peripheral driver
- //
-
- if (peripheralPath == nullptr)
- {
- g_Peripheral = CreateFileW(
- SPBTESTTOOL_USERMODE_PATH,
- (GENERIC_READ | GENERIC_WRITE),
- 0,
- nullptr,
- OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED,
- nullptr);
- }
- else
- {
- printf("Opening %s as peripheral driver path \n", peripheralPath);
- g_Peripheral = CreateFileA(
- peripheralPath,
- (GENERIC_READ | GENERIC_WRITE),
- 0,
- nullptr,
- OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED,
- nullptr);
- }
-
- if (g_Peripheral == INVALID_HANDLE_VALUE)
- {
- printf("Error opening peripheral driver - %u\n", GetLastError());
- goto exit;
- }
-
- setvbuf(inputStream, nullptr, _IONBF, 0);
- setvbuf(stdout, nullptr, _IONBF, 0);
- setvbuf(stderr, nullptr, _IONBF, 0);
-
- //
- // Setup a control-C handler.
- //
-
- if (SetConsoleCtrlHandler(OnControlKey, true) == FALSE)
- {
- printf("Error setting ctrl-C handler - %u\n", GetLastError());
- goto exit;
- }
-
- //
- // Setup an overlapped structure to use with each I/O.
- //
-
- g_Event = CreateEvent(nullptr, true, false, nullptr);
-
- if (g_Event == nullptr)
- {
- printf("error creating I/O event - %u\n", GetLastError());
- goto exit;
- }
-
- //
- // Create interrupt notification thread.
- //
-
- g_InterruptNotificationThread = CreateThread(
- nullptr,
- 0,
- &InterruptNotificationThread,
- nullptr,
- 0,
- nullptr);
-
- if (g_InterruptNotificationThread == nullptr)
- {
- printf("error creating interrupt notification thread - %u\n", GetLastError());
- goto exit;
- }
-
- //
- // Loop reading commands off the command line and parsing them.
- // EOF causes an exit.
- //
-
- do
- {
- list<string> *tokens = new list<string>();
- PCCommand command;
-
- if (prompt)
- {
- printf("> ");
- fflush(stdout);
- }
-
- if (ReadCommandFromStream(inputStream, tokens) == false)
- {
- delete tokens;
- break;
- }
-
- if (tokens->empty())
- {
- delete tokens;
- continue;
- }
-
- command = CCommand::_ParseCommand(tokens);
-
- if (command == nullptr)
- {
- delete tokens;
- continue;
- }
-
- g_CurrentCommand = command;
-
- RunCommand(command);
-
- g_CurrentCommand = nullptr;
-
- //
- // A reference to the tokens list is saved by
- // the command and will be freed when the command
- // is deleted.
- //
-
- delete command;
-
- }
- while (feof(inputStream) == 0);
-
-exit:
-
- if (prompt == false)
- {
- fclose(inputStream);
- }
-
- if (g_InterruptNotificationThread != nullptr)
- {
- WaitForSingleObject(g_InterruptNotificationThread, INFINITE);
- CloseHandle(g_InterruptNotificationThread);
- }
-
- CloseHandle(g_Peripheral);
-
- if (g_Event != nullptr)
- {
- CloseHandle(g_Event);
- }
-
- return;
-}
-
-DWORD WINAPI InterruptNotificationThread(
- _In_ LPVOID pvData
- )
-{
- DWORD status;
- DWORD bytesReturned;
- OVERLAPPED ov = {0};
-
- UNREFERENCED_PARAMETER(pvData);
-
- ov.hEvent = CreateEvent(nullptr, false, false, nullptr);
-
- if (ov.hEvent == nullptr)
- {
- printf("error creating overlapped event for interrupt thread - %u\n", GetLastError());
- goto exit;
- }
-
- while (g_WaitOnInterrupt == true)
- {
- if ((DeviceIoControl(
- g_Peripheral,
- IOCTL_SPBTESTTOOL_WAIT_ON_INTERRUPT,
- nullptr,
- 0,
- nullptr,
- 0,
- nullptr,
- &ov) == TRUE) ||
- (GetLastError() != ERROR_IO_PENDING))
- {
- printf("failed to pend WaitOnInterrupt IOCTL- %u\n", GetLastError());
- goto exit;
- }
-
- status = WaitForSingleObject(ov.hEvent, INFINITE);
-
- switch (status)
- {
- // DeviceIoControl completed.
- case WAIT_OBJECT_0:
-
- if (!GetOverlappedResult(g_Peripheral, &ov, &bytesReturned, FALSE))
- {
- printf("GetOverlappedResult failed with status: %u\n\n", GetLastError());
- }
- else
- {
- printf("\n\n");
- printf(" ** Interrupt detected. Please acknowledge or disable **\n");
- printf(" *** and type 'signal' to inform the SpbTestTool driver ***\n");
- printf(" ** that the interrupt has been handled. **\n");
- printf("\n");
- }
- break;
-
- default:
- // Error in the WaitForSingleObject; abort.
- // This indicates a problem with the OVERLAPPED
- // structure's event handle.
- printf("WaitOnInterrupt unexpected return %u\n\n", status);
- break;
- }
- }
-
-exit:
-
- return 0;
-}
-
-VOID
-PrintUsage(
- _In_ PCSTR exeName
- )
-{
- printf("Usage: %s [/p <driver_path>] [/i <script_name>]\n",
- exeName);
-}
-
-DWORD
-RunCommand(
- _In_ PCCommand Command
- )
-{
-
- DWORD status;
- DWORD bytesTransferred;
-
- Command->Overlapped.hEvent = g_Event;
-
- if (Command->Execute() == true)
- {
- if (GetOverlappedResult(Command->File,
- &(Command->Overlapped),
- &bytesTransferred,
- true) == FALSE)
- {
- status = GetLastError();
- }
- else
- {
- status = NO_ERROR;
- }
-
- Command->Complete(status, bytesTransferred);
- }
- else
- {
- status = GetLastError();
- }
-
- return status;
-}
-
-
-bool
-ReadLine(
- _In_ FILE* InputStream,
- _In_ ULONG BufferCch,
- _Out_writes_(BufferCch) CHAR Buffer[]
- )
-{
- ULONG i;
-
- for(i = 0; i < BufferCch - 1; i += 1)
- {
- if (fread(&(Buffer[i]), sizeof(CHAR), 1, InputStream) == 0)
- {
- return false;
- }
-
- fputc(Buffer[i], stdout);
-
- if (Buffer[i] == '\n')
- {
- Buffer[i] = '\0';
- return true;
- }
- else if (Buffer[i] == '\b')
- {
- Buffer[i] = '\0';
- i -= 2;
- }
- }
-
- return false;
-}
-
-bool
-ReadCommandFromStream(
- _In_ FILE* InputStream,
- _Inout_ list<string> *Tokens
- )
-{
- CHAR buffer[255];
-
- if (ReadLine(InputStream,
- sizeof(buffer) - 1,
- buffer) == false)
- {
- return false;
- }
-
- string currentLine(buffer);
- string token;
-
- list<string> tokens;
-
- Tokens->clear();
-
- string::size_type i;
- long start;
-
- for(i = 0, start = -1;
- i < currentLine.length() + 1;
- i += 1)
- {
- wchar_t c;
-
- if (i < currentLine.length())
- {
- c = currentLine[i];
- }
- else
- {
- c = L'\0';
- }
-
- if (iswspace(c) || (c == L'\0'))
- {
- if (start == -1)
- {
- //
- // not tracking a token - whitespace is skipped.
- //
- }
- else
- {
- //
- // tracking a token - whitespace or NUL terminates it.
- // if the last character was a } then split the token.
- //
-
- if (currentLine[i-1] == '}')
- {
- token.assign(currentLine, start, i - start - 1);
- Tokens->insert(Tokens->end(), token);
- Tokens->insert(Tokens->end(), string("}"));
- }
- else
- {
- token.assign(currentLine, start, i - start);
- Tokens->insert(Tokens->end(), token);
- }
-
- start = -1;
- }
- }
- else if (start == -1)
- {
- //
- // first character of a token. If it's { then split the token.
- //
-
- if (currentLine[i] == '{')
- {
- Tokens->insert(Tokens->end(), string("{"));
- }
- else if (currentLine[i] == '}')
- {
- Tokens->insert(Tokens->end(), string("}"));
- }
- else
- {
- start = (long) i;
- }
- }
- else
- {
- //
- // tracking a token - non whitespace is included.
- //
- }
- }
-
- return true;
-}
-
-VOID
-PrintBytes(
- _In_ ULONG BufferCb,
- _In_reads_bytes_(BufferCb) BYTE Buffer[]
- )
-{
- ULONG index = 0;
-
- for(index = 0; index < BufferCb; index += 16)
- {
- printf(" ");
- for(ULONG i = index; i < (index + 16); i += 1)
- {
- if (i < BufferCb)
- {
- if ((i != index) && (i % 8 == 0))
- {
- printf("- ");
- }
-
- printf("%02x ", Buffer[i]);
- }
- else
- {
- if ((i != index) && (i % 8 == 0))
- {
- printf(" ");
- }
- printf(" ");
- }
- }
-
- printf(" : ");
-
- for(ULONG i = index; i < (index + 16); i += 1)
- {
- if (i < BufferCb)
- {
- if ((i != index) && (i % 8 == 0))
- {
- printf(" ");
- }
-
- if (isprint(Buffer[i]))
- {
- printf("%c", Buffer[i]);
- }
- else
- {
- printf(".");
- }
- }
- else
- {
- printf(" ");
- }
- }
-
- printf("\n");
- }
-}
-
-BOOL
-WINAPI
-OnControlKey(
- _In_ DWORD ControlType
- )
-{
- if (ControlType == CTRL_C_EVENT)
- {
- //
- // If there's a current command then attempt to cancel it.
- //
-
- if (g_CurrentCommand != nullptr)
- {
- g_CurrentCommand->Cancel();
- return TRUE;
- }
-
- //
- // Stop the interrupt notification thread
- //
-
- g_WaitOnInterrupt = false;
- CancelIo(g_Peripheral);
- }
-
- return FALSE;
-}