windows-nt/Source/XPSP1/NT/shell/osshell/control/t1instal/winio.c
2020-09-26 16:20:57 +08:00

298 lines
7 KiB
C

/***
**
** Module: FileIO
**
** Description:
** This is a module of the T1 to TT font converter. The module
** is the interface towards all low level I/O functions that are
** are available on the current platform.
** This version of the module is written specifically for Win32,
** and is based on "memory mapped files".
**
** Author: Michael Jansson
**
** Created: 5/26/93
**
***/
/**** INCLUDES */
/* General types and definitions. */
#include <windows.h>
#undef IN
/* Special types and definitions. */
#include "t1instal.h"
#include "types.h"
#include "safemem.h"
#include "fileio.h"
/* Module dependent types and prototypes. */
/*-none-*/
/***** LOCAL TYPES */
struct ioFile {
HANDLE file;
HANDLE mapping;
LPVOID data;
UBYTE *ptr;
UBYTE *max;
DWORD length;
boolean output;
};
/***** CONSTANTS */
#define FILESIZE 65535L
#define BUFSIZE 8L * 1024L
#define BADSET_ERROR 0xffffffff
/***** MACROS */
#ifndef FASTCALL
# ifdef MSDOS
# define FASTCALL __fastcall
# else
# define FASTCALL
# endif
#endif
#define TRY if (1)
#define EXCEPT(v) else
/***** STATIC FUNCTIONS */
/*-none-*/
/***** FUNCTIONS */
struct ioFile *io_OpenFile(const char *name, const int mode)
{
DWORD access;
DWORD create;
DWORD attr;
DWORD prot;
DWORD lowsize;
DWORD mapaccess;
SECURITY_ATTRIBUTES sa;
struct ioFile *file;
if ((file = Malloc(sizeof(struct ioFile)))!=NULL) {
file->file = NULL;
file->mapping = NULL;
file->data = NULL;
file->ptr = NULL;
file->length = 0;
if (mode == READONLY) {
access = GENERIC_READ;
create = OPEN_EXISTING;
attr = FILE_ATTRIBUTE_NORMAL /*FILE_FLAG_SEQUENTIAL_SCAN*/;
prot = PAGE_READONLY;
lowsize = 0;
mapaccess = FILE_MAP_READ;
file->output = FALSE;
} else {
access = GENERIC_READ | GENERIC_WRITE;
create = CREATE_ALWAYS;
attr = FILE_ATTRIBUTE_NORMAL;
prot = PAGE_READWRITE;
lowsize = FILESIZE;
mapaccess = FILE_MAP_ALL_ACCESS;
file->output = TRUE;
}
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = FALSE;
if ((file->file = CreateFile(name, access, 0, &sa, create,
attr, NULL))==INVALID_HANDLE_VALUE) {
(void)io_CloseFile(file);
SetLastError(0);
file = NULL;
} else {
if ((file->mapping = CreateFileMapping(file->file, NULL,
prot, 0, lowsize,
NULL))==INVALID_HANDLE_VALUE) {
(void)io_CloseFile(file);
file = NULL;
} else {
if ((file->data = MapViewOfFile(file->mapping,
mapaccess, 0, 0, 0))==NULL) {
(void)io_CloseFile(file);
file = NULL;
} else {
file->ptr = (UBYTE *)file->data;
file->max = file->ptr;
file->max = file->max + GetFileSize(file->file, NULL);
}
}
}
}
return file;
}
errcode io_CloseFile(struct ioFile *file)
{
errcode status = SUCCESS;
if (file==NULL || file->data==NULL || file->file==0)
status = FAILURE;
if (file) {
if ((DWORD)(file->ptr - (UBYTE *)file->data)>file->length)
file->length = (long)(file->ptr - (UBYTE *)file->data);
if (file->data){
UnmapViewOfFile(file->data);
file->data = NULL;
}
if (file->mapping) {
CloseHandle(file->mapping);
file->mapping = NULL;
}
if (file->file) {
if (file->output) {
if (SetFilePointer(file->file,
file->length,
0,
FILE_BEGIN)==BADSET_ERROR)
status = FAILURE;
else if (SetEndOfFile(file->file)==FALSE)
status = FAILURE;
}
CloseHandle(file->file);
file->file = NULL;
}
Free(file);
}
return status;
}
USHORT FASTCALL io_ReadOneByte(struct ioFile *file)
{
USHORT byte;
if (file->ptr<=file->max) {
byte = (USHORT)*(file->ptr++);
} else {
SetLastError(ERROR_READ_FAULT);
byte = ERROR_READ_FAULT;
}
return byte;
}
USHORT FASTCALL io_WriteBytes(const UBYTE *buf,
USHORT len,
struct ioFile *file)
{
if ((file->ptr+len)<=file->max) {
memcpy(file->ptr, buf, len);
file->ptr = file->ptr + len;
} else if (file->data) {
long pos = io_FileTell(file);
long size = MAX(GetFileSize(file->file, NULL),
MAX(file->length, (ULONG)(file->ptr -
(UBYTE *)file->data)));
/* Get rid of the old file mapping. */
UnmapViewOfFile(file->data);
file->data = NULL;
CloseHandle(file->mapping);
file->mapping = NULL;
/* Get a new file mapping. */
if ((file->mapping = CreateFileMapping(file->file, NULL,
PAGE_READWRITE, 0,
size + BUFSIZE,
NULL))==INVALID_HANDLE_VALUE) {
SetLastError(ERROR_WRITE_FAULT);
file->ptr = file->max;
len = 0;
} else if ((file->data = MapViewOfFile(file->mapping,
FILE_MAP_ALL_ACCESS,
0, 0, 0))==NULL) {
SetLastError(ERROR_WRITE_FAULT);
file->ptr = file->max;
len = 0;
} else {
file->ptr = (UBYTE *)file->data;
file->max = (UBYTE *)file->data;
file->max = file->max + size + BUFSIZE;
io_FileSeek(file, pos);
io_WriteBytes(buf, len, file);
}
}
return len;
}
USHORT FASTCALL io_ReadBytes(UBYTE *buf, USHORT len, struct ioFile *file)
{
if ((file->ptr+len)<=file->max) {
memcpy(buf, file->ptr, len);
file->ptr = file->ptr + len;
} else {
SetLastError(ERROR_READ_FAULT);
len = 0;
}
return len;
}
boolean io_FileError(struct ioFile *file)
{
return (boolean)GetLastError();
}
long FASTCALL io_FileTell(struct ioFile *file)
{
return (long)(file->ptr - (UBYTE *)file->data);
}
long FASTCALL io_FileSeek(struct ioFile *file, long where)
{
DWORD oldpos = (DWORD)(file->ptr - (UBYTE *)file->data);
/* Keep track of the length of the file. */
if (oldpos>file->length)
file->length = oldpos;
/* Fail if file is not mapped, or if we are jumping out of bounds. */
if (file->data && (where>=0) &&
((UBYTE *)file->data+where) <= file->max) {
file->ptr = (UBYTE *)file->data;
file->ptr = file->ptr + where;
} else {
SetLastError(ERROR_SEEK);
}
return (long)oldpos;
}
/***
** Function: FileSeek
**
** Description:
***/
void FASTCALL io_RemoveFile(const char *name)
{
DeleteFile(name);
}