389 lines
9.4 KiB
C
389 lines
9.4 KiB
C
/*++
|
||
|
||
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
|
||
|