|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
nullio.c
Abstract:
This module implements io on the 'null' device. It's pretty simple.
Author:
Matthew Bradburn (mattbr) 01-Aug-1995
Revision History:
--*/
#include <sys/stat.h>
#include <time.h>
#include <wchar.h>
#include "psxsrv.h"
BOOLEAN NullOpen( IN PPSX_PROCESS p, IN PFILEDESCRIPTOR Fd, IN OUT PPSX_API_MSG m );
BOOLEAN NullRead( IN PPSX_PROCESS p, IN OUT PPSX_API_MSG m, IN PFILEDESCRIPTOR Fd );
BOOLEAN NullWrite( IN PPSX_PROCESS p, IN OUT PPSX_API_MSG m, IN PFILEDESCRIPTOR Fd );
BOOLEAN NullDup( IN PPSX_PROCESS p, IN OUT PPSX_API_MSG m, IN PFILEDESCRIPTOR Fd, IN PFILEDESCRIPTOR FdDup );
BOOLEAN NullLseek( IN PPSX_PROCESS p, IN OUT PPSX_API_MSG m, IN PFILEDESCRIPTOR Fd );
BOOLEAN NullStat( IN PIONODE IoNode, IN HANDLE FileHandle, OUT struct stat *StatBuf, OUT NTSTATUS *pStatus );
void FindOwnerModeFile( IN HANDLE FileHandle, OUT struct stat *StatBuf );
PSXIO_VECTORS NullVectors = { NullOpen, // OpenNewHandle
NULL, // NewHandle
NULL, // Close
NULL, // LastClose
NULL, // IoNodeClose
NullRead, // Read
NullWrite, // Write
NullDup, // Dup
NullLseek, // Lseek
NullStat // Stat
};
BOOLEAN NullOpen( IN PPSX_PROCESS p, IN PFILEDESCRIPTOR Fd, IN OUT PPSX_API_MSG m ) /*++
Routine Description:
This routine
Arguments:
Return Value:
FALSE - Failure. TRUE - Success.
--*/ { PPSX_OPEN_MSG args; LARGE_INTEGER time; ULONG posix_time;
args = &m->u.Open;
NtQuerySystemTime(&time); if (!RtlTimeToSecondsSince1970(&time, &posix_time)) { posix_time = 0; }
KdPrint(("Posix time: %x\n", posix_time));
RtlEnterCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock); Fd->SystemOpenFileDesc->IoNode->ModifyDataTime = posix_time; Fd->SystemOpenFileDesc->IoNode->ModifyIoNodeTime = posix_time; Fd->SystemOpenFileDesc->IoNode->AccessDataTime = posix_time; RtlLeaveCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock);
return TRUE; }
BOOLEAN NullWrite( IN PPSX_PROCESS p, IN OUT PPSX_API_MSG m, IN PFILEDESCRIPTOR Fd )
/*++
Routine Description:
This procedure implements write when the device being written is the null device. Writes to the null device succeed, and the data is discarded.
Arguments:
p - Supplies the address of the process making the call.
m - Supplies the address of the message associated with the request.
Fd - supplies the address of the file descriptor being written.
Return Value:
--*/
{ PPSX_WRITE_MSG args; LARGE_INTEGER time; ULONG posix_time; NTSTATUS st;
args = &m->u.Write;
if (args->Nbytes > 0) {
//
// Update the times for stat.
//
NtQuerySystemTime(&time); if (!RtlTimeToSecondsSince1970(&time, &posix_time)) { posix_time = 0; }
RtlEnterCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock); Fd->SystemOpenFileDesc->IoNode->ModifyDataTime = posix_time; Fd->SystemOpenFileDesc->IoNode->ModifyIoNodeTime = posix_time; RtlLeaveCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock); }
m->ReturnValue = args->Nbytes; return TRUE; }
BOOLEAN NullRead( IN PPSX_PROCESS p, IN OUT PPSX_API_MSG m, IN PFILEDESCRIPTOR Fd )
/*++
Routine Description:
This procedure implements read when the device being read is the null device. Reads from this device always return EOF.
Arguments:
p - Supplies the address of the process making the call.
m - Supplies the address of the message associated with the request.
Fd - supplies the address of the file descriptor being read.
Return Value:
--*/
{ PPSX_READ_MSG args; NTSTATUS st; LARGE_INTEGER ByteOffset; ULONG IoBufferSize; LARGE_INTEGER Time; ULONG posix_time;
args = &m->u.Read;
if (args->Nbytes > 0) {
//
// Update the access time on the ionode.
//
NtQuerySystemTime(&Time); if (!RtlTimeToSecondsSince1970(&Time, &posix_time)) { posix_time = 0; }
RtlEnterCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock); Fd->SystemOpenFileDesc->IoNode->AccessDataTime = posix_time; RtlLeaveCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock); }
m->ReturnValue = 0; return TRUE; }
BOOLEAN NullDup( IN PPSX_PROCESS p, IN OUT PPSX_API_MSG m, IN PFILEDESCRIPTOR Fd, IN PFILEDESCRIPTOR FdDup )
/*++
Routine Description:
This procedure implements dup and dup2.
Arguments:
p - Supplies the address of the process making the call.
m - Supplies the address of the message associated with the request.
Fd - supplies the address of the file descriptor being duplicated.
FdDup - supplies the address of the duplicate file descriptor.
Return Value:
TRUE. --*/
{ PPSX_DUP_MSG args;
args = &m->u.Dup;
//
// Copy contents of source file descriptor slot into new descriptor
// Note that FD_CLOEXEC must be CLEAR on FdDup.
//
*FdDup = *Fd; FdDup->Flags &= ~PSX_FD_CLOSE_ON_EXEC;
//
// Increment reference count associated with the SystemOpenFile
// descriptor for this file.
//
// Grab system open file lock
RtlEnterCriticalSection(&SystemOpenFileLock);
Fd->SystemOpenFileDesc->HandleCount++;
RtlLeaveCriticalSection(&SystemOpenFileLock);
return TRUE; }
BOOLEAN NullLseek( IN PPSX_PROCESS p, IN OUT PPSX_API_MSG m, IN PFILEDESCRIPTOR Fd )
/*++
Routine Description:
This procedure implements lseek when the device being seeked on is the null device. We allow these seeks, but they have no effect.
Arguments:
p - Supplies the address of the process making the call.
m - Supplies the address of the message associated with the request.
Fd - supplies the address of the file descriptor being seekd
Return Value:
TRUE
--*/
{ PPSX_LSEEK_MSG args; NTSTATUS st; LARGE_INTEGER Offset, NewByteOffset;
args = &m->u.Lseek;
Offset = RtlConvertLongToLargeInteger(args->Offset);
NewByteOffset = Offset;
if (SEEK_CUR != args->Whence && SEEK_SET != args->Whence && SEEK_END != args->Whence) {
m->Error = EINVAL; return TRUE; }
// Check for overflow. POSIX limited to arithmetic data type for off_t
if (NewByteOffset.HighPart != 0 || (off_t)NewByteOffset.LowPart < 0) { m->Error = EINVAL; }
return TRUE; }
BOOLEAN NullStat( IN PIONODE IoNode, IN HANDLE FileHandle, OUT struct stat *StatBuf, OUT NTSTATUS *pStatus ) /*++
Routine Description:
This procedure implements stat when the device being read is the null device.
Arguments:
IoNode - supplies a pointer to the ionode of the file for which stat is requested. NULL if no active Ionode entry.
FileHandle - supplies the Nt file handle of the file .
StatBuf - Supplies the address of the statbuf portion of the message associated with the request.
Return Value:
TRUE.
--*/ { IO_STATUS_BLOCK Iosb;
//
// First get the static information on the file from the ionode if
// there is one (i.e. if the file currently open.
// Open() sets the fields in the ionode.
//
if (NULL != IoNode) { StatBuf->st_mode = IoNode->Mode; StatBuf->st_ino = (ino_t)IoNode->FileSerialNumber; StatBuf->st_dev = IoNode->DeviceSerialNumber;
StatBuf->st_atime = IoNode->AccessDataTime; StatBuf->st_ctime = IoNode->ModifyIoNodeTime; StatBuf->st_mtime = IoNode->ModifyDataTime; }
StatBuf->st_uid = 0; StatBuf->st_gid = 0; StatBuf->st_size = 0; StatBuf->st_nlink = 1;
return TRUE; }
|