1029 lines
20 KiB
C
1029 lines
20 KiB
C
/********************************************************************/
|
|
/** Microsoft LAN Manager **/
|
|
/** Copyright(c) Microsoft Corp., 1987-1990 **/
|
|
/********************************************************************/
|
|
|
|
/***
|
|
* mutil.c
|
|
* Message utility functions used by netcmd
|
|
*
|
|
* History:
|
|
* mm/dd/yy, who, comment
|
|
* 06/10/87, andyh, new code
|
|
* 04/05/88, andyh, created from util.c
|
|
* 10/31/88, erichn, uses OS2.H instead of DOSCALLS
|
|
* 01/04/89, erichn, filenames now MAX_PATH_LEN LONG
|
|
* 01/30/89, paulc, added GetMessageList
|
|
* 05/02/89, erichn, NLS conversion
|
|
* 05/11/89, erichn, moved misc stuff into LUI libs
|
|
* 06/08/89, erichn, canonicalization sweep
|
|
* 01/06/90, thomaspa, fix ReadPass off-by-one pwlen bug
|
|
* 03/02/90, thomaspa, add canon flag to ReadPass
|
|
* 02/20/91, danhi, change to use lm 16/32 mapping layer
|
|
* 03/19/91, robdu, support for lm21 dcr 954, general cleanup
|
|
*/
|
|
|
|
/* Include files */
|
|
|
|
#define INCL_NOCOMMON
|
|
#define INCL_DOSFILEMGR
|
|
#define INCL_DOSQUEUES
|
|
#define INCL_DOSMISC
|
|
#define INCL_ERRORS
|
|
|
|
#include <os2.h>
|
|
#include <lmcons.h>
|
|
#include <apperr.h>
|
|
#include <apperr2.h>
|
|
#define INCL_ERROR_H
|
|
#include <lmerr.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <lui.h>
|
|
#include "netcmds.h"
|
|
#include "nettext.h"
|
|
#include "msystem.h"
|
|
|
|
|
|
/* Constants */
|
|
|
|
/* HandType */
|
|
#define FILE_HANDLE 0
|
|
#define DEVICE_HANDLE 1
|
|
|
|
#define CHAR_DEV 0x8000
|
|
#define FULL_SUPPORT 0x0080
|
|
#define STDOUT_DEVICE 0x0002
|
|
#define DESIRED_HAND_STATE (CHAR_DEV | FULL_SUPPORT | STDOUT_DEVICE)
|
|
|
|
|
|
/* External variables */
|
|
|
|
extern int YorN_Switch;
|
|
extern CPINFO CurrentCPInfo;
|
|
|
|
#define MAX_BUF_SIZE 4096
|
|
|
|
TCHAR ConBuf [MAX_BUF_SIZE];
|
|
|
|
|
|
/* Forward declarations */
|
|
|
|
DWORD
|
|
DosQHandType(
|
|
HANDLE hf,
|
|
PWORD pus1,
|
|
PWORD pus2
|
|
);
|
|
|
|
DWORD
|
|
GetPasswdStr(
|
|
LPTSTR buf,
|
|
DWORD buflen,
|
|
PDWORD len
|
|
);
|
|
|
|
|
|
/* Static variables */
|
|
|
|
static DWORD LastError = 0;
|
|
static TCHAR MsgBuffer[LITTLE_BUF_SIZE];
|
|
|
|
|
|
/*** InfoSuccess
|
|
*
|
|
* Just an entrypoint to InfoPrintInsHandle, used to avoid pushing
|
|
* the three args in every invocation. And there are a *lot*
|
|
* of invocations. Saves code space overall.
|
|
*/
|
|
|
|
VOID FASTCALL
|
|
InfoSuccess(
|
|
VOID
|
|
)
|
|
{
|
|
InfoPrintInsHandle(APE_Success, 0, g_hStdOut);
|
|
}
|
|
|
|
|
|
/***
|
|
* I n f o P r i n t
|
|
*
|
|
*/
|
|
|
|
VOID FASTCALL
|
|
InfoPrint(
|
|
DWORD msg
|
|
)
|
|
{
|
|
InfoPrintInsHandle(msg, 0, g_hStdOut);
|
|
}
|
|
|
|
/***
|
|
* I n f o P r i n t I n s
|
|
*
|
|
*/
|
|
|
|
VOID FASTCALL
|
|
InfoPrintIns(
|
|
DWORD msg,
|
|
DWORD nstrings
|
|
)
|
|
{
|
|
InfoPrintInsHandle(msg, nstrings, g_hStdOut);
|
|
}
|
|
|
|
/***
|
|
* I n f o P r i n t I n s T x t
|
|
*
|
|
* Calls InfoPrintInsHandle with supplementary text
|
|
*/
|
|
|
|
void FASTCALL
|
|
InfoPrintInsTxt(
|
|
DWORD msg,
|
|
LPTSTR text
|
|
)
|
|
{
|
|
IStrings[0] = text;
|
|
InfoPrintInsHandle(msg, 1, g_hStdOut);
|
|
}
|
|
|
|
/***
|
|
* I n f o P r i n t I n s H a n d l e
|
|
*
|
|
*/
|
|
|
|
void FASTCALL
|
|
InfoPrintInsHandle(
|
|
DWORD msg,
|
|
DWORD nstrings,
|
|
HANDLE hdl
|
|
)
|
|
{
|
|
PrintMessage(hdl, MESSAGE_FILENAME, msg, IStrings, nstrings);
|
|
}
|
|
|
|
/***
|
|
* P r i n t M e s s a g e
|
|
*
|
|
*/
|
|
DWORD FASTCALL
|
|
PrintMessage(
|
|
HANDLE outFileHandle,
|
|
TCHAR *msgFileName,
|
|
DWORD msg,
|
|
TCHAR *strings[],
|
|
DWORD nstrings
|
|
)
|
|
{
|
|
DWORD msg_len;
|
|
DWORD result;
|
|
|
|
result = DosGetMessageW(strings,
|
|
nstrings,
|
|
MsgBuffer,
|
|
LITTLE_BUF_SIZE,
|
|
msg,
|
|
msgFileName,
|
|
&msg_len);
|
|
|
|
if (result) /* if there was a problem */
|
|
{ /* change outFile to stderr */
|
|
outFileHandle = g_hStdErr;
|
|
}
|
|
|
|
DosPutMessageW(outFileHandle, MsgBuffer, TRUE);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/***
|
|
* P r i n t M e s s a g e I f F o u n d
|
|
*
|
|
*/
|
|
DWORD FASTCALL
|
|
PrintMessageIfFound(
|
|
HANDLE outFileHandle,
|
|
TCHAR *msgFileName,
|
|
DWORD msg,
|
|
TCHAR * strings[],
|
|
DWORD nstrings
|
|
)
|
|
{
|
|
DWORD msg_len;
|
|
DWORD result;
|
|
|
|
result = DosGetMessageW(strings,
|
|
nstrings,
|
|
MsgBuffer,
|
|
LITTLE_BUF_SIZE,
|
|
msg,
|
|
msgFileName,
|
|
&msg_len);
|
|
|
|
if (!result) /* if ok, print it else just ignore */
|
|
{
|
|
DosPutMessageW(outFileHandle, MsgBuffer, TRUE);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/***
|
|
* E r r o r P r i n t
|
|
*
|
|
* nstrings ignored for non-NET errors!
|
|
*
|
|
*/
|
|
VOID FASTCALL
|
|
ErrorPrint(
|
|
DWORD err,
|
|
DWORD nstrings
|
|
)
|
|
{
|
|
TCHAR buf[17];
|
|
DWORD oserr = 0;
|
|
|
|
LastError = err; /* if > NERR_BASE,NetcmdExit() prints a "more help" msg */
|
|
|
|
if (err < NERR_BASE || err > MAX_LANMAN_MESSAGE_ID)
|
|
{
|
|
IStrings[0] = _ultow(err, buf, 10);
|
|
nstrings = 1;
|
|
oserr = err;
|
|
|
|
err = APE_OS2Error;
|
|
}
|
|
|
|
{
|
|
DWORD msg_len;
|
|
|
|
DosGetMessageW(IStrings,
|
|
nstrings,
|
|
MsgBuffer,
|
|
LITTLE_BUF_SIZE,
|
|
err,
|
|
MESSAGE_FILENAME,
|
|
&msg_len);
|
|
|
|
DosPutMessageW(g_hStdErr, MsgBuffer, TRUE);
|
|
|
|
if (!oserr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DosGetMessageW(StarStrings,
|
|
9,
|
|
MsgBuffer,
|
|
LITTLE_BUF_SIZE,
|
|
oserr,
|
|
OS2MSG_FILENAME,
|
|
&msg_len);
|
|
|
|
DosPutMessageW(g_hStdErr, MsgBuffer, TRUE);
|
|
}
|
|
}
|
|
|
|
|
|
/***
|
|
* E m p t y E x i t
|
|
*
|
|
* Prints a message and exits.
|
|
* Called when a list is empty.
|
|
*/
|
|
|
|
VOID FASTCALL
|
|
EmptyExit(
|
|
VOID
|
|
)
|
|
{
|
|
InfoPrint(APE_EmptyList);
|
|
NetcmdExit(0);
|
|
}
|
|
|
|
|
|
/***
|
|
* E r r o r E x i t
|
|
*
|
|
* Calls ErrorPrint and exit for a given LANMAN error.
|
|
*/
|
|
|
|
VOID FASTCALL
|
|
ErrorExit(
|
|
DWORD err
|
|
)
|
|
{
|
|
ErrorExitIns(err, 0);
|
|
}
|
|
|
|
|
|
/***
|
|
* E r r o r E x i t I n s
|
|
*
|
|
* Calls ErrorPrint and exit for a given LANMAN error.
|
|
* Uses IStrings.
|
|
*/
|
|
|
|
VOID FASTCALL
|
|
ErrorExitIns(
|
|
DWORD err,
|
|
DWORD nstrings
|
|
)
|
|
{
|
|
ErrorPrint(err, nstrings);
|
|
NetcmdExit(2);
|
|
}
|
|
|
|
/***
|
|
* E r r o r E x i t I n s T x t
|
|
*
|
|
*/
|
|
VOID FASTCALL
|
|
ErrorExitInsTxt(
|
|
DWORD err,
|
|
LPTSTR text
|
|
)
|
|
{
|
|
IStrings[0] = text;
|
|
ErrorPrint(err, 1);
|
|
NetcmdExit(2);
|
|
}
|
|
|
|
|
|
|
|
/***
|
|
* N e t c m d E x i t
|
|
*
|
|
* Net command exit function. Should always be used instead of exit().
|
|
* Under the appropriate circumstances, it prints a "more help available"
|
|
* message.
|
|
*/
|
|
|
|
VOID FASTCALL
|
|
NetcmdExit(
|
|
int Status
|
|
)
|
|
{
|
|
TCHAR AsciiLastError[17];
|
|
DWORD MsgLen;
|
|
|
|
if (LastError >= NERR_BASE && LastError <= MAX_LANMAN_MESSAGE_ID)
|
|
{
|
|
IStrings[0] = _ultow(LastError, AsciiLastError, 10);
|
|
|
|
if (!DosGetMessageW(IStrings, 1, MsgBuffer, LITTLE_BUF_SIZE,
|
|
APE_MoreHelp, MESSAGE_FILENAME, &MsgLen))
|
|
{
|
|
DosPutMessageW(g_hStdErr, MsgBuffer, TRUE);
|
|
}
|
|
}
|
|
|
|
MyExit(Status);
|
|
}
|
|
|
|
|
|
/***
|
|
* P r i n t L i n e
|
|
*
|
|
* Prints the header line.
|
|
*/
|
|
VOID FASTCALL
|
|
PrintLine(
|
|
VOID
|
|
)
|
|
{
|
|
/* The following code is provided in OS-specific versions to reduce */
|
|
/* FAPI utilization under DOS. */
|
|
|
|
USHORT type;
|
|
USHORT attrib;
|
|
|
|
if (DosQHandType((HANDLE) 1, &type, &attrib) ||
|
|
type != DEVICE_HANDLE ||
|
|
(attrib & DESIRED_HAND_STATE) != DESIRED_HAND_STATE)
|
|
{
|
|
WriteToCon(MSG_HYPHENS, NULL);
|
|
}
|
|
else if (LUI_PrintLine())
|
|
{
|
|
WriteToCon(MSG_HYPHENS, NULL);
|
|
}
|
|
}
|
|
|
|
/***
|
|
* P r i n t D o t
|
|
*
|
|
* Prints a dot, typically to indicate "I'm working".
|
|
*/
|
|
|
|
VOID FASTCALL
|
|
PrintDot(
|
|
VOID
|
|
)
|
|
{
|
|
WriteToCon(DOT_STRING, NULL);
|
|
}
|
|
|
|
|
|
/***
|
|
* P r i n t N L
|
|
*
|
|
* Prints a newline
|
|
*/
|
|
|
|
VOID FASTCALL
|
|
PrintNL(
|
|
VOID
|
|
)
|
|
{
|
|
WriteToCon(TEXT("\r\n"), NULL);
|
|
}
|
|
|
|
|
|
/***
|
|
* Y o r N
|
|
*
|
|
* Gets an answer to a Y/N question
|
|
* an nstrings arg would be nice
|
|
*/
|
|
|
|
int FASTCALL
|
|
YorN(
|
|
USHORT prompt,
|
|
USHORT def
|
|
)
|
|
{
|
|
DWORD err;
|
|
|
|
if (YorN_Switch)
|
|
{
|
|
return(YorN_Switch - 2);
|
|
}
|
|
|
|
err = LUI_YorN(prompt, def);
|
|
|
|
switch (err) {
|
|
case TRUE:
|
|
case FALSE:
|
|
break;
|
|
default:
|
|
ErrorExit(err);
|
|
break;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
/***
|
|
* ReadPass()
|
|
* Reads a users passwd without echo
|
|
*
|
|
* Args:
|
|
* pass - where to put pass
|
|
* NOTE: buffer for pass should be passlen+1 in size.
|
|
* passlen - max length of password
|
|
* confirm - confirm pass if true
|
|
* prompt - prompt to print, NULL for default
|
|
* nstrings - number of insertion strings in IStrings on entry
|
|
* cannon - canonicalize password if true.
|
|
*
|
|
* Returns:
|
|
*/
|
|
VOID FASTCALL
|
|
ReadPass(
|
|
TCHAR pass[],
|
|
DWORD passlen,
|
|
DWORD confirm,
|
|
DWORD prompt,
|
|
DWORD nstrings,
|
|
BOOL canon
|
|
)
|
|
{
|
|
DWORD err;
|
|
DWORD len;
|
|
TCHAR cpass[PWLEN+1]; /* confirmation passwd */
|
|
int count;
|
|
|
|
passlen++; /* one extra for null terminator */
|
|
for (count = LOOP_LIMIT; count; count--)
|
|
{
|
|
InfoPrintIns((prompt ? prompt : APE_UtilPasswd), nstrings);
|
|
|
|
if (err = GetPasswdStr(pass, passlen, &len))
|
|
{
|
|
/* too LONG */
|
|
InfoPrint(APE_UtilInvalidPass);
|
|
continue;
|
|
}
|
|
|
|
if (canon && (err = LUI_CanonPassword(pass)))
|
|
{
|
|
/* not good */
|
|
InfoPrint(APE_UtilInvalidPass);
|
|
continue;
|
|
}
|
|
if (! confirm)
|
|
return;
|
|
|
|
/* password confirmation */
|
|
InfoPrint(APE_UtilConfirm);
|
|
|
|
if (err = GetPasswdStr(cpass, passlen, &len))
|
|
{
|
|
/* too LONG */
|
|
InfoPrint(APE_UtilInvalidPass);
|
|
ClearStringW(cpass) ;
|
|
continue;
|
|
}
|
|
|
|
if (canon && (err = LUI_CanonPassword(cpass)))
|
|
{
|
|
/* not good */
|
|
InfoPrint(APE_UtilInvalidPass);
|
|
ClearStringW(cpass) ;
|
|
continue;
|
|
}
|
|
|
|
if (_tcscmp(pass, cpass))
|
|
{
|
|
InfoPrint(APE_UtilNomatch);
|
|
ClearStringW(cpass) ;
|
|
continue;
|
|
}
|
|
|
|
ClearStringW(cpass) ;
|
|
return;
|
|
}
|
|
/***
|
|
* Only get here if user blew if LOOP_LIMIT times
|
|
*/
|
|
ErrorExit(APE_NoGoodPass);
|
|
}
|
|
|
|
|
|
/***
|
|
* PromptForString()
|
|
* Prompts the user for a string.
|
|
*
|
|
* Args:
|
|
* msgid - id of prompt message
|
|
* buffer - buffer to receive string
|
|
* bufsiz - sizeof buffer
|
|
*
|
|
* Returns:
|
|
*/
|
|
VOID FASTCALL
|
|
PromptForString(
|
|
DWORD msgid,
|
|
LPTSTR buffer,
|
|
DWORD bufsiz
|
|
)
|
|
{
|
|
DWORD err;
|
|
DWORD len;
|
|
TCHAR terminator;
|
|
TCHAR szLen[16] ;
|
|
|
|
InfoPrint(msgid);
|
|
|
|
while (err = GetString(buffer, bufsiz, &len, &terminator))
|
|
{
|
|
if (err == NERR_BufTooSmall)
|
|
{
|
|
InfoPrintInsTxt(APE_StringTooLong, _ultow(bufsiz, szLen, 10));
|
|
}
|
|
else
|
|
{
|
|
ErrorExit(err);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
** There is no need to have these functions in the Chinese/Korean
|
|
** cases, as there are no half-width varients used in the console
|
|
** in those languages (at least, let's hope so.) However, in the
|
|
** interests of a single binary, let's put them in with a CP/932 check.
|
|
**
|
|
** FloydR 7/10/95
|
|
*/
|
|
/***************************************************************************\
|
|
* BOOL IsFullWidth(WCHAR wch)
|
|
*
|
|
* Determine if the given Unicode char is fullwidth or not.
|
|
*
|
|
* History:
|
|
* 04-08-92 ShunK Created.
|
|
\***************************************************************************/
|
|
|
|
BOOL IsFullWidth(WCHAR wch)
|
|
{
|
|
|
|
/* Assert cp == double byte codepage */
|
|
if (wch <= 0x007f || (wch >= 0xff60 && wch <= 0xff9f))
|
|
return(FALSE); // Half width.
|
|
else if (wch >= 0x300)
|
|
return(TRUE); // Full width.
|
|
else
|
|
return(FALSE); // Half width.
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************\
|
|
* DWORD SizeOfHalfWidthString(PWCHAR pwch)
|
|
*
|
|
* Determine width of the given Unicode string in console characters,
|
|
* adjusting for half-width chars.
|
|
*
|
|
* History:
|
|
* 08-08-93 FloydR Created.
|
|
\***************************************************************************/
|
|
DWORD
|
|
SizeOfHalfWidthString(
|
|
PWCHAR pwch
|
|
)
|
|
{
|
|
DWORD c=0;
|
|
DWORD cp;
|
|
|
|
switch (cp=GetConsoleOutputCP())
|
|
{
|
|
case 932:
|
|
case 936:
|
|
case 949:
|
|
case 950:
|
|
while (*pwch)
|
|
{
|
|
if (IsFullWidth(*pwch))
|
|
{
|
|
c += 2;
|
|
}
|
|
else
|
|
{
|
|
c++;
|
|
}
|
|
|
|
pwch++;
|
|
}
|
|
|
|
return c;
|
|
|
|
default:
|
|
return wcslen(pwch);
|
|
}
|
|
}
|
|
|
|
|
|
VOID FASTCALL
|
|
GetMessageList(
|
|
USHORT usNumMsg,
|
|
MESSAGELIST Buffer,
|
|
DWORD *pusMaxActLength
|
|
)
|
|
{
|
|
DWORD Err;
|
|
DWORD MaxMsgLen = 0;
|
|
MESSAGE *pMaxMsg;
|
|
MESSAGE *pMsg;
|
|
DWORD ThisMsgLen;
|
|
|
|
#ifdef DEBUG
|
|
USHORT MallocBytes = 0;
|
|
#endif
|
|
|
|
pMaxMsg = &Buffer[usNumMsg];
|
|
|
|
for (pMsg = Buffer; pMsg < pMaxMsg; pMsg++)
|
|
pMsg->msg_text = NULL;
|
|
|
|
for (pMsg = Buffer; pMsg < pMaxMsg; pMsg++)
|
|
{
|
|
#ifdef DEBUG
|
|
WriteToCon(TEXT("GetMessageList(): Reading msgID %u\r\n"),pMsg->msg_number);
|
|
#endif
|
|
if ((pMsg->msg_text = malloc(MSGLST_MAXLEN)) == NULL)
|
|
ErrorExit(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
Err = LUI_GetMsgInsW(NULL, 0, pMsg->msg_text, MSGLST_MAXLEN,
|
|
pMsg->msg_number, &ThisMsgLen);
|
|
if (Err)
|
|
{
|
|
ErrorExit(Err);
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
MallocBytes += (ThisMsgLen + 1) * sizeof(TCHAR);
|
|
#endif
|
|
|
|
ThisMsgLen = max(ThisMsgLen, SizeOfHalfWidthString(pMsg->msg_text));
|
|
|
|
if (ThisMsgLen > MaxMsgLen)
|
|
MaxMsgLen = ThisMsgLen;
|
|
}
|
|
|
|
*pusMaxActLength = MaxMsgLen;
|
|
|
|
#ifdef DEBUG
|
|
WriteToCon(TEXT("GetMessageList(): NumMsg = %d, MaxActLen=%d, MallocBytes = %d\r\n"),
|
|
usNumMsg, MaxMsgLen, MallocBytes);
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
VOID FASTCALL
|
|
FreeMessageList(
|
|
USHORT usNumMsg,
|
|
MESSAGELIST MsgList
|
|
)
|
|
{
|
|
USHORT i;
|
|
|
|
for (i = 0; i < usNumMsg; i++)
|
|
{
|
|
if (MsgList[i].msg_text != NULL)
|
|
{
|
|
free(MsgList[i].msg_text);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
VOID
|
|
WriteToCon(
|
|
LPWSTR fmt,
|
|
...
|
|
)
|
|
{
|
|
va_list args;
|
|
|
|
va_start( args, fmt );
|
|
_vsntprintf( ConBuf, MAX_BUF_SIZE, fmt, args );
|
|
va_end( args );
|
|
|
|
DosPutMessageW(g_hStdOut, ConBuf, FALSE);
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************\
|
|
* PWCHAR PaddedString(DWORD size, PWCHAR pwch)
|
|
*
|
|
* Realize the string, left aligned and padded on the right to the field
|
|
* width/precision specified.
|
|
*
|
|
* Limitations: This uses a static buffer under the assumption that
|
|
* no more than one such string is printed in a single 'printf'.
|
|
*
|
|
* History:
|
|
* 11-03-93 FloydR Created.
|
|
\***************************************************************************/
|
|
WCHAR PaddingBuffer[MAX_BUF_SIZE];
|
|
|
|
PWCHAR
|
|
PaddedString(
|
|
int size,
|
|
PWCHAR pwch,
|
|
PWCHAR buffer
|
|
)
|
|
{
|
|
int realsize;
|
|
int fEllipsis = FALSE;
|
|
|
|
if (buffer==NULL) buffer = PaddingBuffer;
|
|
|
|
if (size < 0) {
|
|
fEllipsis = TRUE;
|
|
size = -size;
|
|
}
|
|
|
|
//
|
|
// size is >= 0 at this point
|
|
//
|
|
|
|
realsize = _snwprintf(buffer, MAX_BUF_SIZE, L"%-*.*ws", size, size, pwch);
|
|
|
|
if (realsize == 0)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (SizeOfHalfWidthString(buffer) > (DWORD) size)
|
|
{
|
|
do
|
|
{
|
|
buffer[--realsize] = NULLC;
|
|
} while (SizeOfHalfWidthString(buffer) > (DWORD) size);
|
|
|
|
if (fEllipsis && buffer[realsize-1] != L' ')
|
|
{
|
|
buffer[realsize-1] = L'.';
|
|
buffer[realsize-2] = L'.';
|
|
buffer[realsize-3] = L'.';
|
|
}
|
|
}
|
|
|
|
return buffer;
|
|
}
|
|
|
|
|
|
DWORD
|
|
DosQHandType(
|
|
HANDLE hf,
|
|
PWORD pus1,
|
|
PWORD pus2
|
|
)
|
|
{
|
|
|
|
DWORD dwFileType;
|
|
|
|
dwFileType = GetFileType(hf);
|
|
|
|
if (dwFileType == FILE_TYPE_CHAR)
|
|
{
|
|
*pus1 = DEVICE_HANDLE;
|
|
*pus2 = DESIRED_HAND_STATE;
|
|
}
|
|
else
|
|
{
|
|
*pus1 = FILE_HANDLE;
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
/*** GetPasswdStr -- read in password string
|
|
*
|
|
* DWORD GetPasswdStr(char far *, USHORT);
|
|
*
|
|
* ENTRY: buf buffer to put string in
|
|
* buflen size of buffer
|
|
* &len address of USHORT to place length in
|
|
*
|
|
* RETURNS:
|
|
* 0 or NERR_BufTooSmall if user typed too much. Buffer
|
|
* contents are only valid on 0 return.
|
|
*
|
|
* History:
|
|
* who when what
|
|
* erichn 5/10/89 initial code
|
|
* dannygl 5/28/89 modified DBCS usage
|
|
* erichn 7/04/89 handles backspaces
|
|
* danhi 4/16/91 32 bit version for NT
|
|
*/
|
|
#define CR 0xD
|
|
#define BACKSPACE 0x8
|
|
|
|
DWORD
|
|
GetPasswdStr(
|
|
LPTSTR buf,
|
|
DWORD buflen,
|
|
PDWORD len
|
|
)
|
|
{
|
|
TCHAR ch;
|
|
TCHAR *bufPtr = buf;
|
|
DWORD c;
|
|
int err;
|
|
int mode;
|
|
|
|
buflen -= 1; /* make space for null terminator */
|
|
*len = 0; /* GP fault probe (a la API's) */
|
|
|
|
|
|
//
|
|
// Init mode in case GetConsoleMode() fails
|
|
//
|
|
|
|
mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT |
|
|
ENABLE_MOUSE_INPUT;
|
|
|
|
GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode);
|
|
|
|
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),
|
|
(~(ENABLE_ECHO_INPUT|ENABLE_LINE_INPUT)) & mode);
|
|
|
|
while (TRUE)
|
|
{
|
|
err = ReadConsole(GetStdHandle(STD_INPUT_HANDLE), &ch, 1, &c, 0);
|
|
|
|
if (!err || c != 1)
|
|
{
|
|
ch = 0xffff;
|
|
}
|
|
|
|
if ((ch == CR) || (ch == 0xffff)) /* end of the line */
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ch == BACKSPACE) /* back up one or two */
|
|
{
|
|
/*
|
|
* IF bufPtr == buf then the next two lines are
|
|
* a no op.
|
|
*/
|
|
if (bufPtr != buf)
|
|
{
|
|
bufPtr--;
|
|
(*len)--;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*bufPtr = ch;
|
|
|
|
if (*len < buflen)
|
|
bufPtr++ ; /* don't overflow buf */
|
|
(*len)++; /* always increment len */
|
|
}
|
|
}
|
|
|
|
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode);
|
|
|
|
*bufPtr = NULLC; /* null terminate the string */
|
|
putchar(NEWLINE);
|
|
|
|
return ((*len <= buflen) ? 0 : NERR_BufTooSmall);
|
|
}
|
|
|
|
|
|
/*** GetString -- read in string with echo
|
|
*
|
|
* DWORD GetString(char far *, USHORT, USHORT far *, char far *);
|
|
*
|
|
* ENTRY: buf buffer to put string in
|
|
* buflen size of buffer
|
|
* &len address of USHORT to place length in
|
|
* &terminator holds the char used to terminate the string
|
|
*
|
|
* RETURNS:
|
|
* 0 or NERR_BufTooSmall if user typed too much. Buffer
|
|
* contents are only valid on 0 return. Len is ALWAYS valid.
|
|
*
|
|
* OTHER EFFECTS:
|
|
* len is set to hold number of bytes typed, regardless of
|
|
* buffer length. Terminator (Arnold) is set to hold the
|
|
* terminating character (newline or EOF) that the user typed.
|
|
*
|
|
* Read in a string a character at a time. Is aware of DBCS.
|
|
*
|
|
* History:
|
|
* who when what
|
|
* erichn 5/11/89 initial code
|
|
* dannygl 5/28/89 modified DBCS usage
|
|
* danhi 3/20/91 ported to 32 bits
|
|
*/
|
|
|
|
DWORD
|
|
GetString(
|
|
LPTSTR buf,
|
|
DWORD buflen,
|
|
PDWORD len,
|
|
LPTSTR terminator
|
|
)
|
|
{
|
|
int c;
|
|
int err;
|
|
|
|
buflen -= 1; /* make space for null terminator */
|
|
*len = 0; /* GP fault probe (a la API's) */
|
|
|
|
while (TRUE)
|
|
{
|
|
err = ReadConsole(GetStdHandle(STD_INPUT_HANDLE), buf, 1, &c, 0);
|
|
if (!err || c != 1)
|
|
*buf = 0xffff;
|
|
|
|
if (*buf == (TCHAR)EOF)
|
|
break;
|
|
if (*buf == RETURN || *buf == NEWLINE) {
|
|
INPUT_RECORD ir;
|
|
int cr;
|
|
|
|
if (PeekConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &ir, 1, &cr))
|
|
ReadConsole(GetStdHandle(STD_INPUT_HANDLE), buf, 1, &c, 0);
|
|
break;
|
|
}
|
|
|
|
buf += (*len < buflen) ? 1 : 0; /* don't overflow buf */
|
|
(*len)++; /* always increment len */
|
|
}
|
|
|
|
*terminator = *buf; /* set terminator */
|
|
*buf = NULLC; /* null terminate the string */
|
|
|
|
return ((*len <= buflen) ? 0 : NERR_BufTooSmall);
|
|
}
|