287 lines
5.5 KiB
C
287 lines
5.5 KiB
C
/*++
|
||
|
||
Copyright (c) 1995 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
spt.c
|
||
|
||
Abstract:
|
||
|
||
A user mode library that allows simple commands to be sent to a
|
||
selected scsi device.
|
||
|
||
Environment:
|
||
|
||
User mode only
|
||
|
||
Revision History:
|
||
|
||
4/10/2000 - created
|
||
|
||
--*/
|
||
|
||
#include "CmdHelpP.h"
|
||
|
||
static char ValidCharArray[] = {
|
||
' ',
|
||
'0', '1', '2', '3',
|
||
'4', '5', '6', '7',
|
||
'8', '9', 'a', 'b',
|
||
'c', 'd', 'e', 'f',
|
||
'A', 'B', 'C', 'D',
|
||
'E', 'F'
|
||
};
|
||
#define MaxValidOctalChars ( 9) // space + 8 digits
|
||
#define MaxValidDecimalHexChars (11) // + 2 digits
|
||
#define MaxValidHexChars (23) // + 12 letters (upper and lower case)
|
||
#define MaxValidCharacters (23) // number of safe chars to access
|
||
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Validates a string has valid characters
|
||
valid chars are stored in a global static array
|
||
|
||
--*/
|
||
BOOL
|
||
PrivateValidateString(
|
||
IN PCHAR String,
|
||
IN DWORD ValidChars
|
||
)
|
||
{
|
||
if (ValidChars > MaxValidCharacters) {
|
||
return FALSE;
|
||
}
|
||
|
||
if (*String == '\0') {
|
||
return TRUE; // a NULL string is valid
|
||
}
|
||
|
||
while (*String != '\0') {
|
||
|
||
DWORD i;
|
||
BOOL pass = FALSE;
|
||
|
||
for (i=0; i<ValidChars; i++) {
|
||
if (*String == ValidCharArray[i]) {
|
||
pass = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!pass) {
|
||
return FALSE;
|
||
}
|
||
String++; // look at next character
|
||
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
BOOL
|
||
CmdHelpValidateStringHex(
|
||
IN PCHAR String
|
||
)
|
||
{
|
||
return PrivateValidateString(String, MaxValidHexChars);
|
||
}
|
||
|
||
BOOL
|
||
CmdHelpValidateStringDecimal(
|
||
IN PCHAR String
|
||
)
|
||
{
|
||
return PrivateValidateString(String, MaxValidDecimalHexChars);
|
||
}
|
||
|
||
BOOL
|
||
CmdHelpValidateStringOctal(
|
||
IN PCHAR String
|
||
)
|
||
{
|
||
return PrivateValidateString(String, MaxValidOctalChars);
|
||
}
|
||
|
||
BOOL
|
||
CmdHelpValidateStringHexQuoted(
|
||
IN PCHAR String
|
||
)
|
||
{
|
||
DWORD i;
|
||
|
||
if (!PrivateValidateString(String, MaxValidHexChars)) return FALSE;
|
||
|
||
i=1;
|
||
while (*String != '\0') {
|
||
|
||
if ((*String == ' ') && (i%3)) return FALSE;
|
||
if ((*String != ' ') && !(i%3)) return FALSE;
|
||
i++; // use next index
|
||
String++; // go to next character
|
||
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
BOOLEAN
|
||
CmdHelpScanQuotedHexString(
|
||
IN PUCHAR QuotedHexString,
|
||
OUT PUCHAR Data,
|
||
OUT PDWORD DataSize
|
||
)
|
||
{
|
||
PUCHAR temp;
|
||
DWORD availableSize;
|
||
DWORD requiredSize;
|
||
DWORD index;
|
||
|
||
availableSize = *DataSize;
|
||
*DataSize = 0;
|
||
|
||
if (!CmdHelpValidateStringHexQuoted(QuotedHexString)) {
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// the number format is (number)(number)(space) repeated,
|
||
// ending with (number)(number)(null)
|
||
// size = 3(n-1) + 2 chars
|
||
//
|
||
|
||
requiredSize = strlen(QuotedHexString);
|
||
if (requiredSize % 3 != 2) {
|
||
return FALSE;
|
||
}
|
||
|
||
requiredSize /= 3;
|
||
requiredSize ++;
|
||
|
||
//
|
||
// cannot set zero bytes of data
|
||
//
|
||
|
||
if (requiredSize == 0) {
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// validate that we have enough space
|
||
//
|
||
|
||
if (requiredSize > availableSize) {
|
||
*DataSize = requiredSize;
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// the number format is (number)(number)(space) repeated,
|
||
// ending with (number)(number)(null)
|
||
//
|
||
|
||
for (index = 0; index < requiredSize; index ++) {
|
||
|
||
temp = QuotedHexString + (3*index);
|
||
|
||
if (sscanf(temp, "%x", Data+index) != 1) {
|
||
return FALSE;
|
||
}
|
||
|
||
if ((*(temp+0) == '\0') || (*(temp+1) == '\0')) {
|
||
// string too short
|
||
return FALSE;
|
||
}
|
||
|
||
}
|
||
|
||
*DataSize = requiredSize;
|
||
return TRUE;
|
||
}
|
||
|
||
VOID
|
||
CmdHelpUpdatePercentageDisplay(
|
||
IN ULONG Numerator,
|
||
IN ULONG Denominator
|
||
)
|
||
{
|
||
ULONG percent;
|
||
ULONG i;
|
||
|
||
if (Numerator > Denominator) {
|
||
return;
|
||
}
|
||
|
||
// NOTE: Overflow possibility exists for large numerators.
|
||
|
||
percent = (Numerator * 100) / Denominator;
|
||
|
||
for (i=0;i<80;i++) {
|
||
putchar('\b');
|
||
}
|
||
printf("Complete: ");
|
||
|
||
// each block is 2%
|
||
// ----=----1----=----2----=----3----=----4----=----5----=----6----=----7----=----8
|
||
// Complete: <20>.....................
|
||
|
||
for (i=1; i<100; i+=2) {
|
||
if (i < percent) {
|
||
putchar(178);
|
||
} else if (i == percent) {
|
||
putchar(177);
|
||
} else {
|
||
putchar(176);
|
||
}
|
||
}
|
||
|
||
printf(" %d%% (%x/%x)", percent, Numerator, Denominator);
|
||
}
|
||
|
||
VOID
|
||
CmdHelpPrintBuffer(
|
||
IN PUCHAR Buffer,
|
||
IN SIZE_T Size
|
||
)
|
||
{
|
||
DWORD offset = 0;
|
||
|
||
while (Size > 0x10) {
|
||
printf( "%08x:"
|
||
" %02x %02x %02x %02x %02x %02x %02x %02x"
|
||
" %02x %02x %02x %02x %02x %02x %02x %02x"
|
||
"\n",
|
||
offset,
|
||
*(Buffer + 0), *(Buffer + 1), *(Buffer + 2), *(Buffer + 3),
|
||
*(Buffer + 4), *(Buffer + 5), *(Buffer + 6), *(Buffer + 7),
|
||
*(Buffer + 8), *(Buffer + 9), *(Buffer + 10), *(Buffer + 11),
|
||
*(Buffer + 12), *(Buffer + 13), *(Buffer + 14), *(Buffer + 15)
|
||
);
|
||
Size -= 0x10;
|
||
offset += 0x10;
|
||
Buffer += 0x10;
|
||
}
|
||
|
||
if (Size != 0) {
|
||
|
||
DWORD spaceIt;
|
||
|
||
printf("%08x:", offset);
|
||
for (spaceIt = 0; Size != 0; Size--) {
|
||
|
||
if ((spaceIt%8)==0) {
|
||
printf(" "); // extra space every eight chars
|
||
}
|
||
printf(" %02x", *Buffer);
|
||
spaceIt++;
|
||
Buffer++;
|
||
}
|
||
printf("\n");
|
||
|
||
}
|
||
return;
|
||
}
|
||
|
||
|