Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

388 lines
9.4 KiB

/*++
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