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.
273 lines
6.7 KiB
273 lines
6.7 KiB
/*++
|
|
|
|
Copyright (c) 1987 - 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
library.c
|
|
|
|
Provides similar functionality to rpllib.c in LANMAN 2.1 code.
|
|
|
|
Abstract:
|
|
|
|
Common library routines.
|
|
|
|
Author:
|
|
|
|
Vladimir Z. Vulovic 25 - July - 1993
|
|
|
|
Environment:
|
|
|
|
User mode
|
|
|
|
Revision History :
|
|
|
|
--*/
|
|
|
|
#include "local.h"
|
|
|
|
|
|
|
|
LPWSTR RplGetLastPathComponent( IN LPWSTR path_str)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Returns the last component of the path.
|
|
|
|
Arguments:
|
|
path_str - pointer to path string
|
|
|
|
Return Value:
|
|
Pointer to the last component of the path.
|
|
|
|
--*/
|
|
{
|
|
LPWSTR ret_str;
|
|
WCHAR ch;
|
|
|
|
for( ch = *( ret_str = path_str); ch != 0; ch = *(++path_str)) {
|
|
if ( ch == '\\' || ch == '/') {
|
|
ret_str = path_str + 1; // remember most recent component
|
|
}
|
|
}
|
|
return( ret_str);
|
|
}
|
|
|
|
|
|
|
|
HANDLE RplFileOpen( IN LPWSTR FilePath)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Open existing file for reading, at the same time denying write
|
|
access to others. Note that WIN32 errors are basically identical
|
|
to OS/2 errors!
|
|
|
|
In case of special errors we may try a number of times to open the
|
|
requested file.
|
|
|
|
Arguments:
|
|
|
|
FilePath - of file to open
|
|
|
|
Return Value:
|
|
|
|
A valid file handle if successful, else INVALID_HANDLE_VALUE if
|
|
unsuccessful.
|
|
|
|
--*/
|
|
{
|
|
DWORD status;
|
|
DWORD retry_count;
|
|
HANDLE handle;
|
|
|
|
//
|
|
// If file is being used by another process, we make up to 40 retries
|
|
// each one lasting 0.750 seconds (for a max total of 30 seconds) before
|
|
// we resign. Configuration programs may lock the files temporarily,
|
|
// but if somebody locks a file for a long time, then we must die.
|
|
//
|
|
for ( retry_count = 0; retry_count < MAX_OPEN_RETRY; retry_count++) {
|
|
|
|
handle = CreateFile( FilePath, GENERIC_READ, FILE_SHARE_READ,
|
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0L);
|
|
if ( handle != INVALID_HANDLE_VALUE) {
|
|
return( handle); // success, all done
|
|
}
|
|
|
|
status = GetLastError();
|
|
|
|
if ( status != ERROR_SHARING_VIOLATION) {
|
|
break; // bad, unexpected case
|
|
}
|
|
|
|
Sleep( 750L );
|
|
}
|
|
RplReportEvent( NELOG_Init_OpenCreate_Err, FilePath, sizeof(WORD), (PBYTE)&status);
|
|
RplDump( RG_DebugLevel & RPL_DEBUG_MISC,( "FileOpen(%ws) failed, status = %d", FilePath, status));
|
|
return( INVALID_HANDLE_VALUE);
|
|
}
|
|
|
|
|
|
|
|
LPWSTR RplReadTextFile(
|
|
IN HANDLE MemoryHandle,
|
|
IN LPWSTR FileName,
|
|
IN DWORD MaxFileSize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Reads text file, converts its content from dbcs to unicode, and returns
|
|
a pointer to newly allocated unicode buffer.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
Pointer to unicode buffer table if successful, NULL otherwise.
|
|
|
|
--*/
|
|
{
|
|
PBYTE DbcsString = NULL;
|
|
DWORD DbcsSize;
|
|
PWCHAR UnicodeString;
|
|
DWORD UnicodeSize;
|
|
int UnicodeStringLength;
|
|
HANDLE FileHandle;
|
|
DWORD BytesRead;
|
|
BOOL success = FALSE;
|
|
PWCHAR pWchar;
|
|
|
|
RplDump( RG_DebugLevel & RPL_DEBUG_FLOW,( "++ReadTextFile:0x%x,%ws", MemoryHandle, FileName));
|
|
|
|
FileHandle = RplFileOpen( FileName);
|
|
if ( FileHandle == INVALID_HANDLE_VALUE) {
|
|
goto exit;
|
|
}
|
|
DbcsSize = GetFileSize( FileHandle, NULL); // does not include 0x1A at the file end
|
|
if ( DbcsSize == INVALID_FILE_SIZE || DbcsSize > MaxFileSize) {
|
|
goto exit;
|
|
}
|
|
DbcsString = RplMemAlloc( MemoryHandle, DbcsSize);
|
|
if ( DbcsString == NULL) {
|
|
goto exit;
|
|
}
|
|
|
|
UnicodeSize = ( DbcsSize + 1) * sizeof(WCHAR); // extra 1 for terminating NULL
|
|
UnicodeString = RplMemAlloc( MemoryHandle, UnicodeSize);
|
|
if ( UnicodeString == NULL) {
|
|
goto exit;
|
|
}
|
|
|
|
if ( !ReadFile( FileHandle, DbcsString, DbcsSize, &BytesRead, NULL)) {
|
|
goto exit;
|
|
}
|
|
|
|
if ( BytesRead != DbcsSize) {
|
|
goto exit;
|
|
}
|
|
|
|
UnicodeStringLength = MultiByteToWideChar(
|
|
CP_OEMCP, // text files stored in OEM
|
|
MB_PRECOMPOSED, DbcsString, DbcsSize, UnicodeString,
|
|
UnicodeSize);
|
|
if ( UnicodeStringLength == 0) {
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Null-terminate string! JonN 8/7/94
|
|
//
|
|
UnicodeString[ UnicodeStringLength] = 0;
|
|
|
|
//
|
|
// 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) {
|
|
RplMemFree( MemoryHandle, DbcsString);
|
|
}
|
|
|
|
if ( success != TRUE) {
|
|
RplMemFree( MemoryHandle, UnicodeString);
|
|
UnicodeString = NULL;
|
|
}
|
|
|
|
RplDump( RG_DebugLevel & RPL_DEBUG_FLOW,( "--ReadTextFile:0x%x,%ws", MemoryHandle, FileName));
|
|
return( UnicodeString);
|
|
|
|
} // RplReadTextFile
|
|
|
|
|
|
DWORD RplUnicodeToDbcs(
|
|
IN HANDLE MemoryHandle,
|
|
IN LPWSTR UnicodeString,
|
|
IN INT UnicodeStringLength,
|
|
IN DWORD MaxDbcsStringSize,
|
|
OUT LPSTR * pDbcsString
|
|
)
|
|
/*++
|
|
Allocates DBCS string corresponding to a UNICODE string.
|
|
|
|
Returns size of buffer needed for DbcsString, counting space needed for
|
|
the terminal null byte.
|
|
--*/
|
|
{
|
|
LPSTR DbcsString;
|
|
DWORD ByteCount;
|
|
|
|
if ( UnicodeStringLength == -1) {
|
|
UnicodeStringLength = wcslen( UnicodeString);
|
|
}
|
|
|
|
//
|
|
// Assumed the worst case where every UNICODE char maps to a double
|
|
// byte DBCS char (except for DBCS terminating null char).
|
|
//
|
|
ByteCount = UnicodeStringLength * sizeof(WCHAR) + sizeof(CHAR);
|
|
|
|
//
|
|
// If caller's limit is more stringent, use it.
|
|
//
|
|
if ( ByteCount > MaxDbcsStringSize) {
|
|
ByteCount = MaxDbcsStringSize;
|
|
}
|
|
|
|
DbcsString = RplMemAlloc( MemoryHandle, ByteCount);
|
|
if ( DbcsString == NULL) {
|
|
RPL_RETURN( 0);
|
|
}
|
|
|
|
ByteCount = WideCharToMultiByte( // not counting terminal null byte
|
|
CP_OEMCP, // always use OEM
|
|
0,
|
|
UnicodeString,
|
|
UnicodeStringLength,
|
|
DbcsString, // dbcs string
|
|
ByteCount,
|
|
NULL, // no default character
|
|
NULL // no default character flag
|
|
);
|
|
if ( ByteCount == 0) {
|
|
RplMemFree( MemoryHandle, DbcsString);
|
|
RPL_RETURN( 0);
|
|
}
|
|
DbcsString[ ByteCount] = 0; // this may be redundant
|
|
*pDbcsString = DbcsString;
|
|
return( ByteCount + 1); // caller expects terminal null byte to be counted
|
|
}
|
|
|