windows-nt/Source/XPSP1/NT/base/fs/utils/cipher/support.c

600 lines
12 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1994-1999 Microsoft Corporation
Module Name:
Support.c
Abstract:
Support routines for compact utility
Author:
Matthew Bradburn [mattbr] 05-Oct-1994
Robert Reichel [RobertRe] 01-Apr-1997
Revision History:
--*/
#undef UNICODE
#define UNICODE
#undef _UNICODE
#define _UNICODE
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <windows.h>
#include "support.h"
#include "msg.h"
//
// Declare routines to put out internationalized messages
//
typedef enum {
READ_ACCESS,
WRITE_ACCESS
} STREAMACCESS;
HANDLE
GetStandardStream(
IN HANDLE Handle,
IN STREAMACCESS Access
);
HANDLE hInput;
HANDLE hOutput;
HANDLE hError;
#define STDIN 0
#define STDOUT 1
#define STDERR 2
BOOL ConsoleInput;
BOOL ConsoleOutput;
BOOL ConsoleError;
int
FileIsConsole(int fh)
{
unsigned htype;
DWORD dwMode;
HANDLE hFile;
hFile = (HANDLE)_get_osfhandle(fh);
htype = GetFileType(hFile);
htype &= ~FILE_TYPE_REMOTE;
if (FILE_TYPE_CHAR == htype) {
switch (fh) {
case STDIN:
hFile = GetStdHandle(STD_INPUT_HANDLE);
break;
case STDOUT:
hFile = GetStdHandle(STD_OUTPUT_HANDLE);
break;
case STDERR:
hFile = GetStdHandle(STD_ERROR_HANDLE);
break;
}
if (GetConsoleMode(hFile, &dwMode)) {
return TRUE;
}
}
return FALSE;
}
VOID
InitializeIoStreams()
{
hInput = GetStdHandle(STD_INPUT_HANDLE);
ConsoleInput = FileIsConsole(STDIN);
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
ConsoleOutput = FileIsConsole(STDOUT);
hError = GetStdHandle(STD_ERROR_HANDLE);
ConsoleError = FileIsConsole(STDERR);
}
VOID
DisplayMsg(DWORD MsgNum, ... )
{
DWORD len, bytes_written;
BOOL success = FALSE;
DWORD status;
va_list ap;
LPTSTR DisplayBuffer;
va_start(ap, MsgNum);
len = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, MsgNum, 0,
(LPVOID)&DisplayBuffer, 0, &ap);
if (len && DisplayBuffer) {
if (ConsoleOutput) {
success = WriteConsole(hOutput, (LPVOID)DisplayBuffer, len,
&bytes_written, NULL);
} else {
DWORD ascii_len;
LPSTR DisplayBufferAscii;
len = lstrlen(DisplayBuffer);
ascii_len = WideCharToMultiByte(
CP_OEMCP, // Unicode -> OEM
0, // gives best visual match
DisplayBuffer, len+1, // source & length
NULL, 0, // dest & length
NULL, // default char
NULL);
DisplayBufferAscii = LocalAlloc(LPTR, ascii_len);
if (DisplayBufferAscii != NULL) {
WideCharToMultiByte(
CP_OEMCP,
0,
DisplayBuffer, len+1,
DisplayBufferAscii, ascii_len,
NULL,
NULL);
success = WriteFile(hOutput, (LPVOID)DisplayBufferAscii, ascii_len,
&bytes_written, NULL);
len = ascii_len;
LocalFree(DisplayBufferAscii);
}
}
if (!success || bytes_written != len) {
status = GetLastError();
}
LocalFree(DisplayBuffer);
}
va_end(ap);
}
VOID
DisplayErr(
PTCHAR Prefix,
DWORD MsgNum,
...
)
{
DWORD len, bytes_written, PrefixLen;
BOOL success = FALSE;
DWORD status;
va_list ap;
LPTSTR DisplayBuffer;
LPTSTR MessageBuffer;
#define PREFIX_MSG TEXT(": ")
va_start(ap, MsgNum);
len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, MsgNum, 0,
(LPVOID)&MessageBuffer, 0, &ap);
if (len && MessageBuffer) {
if (Prefix == NULL) {
PrefixLen = 0;
} else {
PrefixLen = wcslen(Prefix)+wcslen(PREFIX_MSG);
}
DisplayBuffer = LocalAlloc(LPTR, (len+PrefixLen+1) * sizeof(WCHAR));
if (DisplayBuffer != NULL) {
if (NULL != Prefix) {
lstrcpy(DisplayBuffer, Prefix);
lstrcat(DisplayBuffer, PREFIX_MSG);
} else {
DisplayBuffer[0] = UNICODE_NULL;
}
lstrcat(DisplayBuffer, MessageBuffer);
len = lstrlen(DisplayBuffer);
if (ConsoleError) {
success = WriteConsole(hError, (LPVOID)DisplayBuffer, len,
&bytes_written, NULL);
} else {
DWORD ascii_len;
LPSTR DisplayBufferAscii;
ascii_len = WideCharToMultiByte(
CP_OEMCP, // Unicode -> OEM
0, // gives best visual match
DisplayBuffer, len+1, // source & length
NULL, 0, // dest & length
NULL, // default char
NULL);
DisplayBufferAscii = LocalAlloc(LPTR, ascii_len);
if (DisplayBufferAscii != NULL) {
WideCharToMultiByte(
CP_OEMCP,
0,
DisplayBuffer, len+1,
DisplayBufferAscii, ascii_len,
NULL,
NULL);
success = WriteFile(hError, (LPVOID)DisplayBufferAscii, ascii_len,
&bytes_written, NULL);
LocalFree(DisplayBufferAscii);
}
}
LocalFree(DisplayBuffer);
}
if (!success) {
status = GetLastError();
}
LocalFree(MessageBuffer);
}
va_end(ap);
}
DWORD
GetResourceString(
LPWSTR *OutStr,
DWORD MsgNum,
...
)
{
DWORD rc = ERROR_SUCCESS;
DWORD len;
va_list ap;
va_start(ap, MsgNum);
*OutStr = NULL;
len = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL,
MsgNum,
0,
(LPVOID)OutStr,
0,
&ap
);
if (len && *OutStr) {
//
// Let's get rid of \n
//
len = wcslen( *OutStr );
if (((*OutStr)[len-1] == 0x000a) && ((*OutStr)[len-2] == 0x000d) ) {
(*OutStr)[len-2] = 0;
}
} else {
rc = ERROR_NOT_ENOUGH_MEMORY;
}
va_end(ap);
return rc;
}
BOOLEAN
IsNtldr(
PTCHAR Path
)
/*++
Routine Description:
Used to keep the user from compressing \NTLDR (which would prevent
the machine from booting).
Arguments:
Path - the path to examine.
Return Value:
TRUE - the path looks like \ntldr.
FALSE - the path does not look like \ntldr.
--*/
{
PTCHAR pch;
// try "X:\ntldr"
if (0 == lstricmp(Path + 2, TEXT("\\ntldr"))) {
return TRUE;
}
// try "\\machine\share\ntldr"
if ('\\' == Path[0] && '\\' != Path[1]) {
pch = lstrchr(Path + 2, '\\');
if (NULL == pch) {
return FALSE;
}
pch = lstrchr(pch + 1, '\\');
if (NULL == pch) {
return FALSE;
}
if (0 == lstricmp(pch, TEXT("\\ntldr"))) {
return TRUE;
}
}
return FALSE;
}
BOOLEAN
IsUncRoot(
PTCHAR Path
)
/*++
Routine Description:
Determine whether the given path is of the form \\server\share.
Arguments:
Path - the path to examine.
Return Value:
TRUE - the path looks like a unc share name.
FALSE - the path does not look like that.
--*/
{
PTCHAR pch;
if ('\\' != *Path || '\\' != *(Path + 1)) {
return FALSE;
}
pch = lstrchr(Path + 2, '\\');
if (NULL == pch) {
//
// There is no slash to seperate server and share.
//
return FALSE;
}
pch = lstrchr(pch + 1, '\\');
if (NULL != pch) {
//
// There are additional component -- no match.
//
return FALSE;
}
if ('\\' == *(Path + lstrlen(Path))) {
//
// The string ends in slash -- it doesn't match.
//
return FALSE;
}
return TRUE;
}
ULONG
FormatFileSize(
IN PLARGE_INTEGER FileSize,
IN DWORD Width,
OUT PTCHAR FormattedSize,
IN BOOLEAN Commas
)
{
TCHAR Buffer[100];
PTCHAR s, s1;
ULONG DigitIndex, Digit;
ULONG Size;
LARGE_INTEGER TempSize;
s = &Buffer[ 99 ];
*s = TEXT('\0');
DigitIndex = 0;
TempSize = *FileSize;
while (TempSize.HighPart != 0) {
if (TempSize.HighPart != 0) {
Digit = (ULONG)(TempSize.QuadPart % 10);
TempSize.QuadPart = TempSize.QuadPart / 10;
} else {
Digit = TempSize.LowPart % 10;
TempSize.LowPart = TempSize.LowPart / 10;
}
*--s = (TCHAR)(TEXT('0') + Digit);
if ((++DigitIndex % 3) == 0 && Commas) {
*--s = TEXT(',');
}
}
Size = TempSize.LowPart;
while (Size != 0) {
*--s = (TCHAR)(TEXT('0') + (Size % 10));
Size = Size / 10;
if ((++DigitIndex % 3) == 0 && Commas) {
*--s = TEXT(',');
}
}
if (DigitIndex == 0) {
*--s = TEXT('0');
} else if (Commas && *s == TEXT(',')) {
s += 1;
}
Size = lstrlen( s );
if (Width != 0 && Size < Width) {
s1 = FormattedSize;
while (Width > Size) {
Width -= 1;
*s1++ = TEXT(' ');
}
lstrcpy( s1, s );
} else {
lstrcpy( FormattedSize, s );
}
return lstrlen( FormattedSize );
}
PTOKEN_USER
GetTokenUser(
VOID
)
{
HANDLE TokenHandle;
BOOL b;
DWORD ReturnLength;
PTOKEN_USER TokenInfo;
//
// If we're impersonating, use the thread token, otherwise
// use the process token.
//
PTOKEN_USER Result = NULL;
b = OpenThreadToken(
GetCurrentThread(),
TOKEN_QUERY,
FALSE,
&TokenHandle
);
if (!b) {
if (GetLastError() == ERROR_NO_TOKEN) {
//
// We're not impersonating, try the process token
//
b = OpenProcessToken(
GetCurrentProcess(),
TOKEN_QUERY,
&TokenHandle
);
if (!b) {
return( Result );
}
} else {
//
// We failed for some unexpected reason, return NULL and
// let the caller figure it out if he so chooses.
//
return( Result );
}
}
ReturnLength = GetSidLengthRequired( SID_MAX_SUB_AUTHORITIES ) + sizeof( TOKEN_USER );
TokenInfo = (PTOKEN_USER)malloc( ReturnLength );
if (TokenInfo != NULL) {
b = GetTokenInformation (
TokenHandle,
TokenUser,
TokenInfo,
ReturnLength,
&ReturnLength
);
if (b) {
Result = TokenInfo;
} else {
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
//
// Reallocate TokenInfo
//
free( TokenInfo );
TokenInfo = (PTOKEN_USER)malloc( ReturnLength );
if (TokenInfo != NULL) {
b = GetTokenInformation (
TokenHandle,
TokenUser,
TokenInfo,
ReturnLength,
&ReturnLength
);
if (b) {
Result = TokenInfo;
}
} else {
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
}
}
}
} else {
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
}
CloseHandle( TokenHandle );
return( Result );
}