Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

330 lines
8.8 KiB

/*++
Copyright (c) 1987-1993 Microsoft Corporation
Module Name:
library.c
Abstract:
Common routines used in CONVERT code.
Author:
Vladimir Z. Vulovic (vladimv) 19 - November - 1993
Revision History:
Jon Newman (jonn) 06 - June - 1994
Convert file from OEM code page
--*/
#include "local.h"
LPWSTR ReadTextFile(
IN LPWSTR FilePath,
IN LPWSTR FileName,
IN DWORD MaxFileSize
)
/*++
Routine Description:
Reads text file, converts its content from dbcs to unicode, and returns
a pointer to newly allocate unicode buffer.
Arguments:
Return Value:
Pointer to unicode buffer table if successful, NULL otherwise.
--*/
{
PBYTE DbcsString = NULL;
DWORD DbcsSize;
PWCHAR UnicodeString = NULL;
DWORD UnicodeSize;
int UnicodeStringLength;
HANDLE FileHandle;
DWORD BytesRead;
BOOL success = FALSE;
PWCHAR pWchar;
WCHAR CompleteFilePath[ MAX_PATH+1];
PWCHAR UseFilePath = FileName;
CompleteFilePath[0] = L'\0';
if ( FilePath != NULL && lstrlenW(FilePath) > 0) {
lstrcpyW( CompleteFilePath, FilePath);
if ( CompleteFilePath[ lstrlenW(CompleteFilePath)-1 ] != L'\\') {
lstrcatW( CompleteFilePath, L"\\");
}
if ( FileName != NULL) {
lstrcatW( CompleteFilePath, FileName );
}
UseFilePath = CompleteFilePath;
}
FileHandle = CreateFile( UseFilePath, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0L);
if ( FileHandle == INVALID_HANDLE_VALUE) {
//
// Specifying a bad path (path with missing OS/2 rpl init files)
// is a common user error. Print out something for the user.
//
RplAssert( TRUE, ("CreateFile: Error = %d", GetLastError()));
RplPrintf1( RPLI_CVT_CannotOpenFile, UseFilePath);
goto exit;
}
DbcsSize = GetFileSize( FileHandle, NULL); // does not include 0x1A at the file end
if ( DbcsSize == INVALID_FILE_SIZE || DbcsSize > MaxFileSize) {
RplAssert( TRUE, ("DbcsSize = %d", DbcsSize));
goto exit;
}
DbcsString = GlobalAlloc( GMEM_FIXED, DbcsSize);
if ( DbcsString == NULL) {
RplAssert( TRUE, ("GlobalAlloc: Error = %d", GetLastError()));
goto exit;
}
UnicodeSize = ( DbcsSize + 1) * sizeof(WCHAR); // extra 1 for terminating NULL
UnicodeString = GlobalAlloc( GMEM_FIXED, UnicodeSize);
if ( UnicodeString == NULL) {
RplAssert( TRUE, ("GlobalAlloc: Error = %d", GetLastError()));
goto exit;
}
if ( !ReadFile( FileHandle, DbcsString, DbcsSize, &BytesRead, NULL)) {
RplAssert( TRUE, ("ReadFile: Error = %d", GetLastError()));
goto exit;
}
if ( BytesRead != DbcsSize) {
RplAssert( TRUE, ("BytesRead = %d, DbcsSize", BytesRead, DbcsSize));
goto exit;
}
UnicodeStringLength = MultiByteToWideChar(
CP_OEMCP, // file is in OEM codepage
MB_PRECOMPOSED, DbcsString, DbcsSize, UnicodeString, UnicodeSize);
if ( UnicodeStringLength == 0) {
RplAssert( TRUE, ("MultiByte...: Error = %d", GetLastError()));
goto exit;
}
//
// If file has END_OF_TEXT_FILE_CHAR, truncate the text there.
//
pWchar = wcschr( UnicodeString, END_OF_TEXT_FILE_CHAR);
if ( pWchar != NULL) {
*pWchar = 0;
}
success = TRUE;
exit:
if ( FileHandle != INVALID_HANDLE_VALUE) {
(VOID)CloseHandle( FileHandle);
}
if ( DbcsString != NULL) {
GlobalFree( DbcsString);
}
if ( success != TRUE && UnicodeString != NULL) {
GlobalFree( UnicodeString);
UnicodeString = NULL;
}
return( UnicodeString);
} // ReadTextFile
PWCHAR GetFirstLine( PWCHAR Cursor)
/*++
Skips all white characters.
--*/
//
{
// Read empty chars if there's some.
while( *Cursor != 0 && iswspace(*Cursor)) {
Cursor++;
}
return( Cursor);
}
PWCHAR GetNextLine( PWCHAR Cursor)
/*++
Skips to the end of the current line.
Then skips all white characters.
--*/
//
{
// Read to end of line.
do {
Cursor++;
} while ( *Cursor != 0 && *Cursor != NEW_LINE_CHAR);
// Read empty chars if there's some.
while( *Cursor != 0 && iswspace(*Cursor)) {
Cursor++;
}
return( Cursor);
}
DWORD OffsetAfterComment( IN PWCHAR Cursor)
/*++
Returns the offset of the first non-white non-newline character
after an optional RPL_COMMENT. This routine does not & should
not cross line boundaries (this is reserved for GetNewLine).
--*/
{
#define RPL_COMMENT L";*;"
#define RPL_COMMENT_LENGTH (sizeof(RPL_COMMENT)/sizeof(WCHAR) - 1)
PWCHAR End;
if ( wcsncmp( Cursor, RPL_COMMENT, RPL_COMMENT_LENGTH)) {
return( 0); // there is no RPL_COMMENT
}
for ( End = Cursor + RPL_COMMENT_LENGTH;
*End != 0 && *End != NEW_LINE_CHAR && iswspace(*End);
End++) {
NOTHING;
}
if ( *End == NEW_LINE_CHAR) {
//
// We went to far. Must decrement end pointer or
// GetNewLine() will advance to the second next line.
//
End--;
}
return( (DWORD)(End - Cursor));
}
BOOL Find( IN JET_TABLEID TableId, IN PWCHAR Name)
{
JET_ERR JetError;
JetError = JetMove( SesId, TableId, JET_MoveFirst, 0);
if ( JetError != JET_errSuccess) {
RplAssert( TRUE, ("JetMove failed err=%d", JetError));
return( FALSE);
}
JetError = JetMakeKey( SesId, TableId, Name,
( wcslen( Name) + 1) * sizeof(WCHAR), JET_bitNewKey);
if ( JetError != JET_errSuccess) {
RplAssert( TRUE, ("MakeKey failed err=%d", JetError));
return( FALSE);
}
JetError = JetSeek( SesId, TableId, JET_bitSeekEQ);
if ( JetError != JET_errSuccess) {
if ( JetError == JET_errRecordNotFound) {
//
// This is an expected error => no break for this.
//
RplDbgPrint(("JetSeek for %ws failed with error = %d.\n", Name, JetError));
} else {
RplAssert( TRUE, ("JetSeek failed err=%d", JetError));
}
return( FALSE);
}
return( TRUE);
}
VOID Enum( IN JET_TABLEID TableId, IN JET_COLUMNID ColumnId, IN PCHAR IndexName)
{
WCHAR Name[ 20];
DWORD NameSize;
JET_ERR ForJetError;
JET_ERR JetError;
Call( JetSetCurrentIndex( SesId, TableId, IndexName));
for ( ForJetError = JetMove( SesId, TableId, JET_MoveFirst, 0);
ForJetError == JET_errSuccess;
ForJetError = JetMove( SesId, TableId, JET_MoveNext, 0)) {
JetError = JetRetrieveColumn( SesId, TableId,
ColumnId, Name, sizeof( Name), &NameSize, 0, NULL);
if ( JetError != JET_errSuccess) {
RplAssert( TRUE, ("RetriveColumn failed err=%d", JetError));
continue;
}
RplDbgPrint(( "%ws\n", Name));
}
}
VOID ListTable( IN PCHAR TableName, IN PCHAR ColumnName, IN PCHAR IndexName)
{
JET_TABLEID TableId;
JET_COLUMNDEF ColumnDef;
Call( JetOpenTable( SesId, DbId, TableName, NULL, 0,
JET_bitTableDenyWrite, &TableId));
Call( JetGetTableColumnInfo( SesId, TableId, ColumnName, &ColumnDef,
sizeof( ColumnDef), JET_ColInfo));
RplDbgPrint(( "\tTable: %s\n", TableName));
Enum( TableId, ColumnDef.columnid, IndexName);
Call( JetCloseTable( SesId, TableId));
}
PWCHAR AddFileExtension(
IN PWCHAR FilePath,
IN PWCHAR FileExtension,
IN BOOLEAN ExtensionOK
)
{
#define DOT_CHAR L'.'
#define BACK_SLASH_CHAR L'\\'
PWCHAR FilePathEx;
PWCHAR pDot;
DWORD Length;
DWORD Error;
if ( FilePath == NULL) {
RplAssert( TRUE, ("FilePath is NULL"));
return( NULL);
}
pDot = wcsrchr( FilePath, DOT_CHAR);
if ( pDot != NULL) {
//
// Found a DOT. FilePath may have an extension.
//
if ( wcschr( pDot, BACK_SLASH_CHAR) == NULL) {
//
// There is no backslash after the DOT. FilePath has an extension.
// Return NULL if caller insists that file should have no extension.
//
return( ExtensionOK ? FilePath : NULL);
}
}
Length = wcslen( FilePath) + wcslen( FileExtension);
FilePathEx = GlobalAlloc( GMEM_FIXED, (Length + 1) * sizeof(WCHAR));
if ( FilePathEx == NULL) {
Error = GetLastError();
RplAssert( TRUE, ("GlobalAlloc: Error = %d", Error));
return( NULL);
}
wcscpy( FilePathEx, FilePath);
wcscat( FilePathEx, FileExtension);
return( FilePathEx);
}