Sun Nov 20 18:30:06 1994 Alexandre Julliard (julliard@lamisun.epfl.ch) * [controls/scroll.c] [include/scroll.h] Rewritten most of scroll-bar code for better Windows look & feel. Implemented EnableScrollBar(). Preliminary keyboard support. * [objects/bitblt.c] Fixed BadMatch error for BitBlt() and StretchBlt() when reading bits from outside the visible region. * [objects/oembitmap.c] [include/bitmaps/obm_*] Use XPM symbolic colors to load bitmaps. This allows the colors of the bitmaps to depend on the system colors. * [tools/make_debug] Made the make_debug script more robust. * [windows/dialog.c] Fixed CheckRadioButton(). * [windows/nonclient.c] A few changes to scroll-bar drawing and tracking. * [windows/winpos.c] Renamed NextWindowFromPoint() to WINPOS_NextWindowFromPoint() to avoid confusion, and optimized it somewhat. Nov 19, 94 Martin Ayotte (wine@trgcorp.mksinfo.qc.ca) * [misc/audio.c] * [misc/mcianim.c] more coding but nothing spectacular. * [misc/mmaux.c] some coding to access '/dev/mixer'. * [misc/midi.c] some coding to read .MID files, but it's not playing yet. Sun Nov 13 19:31:03 1994 James Youngman (mbcstjy@afs.man.ac.uk) * [objects/dib.c] Reimplemented DIB_SetImageBits_RLE8() so that it would cope with bitmaps which don't end 0x00, 0x02 (previously it blew up). This includes some bitmaps output by Paint Shop Pro. Implementation is possibly now too lax. Please see the notes on the function about why. * [controls/desktop.c] The desktop pattern should be painted if the wallpaper doesn't cover the whole screen width OR the whole screen height. Sun Nov 13 00:07:11 MET 1994 Erik Bos <erik@xs4all.nl> * [objects/dib.c] Small bug in DIB_SetImageBits() fixed, bitmaps in 16,24 bpp now work. * [loader/ne_resource.c] [include/resource.h] Some cleanup. Thu Nov 10 20:44:58 1994 Martin von Loewis (martin@cs.csufresno.edu) * [Configure] [rc/sysres.rc] Primitive compile-time support for multiple languages * [rc/sysres_De.rc] New file * [loader/resource.c] LoadBitmap: Recognize end of sysresbm properly * [rc/Imakefile] Rules to compile resources simplified, dependencies changed * [rc/sysresbm.rc] Don't use sysresbm if using XPM * [windows/dialog.c] CreateDialogIndirectParam: Reverse Z-order of controls * [windows/message.c] MSG_TranslateMouseMsg: Fix HTTRANSPARENT handling * [windows/winpos.c] NextWindowFromPoint: New function * [controls/button.c] WM_NCHITTEST: Group Box is HTTRANSPARENT BUTTON_CheckAutoRadioButton: New function BM_SETCHECK: Added call to BUTTON_CheckAutoRadioButton Mon Nov 7 11:20:26 1994 Paul Falstad (pf@zoof.cts.com) * [objects/text.c] Fix hang when using DrawText(..., DT_WORDBREAK) with a word that is too long to break. * [objects/font.c] Don't assume helvetica if there is no font family; let the other font attributes decide what font to use. * [controls/widgets.c] Listboxes and combo boxes need to be notified of double-clicks. * [controls/listbox.c] [include/listbox.h] scrolling to bottom of list box should display last item at the bottom, not at the top. list boxes need to allocate a separate heap for their item data, rather than using the user heap. Otherwise, it's very easy to run out of memory for list box items. removed redundant code in ListBoxAddString(). Implemented simple version of LBS_SORT. Don't put [.] in the list box when using DDL_DIRECTORY. * [controls/combo.c] Combos should pass CBS_SORT onto their list box. * [windows/win.c] If window creation is aborted, remove the window from the linked lists. * [controls/static.c] static controls with SS_ICON were always returning 0 from WM_NCCREATE. Make sure static controls have text to draw before drawing it.
440 lines
12 KiB
C
440 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 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 "prototypes.h"
|
|
#include "regfunc.h"
|
|
#include "windows.h"
|
|
#include "wine.h"
|
|
#include "msdos.h"
|
|
#include "registers.h"
|
|
#include "options.h"
|
|
#include "stddebug.h"
|
|
/* #define DEBUG_FILE /* */
|
|
/* #undef DEBUG_FILE /* */
|
|
#include "debug.h"
|
|
|
|
#define MAX_PATH 255
|
|
|
|
char WindowsDirectory[256], SystemDirectory[256], TempDirectory[256];
|
|
extern char WindowsPath[256];
|
|
|
|
extern char WindowsPath[];
|
|
extern WORD ExtendedError;
|
|
|
|
|
|
char *GetDosFileName(char *unixfilename);
|
|
|
|
/***************************************************************************
|
|
_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 = GetUnixFileName(lpPathName)) == NULL)
|
|
return HFILE_ERROR;
|
|
iReadWrite &= 0x000F;
|
|
handle = open (UnixFileName, iReadWrite);
|
|
|
|
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)
|
|
{
|
|
int handle;
|
|
#ifndef PROCEMU
|
|
struct sigcontext_struct ccontext;
|
|
/* To make macros like EAX happy */
|
|
struct sigcontext_struct *context=&ccontext;
|
|
#endif
|
|
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 = 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(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(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(GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
|
|
break;
|
|
if (!FindFile(temp,MAX_PATH,lpFileName,NULL,WindowsPath))
|
|
{
|
|
strcpy(filename, 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(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_EXIST)
|
|
return 0;
|
|
|
|
if (action & OF_VERIFY)
|
|
return (verify_time != *((int*)ofs->reserved));
|
|
|
|
|
|
/* Now we are actually going to open the file. According to Microsoft's
|
|
Knowledge Basis, this is done by calling int 21h, ax=3dh. */
|
|
|
|
AX = 0x3d00;
|
|
AL = (AL & 0x0f) | (wStyle & 0x70); /* Handle OF_SHARE_xxx etc. */
|
|
AL = (AL & 0xf0) | (wStyle & 0x03); /* Handle OF_READ etc. */
|
|
DS = segment (ofs->szPathName);
|
|
DX = offset (ofs->szPathName);
|
|
|
|
OpenExistingFile (context);
|
|
|
|
if (EFL & 0x00000001) /* Cflag */
|
|
{
|
|
ofs->nErrCode = AL;
|
|
return -1;
|
|
}
|
|
|
|
return AX;
|
|
}
|
|
|
|
/**************************************************************************
|
|
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 = 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);
|
|
}
|
|
|
|
/***************************************************************************
|
|
_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);
|
|
}
|