Windows NT 4.0 source code leak
 
 
 
 
 
 

521 lines
14 KiB

#include "abridge.h"
#include <windows.h>
#include <windowsx.h>
#include <winbase.h>
#include <io.h>
#include <stdio.h>
#include <direct.h>
#include <stdlib.h>
#include <string.h>
#include "fileutil.h"
#include "filing.h"
/* reserved DOS key words */
char *p_dos_resv[] = { "CLOCK$", "CON", "AUX", "COM1", "COM2", "COM3",
"COM4", "LPT1", "LPT2", "LPT3", "PRN" };
#define NUM_RESV_WORDS 11
/* Procedure converts an integer to an ascii string (2 <= base <= 36) */
LPSTR PASCAL intoa (i, str, base)
int i;
LPSTR str;
int base;
{
return(_itoa(i,str,base));
}
/*****************************************************************/
/* Procedure convert a long integer to an ascii string (2 <= base <= 36) */
LPSTR PASCAL lntoa (i, str, base)
LONG i;
LPSTR str;
int base;
{
return(_ltoa(i,str,base));
}
/*****************************************************************/
/* Procedure convert an ascii strin to an unsigned long */
unsigned long PASCAL atoul ( s )
LPSTR s;
{
LPSTR lpTemp;
return(strtoul(s,&lpTemp,10));
}
/*****************************************************************/
/* Procedure convert an ascii string to an unsigned integer */
unsigned PASCAL atoun ( s )
LPSTR s;
{
LPSTR lpTemp;
return((unsigned int)strtoul(s,&lpTemp,10));
}
VOID PASCAL AddSlash (str)
LPSTR str;
{
/* if the last char isn't a slash add one */
if (lstrlen(str) != 0)
{
if (*lstrlast(str) != '\\')
lstrcat(str, "\\");
}
}
BOOL PASCAL DosNameValid (str, p)
LPSTR str;
LPSTR p; /* p == NULL if no '.' */
{
char hold_str[MAXFILELENGTH];
int c = 0;
BOOL bRetcode;
int i, len_str, len_resv;
lstrcpy((LPSTR)hold_str, str);/* copy the string so we can muddle with it */
/* check for invalid characters according to dos 5.0 */
/* Begin DBCS Enable */
while (hold_str[c])
{
if (IsDBCSLeadByte(hold_str[c]))
c++;
else
{
if (!(IsCharAlphaNumeric(hold_str[c]) ||
(hold_str[c] == '_') ||
(hold_str[c] == '^') ||
(hold_str[c] == '$') ||
(hold_str[c] == '~') ||
(hold_str[c] == '!') ||
(hold_str[c] == '#') ||
(hold_str[c] == '%') ||
(hold_str[c] == '&') ||
(hold_str[c] == '-') ||
(hold_str[c] == '{') ||
(hold_str[c] == '}') ||
(hold_str[c] == '(') ||
(hold_str[c] == ')') ||
(hold_str[c] == '@') ||
(hold_str[c] == '`') ||
(hold_str[c] == '.') ||
(hold_str[c] == '\'')))
break;
/* End DBCS Enable */
}
c++;
}
if ((c < MAXFILELENGTH) && (hold_str[c] != 0))
return (bRetcode=FALSE);
AnsiUpper(hold_str);
/* check for reserved DOS 5.0 filenames */
/* CLOCK$, CON, AUX, COMn (where n = 1-4), LPTn (where n = 1-3) and PRN */
/* Look for the reserved DOS key words, reserved letter combinations are: */
/* CLOCK$, CLOCK$.xxx where xxx can be any letters or NULL. */
/* The following letter combination is not reserved: */
/* CLOCK$n.xxx where n can be any letter xxx can be any letters or NULL. */
/* I assume the same rules hold for the other reserved key words */
/* i have no idea HOW to internationalize this, or even if its neccessary */
bRetcode = TRUE;
i = 0;
while ((i < NUM_RESV_WORDS) && (bRetcode == TRUE))
{
bRetcode = TRUE;
/* Begin DBCS Enable */
len_resv = lstrlen(p_dos_resv[i]);
if (lstrcmpi( hold_str, p_dos_resv[i] ) == 0 )
{
if ( (len_str = lstrlen(hold_str)) == len_resv )
bRetcode = FALSE;
if (bRetcode == TRUE)
if (!IsDBCSLeadByte(hold_str[len_resv-1]))
if ( hold_str[len_resv] == '.' ) bRetcode = FALSE;
/* End DBCS Enable */
if (bRetcode == TRUE) i = NUM_RESV_WORDS;
}
i++;
}
return(bRetcode);
}
/*****************************************************************/
/* Take away the path name, return the file name only */
/* e.g. c:\oi\junk.doc will return junk.doc */
/*****************************************************************/
LPSTR PASCAL StripPathName(str)
LPSTR str;
{
LPSTR p;
/* look for slash first and then colon */
if ((p = lstrrchr(str,'\\')) == NULL)
p = lstrrchr(str, ':');
if (p) /* found one of them */
{
if (lstrlen(p) > 1)
p = (LPSTR) AnsiNext(p);
else
p = NULL;
}
else /* is something there ?? */
{
if (lstrlen(str) == 0)
p = NULL;
else
p = str;
}
return p;
}
/*****************************************************************/
BOOL PASCAL AValidFileName (str)
LPSTR str;
{
LPSTR p, p1;
LPBYTE p2; /* this is a fix cause valid macros need unsigned chars */
leftjust(str); /* left justify the string */
if (!lstrlen(str)) return FALSE; /* return false on empty string */
// 9504.18 rwr replace 8.3 length validation with MAXPATHLENGTH
// if (lstrlen(str) > (MAXFNAME + MAXEXT - 2)) /* > 12 characters */
if (lstrlen(str) > MAXPATHLENGTH)
return FALSE;
p = lstrchr(str, '.'); /* find first '.' */
p1 = lstrrchr(str, '.'); /* find last '.' */
if (p != p1) /* more then one dot in the filename */
return FALSE;
if (p == NULL) /* no extension in the filename */
{
// 9504.18 rwr long filename support (no more validation here)
// if (lstrlen(str) > (MAXFNAME - 1)) /* can't be > 8 chars */
// return FALSE;
p1 = str + lstrlen(str); /* set p1 for use when validating name */
}
else
{
// 9504.18 rwr long filename support (no more validation here)
// if (lstrlen(p) > (MAXEXT - 1)) /* extension can't be > 4 w/dot */
// return FALSE;
// 9504.18 rwr long filename support (no more validation here)
// if ((p - str) > (MAXFNAME - 1)) /* name can't be > 8 */
// return FALSE;
p2 = (LPBYTE)p;
for (p2++; *p2; p2++) /* check all characters after the dot */
/* Begin DBCS Enable */
{
if (IsDBCSLeadByte(*p2))
p2++;
else if (!(VALIDFNCHAR(*p2)))
return FALSE;
}
/* End DBCS Enable */
}
for (p2 = str; p2 != p1; p2++) /* check characters in the name */
/* Begin DBCS Enable */
{
if (IsDBCSLeadByte(*p2))
p2++;
else if (!(VALIDFNCHAR(*p2)))
return FALSE;
}
/* End DBCS Enable */
if (!DosNameValid(str,p))
return FALSE;
/* We made it!! return TRUE */
return TRUE;
}
/********************************************************************
* Procedure separates the path and filename adding if necessary the *
* current drive or current working directory to what was typed in *
* Input: String in Filename *
* Possible input c:, c:\,c:\junk.doc, c:\oi95\junk.doc, *
* junk.doc, oi95\junk.doc, \junk.doc,c:junk.doc *
* Output: Pathname and Filename *
*********************************************************************/
INT PASCAL SeparatePathFile (LPSTR PathName,LPSTR FileName)
{
INT wReturn,curDrive;
LPSTR lpName, lpTemp;
char szBuffer[MAXFILESPECLENGTH];
wReturn = SUCCESS;
lstrcpy(PathName, FileName);
// if file name only, get current drive and cwd
if (!(lstrchr(PathName, '\\')) && !(lstrchr(PathName,':')))
{
curDrive = _getdrive(); /* get the drive */
PathName[0] = curDrive+'A'-1;
PathName[1] = ':';
PathName[2] = '\0';
_getcwd((char *)szBuffer,sizeof(szBuffer));
lstrcpy(PathName,szBuffer);
return(TRUE);
}
lpName = StripPathName(PathName);
if (lpName != 0)
{
lstrcpy(FileName, lpName);
*lpName = '\0';
lpName--;
}
else
{
lpName = lstrlast(PathName);
*FileName = '\0'; // no filename
}
if (*PathName == '\\') /* root directory but we need the drive */
{ /* using space at end of filename so as not to use temp array */
lpTemp = lstrrcpy(PathName+3, PathName); /* Save PathName */
curDrive = _getdrive(); /* get the drive */
PathName[0] = curDrive+'A'-1;
PathName[1] = ':';
PathName[2] = '\0';
lstrcat(PathName, lpTemp); /* Concatenate PathName to drive */
lpName = lstrlast(PathName);
}
// e.g. oi95\junk.doc will treat as \oi95\junk.doc
if ((lstrchr(PathName, '\\')) &&
(!(lstrchr(PathName,':')))) /* call lgetcwd, add what we have to it */
{
lpTemp = FileName + lstrlen(FileName) + 1;
lstrcpy(lpTemp, PathName);
curDrive = _getdrive(); /* get the drive */
PathName[0] = curDrive+'A'-1;
PathName[1] = ':';
PathName[2] = '\\';
PathName[3] = '\0';
lstrcat(PathName, lpTemp);
lpName = lstrlast(PathName); /* Get last char in PathName */
}
/* if not the root directory, strip the '\' e.g. */
/* kmc - make sure lpName != NULL before trying to access it. */
if (lpName != NULL)
{
if ((lstrlen(PathName) > _MAX_DRIVE) && (*lpName == '\\'))
*lpName = '\0';
else /* check validity,expand if needed e.g. c: or c:junk.doc*/
{
if (*lpName != '\\') /* must be a drive */
{
if ((lstrlen(PathName) >= 2) && ( *FileName == '\0'))
wReturn = TRUE;
else
{ // don't know how big the PathName size is, use local varibale
if(_getdcwd(PathName[0]-'A'+1,(char *)szBuffer,
MAXFILESPECLENGTH) != NULL)
{
lstrcpy(PathName,szBuffer);
wReturn =0;
}
else
wReturn = FAILURE;
}
}
}
}
return (wReturn);
}
/*****************************************************************/
/* input is pointer to the string, and pointer to the '.' */
/* this routine assumes the name is not longer than 12 chars and */
/* that there is at most one '.' */
/*****************************************************************/
void PASCAL leftjust(instring)
LPSTR instring;
{
int buf_pos;
char far *p;
char far *s1;
// DBCS assume space 0x20 is always out of double-byte code ranage
s1 = instring;
for ( buf_pos = 0; s1[buf_pos] != 0; buf_pos++)
{
if (s1[buf_pos] != ' ')
{
break;
}
else
p = &s1[buf_pos+1];
}
if (buf_pos != 0)
lstrcpy(s1, p);
}
/*****************************************************************/
/*****
This Function finds tokens in string1 based on delimiters in
string2 see c runtime strtok.
NOTE: MAKE SURE the data cannot move between a (s1 == NULL) call
and it's predecessor....
lstrtok may be called iteratively for the same string, to find all tokens.
lstrtok has been rewritten to remove the next_token_position static
variable. Now the calling procedure must allocate the space to hold the
NextTokenPosition from the previous call. On the first call to parse a
particular string *lpNextTokenPosition is set = 0, but on subsequent calls it
holds the result of the previous call.
*****/
LPSTR PASCAL lstrtok ( s1, d1, lpNextTokenPosition)
LPSTR s1; /* string */
LPSTR d1; /* delimiter */
LPSTR lpNextTokenPosition;
{
LPSTR s2;
LPSTR d2;
if ( d1 );
else
return ( NULL );
if ( s1 == NULL )
if ( *(s1 = lpNextTokenPosition) );
else
return (s1);
/***** EAT DELIMITER'S OR NULL UI BREATH *****/
while ( *s1 )
{
s2 = s1;
d2 = d1;
while ( *s2 != *d2 )
{
if ( *d2 == (char)NULL )
break;
d2++;
}
if ( *d2 == (char)NULL )
break;
else
s1++;
}
/***** FIND A DELIMITER OR NULL UI BREATH *****/
s2 = s1;
while ( *s2 )
{
d2 = d1;
while ( *s2 != *d2 )
{
if ( *d2 == (char)NULL )
break;
d2++;
}
if ( *s2 == *d2 )
{
*s2++ = (char)NULL;
break;
}
s2++;
}
lpNextTokenPosition = s2;
return ( s1 );
}
/*****************************************************************/
/*****
This Function finds an occurrance of sting2 in string1 or returns
NULL see c runtime strstr
*****/
LPSTR PASCAL lstrstr ( s1, s2 )
LPSTR s1;
LPSTR s2;
{
LPSTR s3;
LPSTR s4;
if ( s1 == NULL || s2 == NULL )
return ( NULL );
while ( *s1 )
{
if ( (lstrlen(s2)) > (lstrlen(s1)) )
return (NULL);
s3 = s1;
s4 = s2;
while ( *s3 == *s4 )
{
if ( *s4 == (char)NULL )
break;
s3++;
s4++;
}
if ( *s4 == (char)NULL )
break;
s1++;
}
return ( s1 );
}
/***************************************************************************
* wcreat(filename, mode)
*
* This functions creates a file, failing if the file already exists
* (or for various other reasons too numerous to mention).
***************************************************************************/
int FAR wcreat (LPSTR lpszPath, WORD wMode)
{
union {
HANDLE hfile; // Returned from CreateFile()
int ifile; // Pseudonym for "hfile" to avoid compiler warning
} wcreatvar;
wcreatvar.hfile = CreateFile(lpszPath,GENERIC_WRITE,0,NULL,CREATE_NEW,0,NULL);
if (wcreatvar.hfile == INVALID_HANDLE_VALUE)
return(-1);
else
return(wcreatvar.ifile);
}
/***************************************************************************
* farbmcopy(source, destination, srcpitch, dstpitch, linewidth, linecount)
*
* This function copies source image lines to destination lines, allowing
* for (but not padding) actual source and destination line lengths
***************************************************************************/
void farbmcopy(LPSTR lpSource, LPSTR lpDest,
unsigned SourcePitch, unsigned DestPitch,
unsigned uWidth, unsigned uCount)
{
unsigned index;
for (index = 1 ; index <= uCount ; ++index)
{
memcpy(lpDest,lpSource,uWidth);
lpSource += SourcePitch;
lpDest += DestPitch;
}
return;
}