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.
 
 
 
 
 
 

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
}