wine/misc/file.c
Alexandre Julliard fa68b75bad Release 950403
Sun Apr  2 18:31:12 1995  Alexandre Julliard  (julliard@sunsite.unc.edu)

	* [Configure] [if1632/Imakefile]
	Removed new build and short names options.

	* [if1632/*.c] [tools/build.c]
	Implemented compiled call-back functions for better performance;
	all the relay code is now done in assembly code generated by the
	build program.
	Relay code is no longer dependent on being loaded below 64K.

	* [loader/resource.c]
	Fixed memory leak in LoadString(). A fix will also be needed for
	other resources.

	* [memory/global.c]
	Implemented global heap arenas, so we can store informations about
	global blocks, like lock counts or owner handle.
	Implemented FarGetOwner() and FarSetOwner().
	Implemented global heap TOOLHELP functions.

	* [memory/selector.c]
	Bug fix: it was not possible to re-use a free selector.

Sun Apr 2 01:34:52 1995 Constantine Sapuntzakis  (csapuntz@mit.edu)

	*  [controls/listbox.c]
	Major work on listbox code
         - Many bugs fixed (still many bugs)
         - More messages supported
         - Code simplified

Fri Mar 31 03:27:16 EST 1995 William Magro (wmagro@tc.cornell.edu)

	* [controls/edit.c]
	Lots of bug fixes related to diappearing text, lost carets,
	highlighting, segmentation faults, occurance of random
	characters, insertion of characters over selection, misplaced
	caret location, display corruption, end of line behavior, etc.

	* [controls/widgets.c]
	EDIT class doesn't want to use CS_PARENTDC flag.

Thu Mar 30 20:58:25 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
        
	* [loader/selector.c]
	  FixupFunctionPrologs() should also handle multiple data modules.
	  (this bug only became visible because MakeProcInstance() was fixed
	  in 950319)
	
	* [misc/dosfs.c]
	  Simplified DOS_SimplifyPath.
	  Small fix to DOS_opendir to reuse an entry if an open directory
	  is opened again, to prevent "too many open directories" messages.

Thu Mar 30 12:05:05 1995 Martin von Loewis  <loewis@informatik.hu-berlin.de>

	* [if1632/compobj.spec][include/compobj.h][misc/compobj.c]
	CoDisconnectObject: new stub function

	* [include/msdos.h]
	fix DOSVERSION

	* [loader/ne_image.c]
	NE_FixupSegment: Be more generous on additive fixups

	* [if1632/user.spec][misc/network.c]
	Add more WNet* stubs

Wed Mar 29 11:47:22 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>

        * [controls/listbox.c]
	  DlgDirList(): send segptr instead of linear pointer 
	  in message to static control
	* [controls/menu.c]
	  Tried to implement ownerdrawn menuitems. Doesn't work.
	* [if1632/gdi.spec] [include/windows.h] [objects/font.c]
	  Provide a stub for GetRasterizerCaps()
	* [loader/selector.c]
	  Pass end address instead of length to LocalInit() in 
	  CreateSelectors()
	* [memory/local.c]
	  LocalInit(): If there's already a local heap in the segment, do
	  nothing and return TRUE
	* [objects/linedda.c]
	  Replaced buggy LineDDA() with a Bresenham algorithm. Should work
	  now.
	* [windows/cursor.c]
	  LoadCursor()/CreateCursor(): Cleaned up the mess. Needs some
	  more work still.

Tue Mar 21 17:54:43 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>

        * [if1632/relay.c] [if1632/callback.c] [include/dlls.h]
	  [if1632/winprocs.spec] [if1632/winprocs.c] [include/winprocs.h]
	  [controls/widgets.c] [misc/shell.c] [misc/commdlg.c]
	  [windows/nonclient.c] [misc/message.c]
	  Added a new builtin DLL that provides 16 bit entry points for all
	  the Def*Procs (DefDlgProc, ButtonProc etc.). OWL programs work
	  again.
	* [misc/shell.c]
	  RegOpenKey()/RegCreateKey() bugs fixed.
        * [loader/ne_image.c]
	  Skipping the initialization of a DLL when CS == 0 was broken.
1995-04-03 16:55:37 +00:00

451 lines
12 KiB
C

/************************************************************************
* FILE.C Copyright (C) 1993 John Burton
*
* File I/O routines for the Linux Wine Project.
*
* WARNING : Many options of OpenFile are not yet implemeted.
*
* NOV 93 Erik Bos (erik@xs4all.nl)
* - removed ParseDosFileName, and DosDrive structures.
* - structures dynamically configured at runtime.
* - _lopen modified to use DOS_GetUnixFileName.
* - Existing functions modified to use dosfs functions.
* - Added _llseek, _lcreat, GetDriveType, GetTempDrive,
* GetWindowsDirectory, GetSystemDirectory, GetTempFileName.
*
************************************************************************/
#include <stdio.h>
#include <fcntl.h>
#include <limits.h>
#include <unistd.h>
#include <time.h>
#include <sys/stat.h>
#include <string.h>
#include "dos_fs.h"
#include "windows.h"
#include "msdos.h"
#include "options.h"
#include "stddebug.h"
#include "debug.h"
#define MAX_PATH 255
char WindowsDirectory[256], SystemDirectory[256], TempDirectory[256];
/***************************************************************************
_lopen
Emulate the _lopen windows call
***************************************************************************/
INT _lopen (LPSTR lpPathName, INT iReadWrite)
{
int handle;
char *UnixFileName;
dprintf_file(stddeb, "_lopen: open('%s', %X);\n", lpPathName, iReadWrite);
if ((UnixFileName = DOS_GetUnixFileName(lpPathName)) == NULL)
return HFILE_ERROR;
iReadWrite &= 0x000F;
handle = open (UnixFileName, iReadWrite);
if( ( handle == -1 ) && Options.allowReadOnly )
handle = open( UnixFileName, O_RDONLY );
dprintf_file(stddeb, "_lopen: open: %s (handle %d)\n", UnixFileName, handle);
if (handle == -1)
return HFILE_ERROR;
else
return handle;
}
/***************************************************************************
_lread
***************************************************************************/
INT _lread (INT hFile, LPSTR lpBuffer, WORD wBytes)
{
int result;
dprintf_file(stddeb, "_lread: handle %d, buffer = %ld, length = %d\n",
hFile, (long) lpBuffer, wBytes);
result = read (hFile, lpBuffer, wBytes);
if (result == -1)
return HFILE_ERROR;
else
return result;
}
/****************************************************************************
_lwrite
****************************************************************************/
INT _lwrite (INT hFile, LPSTR lpBuffer, WORD wBytes)
{
int result;
dprintf_file(stddeb, "_lwrite: handle %d, buffer = %ld, length = %d\n",
hFile, (long) lpBuffer, wBytes);
result = write (hFile, lpBuffer, wBytes);
if (result == -1)
return HFILE_ERROR;
else
return result;
}
/***************************************************************************
_lclose
***************************************************************************/
INT _lclose (INT hFile)
{
dprintf_file(stddeb, "_lclose: handle %d\n", hFile);
if (close (hFile))
return HFILE_ERROR;
else
return 0;
}
/**************************************************************************
OpenFile
**************************************************************************/
INT OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle)
{
#ifdef WINELIB
dprintf_file(stdnimp, "OpenFile: not implemented\n");
#else
char filename[MAX_PATH+1];
int action;
struct stat s;
struct tm *now;
int res;
int verify_time;
dprintf_file(stddeb,"Openfile(%s,<struct>,%d) ",lpFileName,wStyle);
action = wStyle & 0xff00;
/* OF_CREATE is completly different from all other options, so
handle it first */
if (action & OF_CREATE)
{
int handle;
char *unixfilename;
if (!(action & OF_REOPEN))
strcpy(ofs->szPathName, lpFileName);
ofs->cBytes = sizeof(OFSTRUCT);
ofs->fFixedDisk = FALSE;
ofs->nErrCode = 0;
*((int*)ofs->reserved) = 0;
if ((unixfilename = DOS_GetUnixFileName (ofs->szPathName)) == NULL)
{
errno_to_doserr();
ofs->nErrCode = ExtendedError;
return -1;
}
handle = open (unixfilename, (wStyle & 0x0003) | O_CREAT, 0x666);
if (handle == -1)
{
errno_to_doserr();
ofs->nErrCode = ExtendedError;
}
return handle;
}
/* If path isn't given, try to find the file. */
if (!(action & OF_REOPEN))
{
if( !( index(lpFileName,'\\') || index(lpFileName,'/') ||
index(lpFileName,':')))
while(1)
{
char temp[MAX_PATH+1];
strcpy (filename, lpFileName);
if ( (!stat(DOS_GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
break;
GetWindowsDirectory (filename,MAX_PATH);
if ((!filename[0])||(filename[strlen(filename)-1]!='\\'))
strcat(filename, "\\");
strcat (filename, lpFileName);
if ( (!stat(DOS_GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
break;
GetSystemDirectory (filename,MAX_PATH);
if ((!filename[0])||(filename[strlen(filename)-1]!='\\'))
strcat(filename, "\\");
strcat (filename, lpFileName);
if ( (!stat(DOS_GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
break;
if (!DOS_FindFile(temp,MAX_PATH,lpFileName,NULL,WindowsPath))
{
strcpy(filename, DOS_GetDosFileName(temp));
break;
}
strcpy (filename, lpFileName);
break;
}
else
strcpy (filename,lpFileName);
ofs->cBytes = sizeof(OFSTRUCT);
ofs->fFixedDisk = FALSE;
strcpy(ofs->szPathName, filename);
ofs->nErrCode = 0;
if (!(action & OF_VERIFY))
*((int*)ofs->reserved) = 0;
}
if (action & OF_PARSE)
return 0;
if (action & OF_DELETE)
return unlink(ofs->szPathName);
/* Now on to getting some information about that file */
if ((res = stat(DOS_GetUnixFileName(ofs->szPathName), &s)))
{
errno_to_doserr();
ofs->nErrCode = ExtendedError;
return -1;
}
now = localtime (&s.st_mtime);
if (action & OF_VERIFY)
verify_time = *((int*)ofs->reserved);
*((WORD*)(&ofs->reserved[2]))=
((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + (now->tm_sec / 2));
*((WORD*)(&ofs->reserved[0]))=
((now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday);
if (action & OF_VERIFY)
return (verify_time != *((int*)ofs->reserved));
if (action & OF_EXIST)
return 0;
/* Now we are actually going to open the file. According to Microsoft's
Knowledge Basis, this is done by calling int 21h, ax=3dh. */
#if 0
AX = 0x3d00;
AL = (AL & 0x0f) | (wStyle & 0x70); /* Handle OF_SHARE_xxx etc. */
AL = (AL & 0xf0) | (wStyle & 0x03); /* Handle OF_READ etc. */
DS = SELECTOROF(ofs->szPathName);
DX = OFFSETOF(ofs->szPathName);
OpenExistingFile (context);
if (EFL & 0x00000001) /* Cflag */
{
ofs->nErrCode = AL;
return -1;
}
return AX;
#endif
/* FIXME: Quick hack to get it to work without calling DOS --AJ */
{
int mode, handle;
switch(wStyle & 3)
{
case 0: mode = O_RDONLY; break;
case 1: mode = O_WRONLY; break;
default: mode = O_RDWR; break;
}
if ((handle = open(DOS_GetUnixFileName(ofs->szPathName), mode)) == -1)
{
ofs->nErrCode = 2; /* not found */
return -1;
}
/* don't bother with locking for now */
return handle;
}
#endif /*WINELIB*/
}
/**************************************************************************
SetHandleCount
Changes the number of file handles available to the application. Since
Linux isn't limited to 20 files, this one's easy. - SL
**************************************************************************/
#if !defined (OPEN_MAX)
/* This one is for the Sun */
#define OPEN_MAX _POSIX_OPEN_MAX
#endif
WORD SetHandleCount (WORD wNumber)
{
dprintf_file(stddeb,"SetHandleCount(%d)\n",wNumber);
return((wNumber<OPEN_MAX) ? wNumber : OPEN_MAX);
}
/***************************************************************************
_llseek
***************************************************************************/
LONG _llseek (INT hFile, LONG lOffset, INT nOrigin)
{
int origin;
dprintf_file(stddeb, "_llseek: handle %d, offset %ld, origin %d\n",
hFile, lOffset, nOrigin);
switch (nOrigin) {
case 1: origin = SEEK_CUR;
break;
case 2: origin = SEEK_END;
break;
default: origin = SEEK_SET;
break;
}
return ( lseek(hFile, lOffset, origin) );
}
/***************************************************************************
_lcreat
***************************************************************************/
INT _lcreat (LPSTR lpszFilename, INT fnAttribute)
{
int handle;
char *UnixFileName;
dprintf_file(stddeb, "_lcreat: filename %s, attributes %d\n",
lpszFilename, fnAttribute);
if ((UnixFileName = DOS_GetUnixFileName(lpszFilename)) == NULL)
return HFILE_ERROR;
handle = open (UnixFileName, O_CREAT | O_TRUNC | O_WRONLY, 426);
if (handle == -1)
return HFILE_ERROR;
else
return handle;
}
/***************************************************************************
GetDriveType
***************************************************************************/
UINT GetDriveType(INT drive)
{
dprintf_file(stddeb,"GetDriveType %c:\n",'A'+drive);
if (!DOS_ValidDrive(drive))
return DRIVE_DOESNOTEXIST;
if (drive == 0 || drive == 1)
return DRIVE_REMOVABLE;
return DRIVE_FIXED;
}
/***************************************************************************
GetTempDrive
***************************************************************************/
BYTE GetTempDrive(BYTE chDriveLetter)
{
dprintf_file(stddeb,"GetTempDrive (%d)\n",chDriveLetter);
return('C');
}
/***************************************************************************
GetWindowsDirectory
***************************************************************************/
UINT GetWindowsDirectory(LPSTR lpszSysPath, UINT cbSysPath)
{
if (cbSysPath < strlen(WindowsDirectory))
*lpszSysPath = 0;
else
strcpy(lpszSysPath, WindowsDirectory);
dprintf_file(stddeb,"GetWindowsDirectory (%s)\n",lpszSysPath);
ChopOffSlash(lpszSysPath);
return(strlen(lpszSysPath));
}
/***************************************************************************
GetSystemDirectory
***************************************************************************/
UINT GetSystemDirectory(LPSTR lpszSysPath, UINT cbSysPath)
{
if (cbSysPath < strlen(SystemDirectory))
*lpszSysPath = 0;
else
strcpy(lpszSysPath, SystemDirectory);
dprintf_file(stddeb,"GetSystemDirectory (%s)\n",lpszSysPath);
ChopOffSlash(lpszSysPath);
return(strlen(lpszSysPath));
}
/***************************************************************************
GetTempFileName
***************************************************************************/
INT GetTempFileName(BYTE bDriveLetter, LPCSTR lpszPrefixString, UINT uUnique, LPSTR lpszTempFileName)
{
int unique;
int handle;
char tempname[256];
if (uUnique == 0)
unique = time(NULL)%99999L;
else
unique = uUnique%99999L;
strcpy(tempname,lpszPrefixString);
tempname[3]='\0';
sprintf(lpszTempFileName,"%s\\%s%d.tmp", TempDirectory, tempname,
unique);
ToDos(lpszTempFileName);
dprintf_file(stddeb,"GetTempFilename: %c %s %d => %s\n",bDriveLetter,
lpszPrefixString,uUnique,lpszTempFileName);
if ((handle = _lcreat (lpszTempFileName, 0x0000)) == -1) {
fprintf(stderr,"GetTempFilename: can't create temp file '%s' !\n", lpszTempFileName);
}
else
close(handle);
return unique;
}
/***************************************************************************
SetErrorMode
***************************************************************************/
WORD SetErrorMode(WORD x)
{
dprintf_file(stdnimp,"wine: SetErrorMode %4x (ignored)\n",x);
return 1;
}
/***************************************************************************
_hread
***************************************************************************/
long _hread(int hf, void FAR *hpvBuffer, long cbBuffer)
{
return read(hf, hpvBuffer, cbBuffer);
}
/***************************************************************************
_hwrite
***************************************************************************/
long _hwrite(int hf, const void FAR *hpvBuffer, long cbBuffer)
{
return write(hf, hpvBuffer, cbBuffer);
}