|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
fileio.c
Abstract:
This source implements a stdio-like facility.
Author:
Jim Stewart June 1993
Revision History:
--*/
#include "precomp.h"
#include "hosts.h"
#include <string.h>
//
// Private Definitions
//
//
// Local Variables
//
//
// Local (Private) Functions
//
PUCHAR LmpMapFile ( IN HANDLE handle, IN OUT int *pnbytes );
//******************* Pageable Routine Declarations ****************
#ifdef ALLOC_PRAGMA
#pragma CTEMakePageable(PAGE, LmCloseFile)
#pragma CTEMakePageable(PAGE, LmFgets)
#pragma CTEMakePageable(PAGE, LmpMapFile)
#pragma CTEMakePageable(PAGE, LmOpenFile)
#endif
//******************* Pageable Routine Declarations ****************
//----------------------------------------------------------------------------
NTSTATUS LmCloseFile ( IN PLM_FILE pfile )
/*++
Routine Description:
This function closes a file opened via LmOpenFile(), and frees its LM_FILE object.
Arguments:
pfile - pointer to the LM_FILE object
Return Value:
An NTSTATUS value.
--*/
{ NTSTATUS status;
CTEPagedCode(); CTEMemFree(pfile->f_buffer);
status = ZwClose(pfile->f_handle);
ASSERT(status == STATUS_SUCCESS);
CTEMemFree(pfile);
return(status);
} // LmCloseFile
//----------------------------------------------------------------------------
PUCHAR LmFgets ( IN PLM_FILE pfile, OUT int *nbytes )
/*++
Routine Description:
This function is vaguely similar to fgets(3).
Starting at the current seek position, it reads through a newline character, or the end of the file. If a newline is encountered, it is replaced with a NULL character.
Arguments:
pfile - file to read from nbytes - the number of characters read, excluding the NULL character
Return Value:
A pointer to the beginning of the line, or NULL if we are at or past the end of the file.
--*/
{ PUCHAR endOfLine; PUCHAR startOfLine; size_t maxBytes;
CTEPagedCode(); startOfLine = pfile->f_current;
if (startOfLine >= pfile->f_limit) {
return((PUCHAR) NULL); }
maxBytes = (size_t)(pfile->f_limit - pfile->f_current); endOfLine = (PUCHAR) memchr(startOfLine, (UCHAR) '\n', maxBytes);
if (!endOfLine) { IF_DBG(NBT_DEBUG_LMHOST) KdPrint(("NBT: lmhosts file doesn't end in '\\n'")); endOfLine = pfile->f_limit; }
*endOfLine = (UCHAR) NULL;
pfile->f_current = endOfLine + 1; (pfile->f_lineno)++; ASSERT(pfile->f_current <= pfile->f_limit+1);
*nbytes = (int)(endOfLine - startOfLine);
return(startOfLine);
} // LmFgets
//----------------------------------------------------------------------------
PUCHAR LmpMapFile ( IN HANDLE handle, IN OUT int *pnbytes )
/*++
Routine Description:
This function reads an entire file into memory.
Arguments:
handle - file handle pnbytes - size of the whole file
Return Value:
the buffer allocated, or NULL if unsuccessful.
--*/
{ PUCHAR buffer; NTSTATUS status; IO_STATUS_BLOCK iostatus; FILE_STANDARD_INFORMATION stdInfo; LARGE_INTEGER offset ={0, 0}; LARGE_INTEGER length ={0x7fffffff, 0x7fffffff};
CTEPagedCode();
status = ZwQueryInformationFile( handle, // FileHandle
&iostatus, // IoStatusBlock
(PVOID) &stdInfo, // FileInformation
sizeof(stdInfo), // Length
FileStandardInformation); // FileInformationClass
if (status != STATUS_SUCCESS) { IF_DBG(NBT_DEBUG_LMHOST) KdPrint(("NBT: ZwQueryInformationFile(std) = %X\n", status)); return(NULL); }
length = stdInfo.EndOfFile; // structure copy
if (length.HighPart) { return(NULL); }
buffer = NbtAllocMem (length.LowPart+2, NBT_TAG2('18'));
if (buffer != NULL) {
status = ZwReadFile( handle, // FileHandle
NULL, // Event
NULL, // ApcRoutine
NULL, // ApcContext
&iostatus, // IoStatusBlock
buffer, // Buffer
length.LowPart, // Length
&offset, // ByteOffset
NULL); // Key
if (status != STATUS_SUCCESS) { IF_DBG(NBT_DEBUG_LMHOST) KdPrint(("NBT: ZwReadFile(std) = %X\n", status)); }
ASSERT(status != STATUS_PENDING);
if (iostatus.Status != STATUS_SUCCESS || status != STATUS_SUCCESS) { CTEMemFree(buffer); return(NULL); }
*pnbytes = length.LowPart; } return(buffer);
} // LmpMapFile
//----------------------------------------------------------------------------
PLM_FILE LmOpenFile ( IN PUCHAR path )
/*++
Routine Description:
This function opens a file for use by LmFgets().
Arguments:
path - a fully specified, complete path to the file.
Return Value:
A pointer to an LM_FILE object, or NULL if unsuccessful.
--*/
{ NTSTATUS status; HANDLE handle; PLM_FILE pfile; IO_STATUS_BLOCK iostatus; OBJECT_ATTRIBUTES attributes; UNICODE_STRING ucPath; PUCHAR start; int nbytes; OEM_STRING String; PUCHAR LongerPath;
CTEPagedCode(); ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
status = LmGetFullPath(path,&LongerPath);
if (NT_SUCCESS(status)) { RtlInitString(&String,LongerPath);
status = RtlAnsiStringToUnicodeString(&ucPath,&String,TRUE);
if (NT_SUCCESS(status)) {
#ifdef HDL_FIX
InitializeObjectAttributes (&attributes, // POBJECT_ATTRIBUTES
&ucPath, // ObjectName
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, // Attributes
(HANDLE) NULL, // RootDirectory
(PSECURITY_DESCRIPTOR) NULL); // SecurityDescriptor
#else
InitializeObjectAttributes (&attributes, // POBJECT_ATTRIBUTES
&ucPath, // ObjectName
OBJ_CASE_INSENSITIVE, // Attributes
(HANDLE) NULL, // RootDirectory
(PSECURITY_DESCRIPTOR) NULL); // SecurityDescriptor
#endif // HDL_FIX
status = ZwCreateFile (&handle, // FileHandle
SYNCHRONIZE | FILE_READ_DATA, // DesiredAccess
&attributes, // ObjectAttributes
&iostatus, // IoStatusBlock
0, // AllocationSize
FILE_ATTRIBUTE_NORMAL, // FileAttributes
FILE_SHARE_READ | FILE_SHARE_WRITE, // ShareAccess
FILE_OPEN, // CreateDisposition
FILE_SYNCHRONOUS_IO_NONALERT, // OpenOptions
NULL, // EaBuffer
0); // EaLength
if (NT_SUCCESS(status)) { start = LmpMapFile(handle, &nbytes);
if (start) { pfile = (PLM_FILE) NbtAllocMem (sizeof(LM_FILE), NBT_TAG2('19')); if (pfile) { KeInitializeSpinLock(&(pfile->f_lock));
pfile->f_refcount = 1; pfile->f_handle = handle; pfile->f_lineno = 0; pfile->f_fileOffset.HighPart = 0; pfile->f_fileOffset.LowPart = 0;
pfile->f_current = start; pfile->f_buffer = start; pfile->f_limit = pfile->f_buffer + nbytes;
RtlFreeUnicodeString(&ucPath); CTEMemFree(LongerPath);
return(pfile); }
CTEMemFree(start); }
ZwClose(handle); }
RtlFreeUnicodeString(&ucPath);
IF_DBG(NBT_DEBUG_LMHOST) KdPrint(("Nbt.LmOpenFile: ZwOpenFile(std) = %X\n", status));
}
CTEMemFree(LongerPath); }
return((PLM_FILE) NULL);
} // LmOpenFile
|