mirror of https://github.com/lianthony/NT4.0
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
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);
|
|
}
|