Fri Nov 3 20:08:17 1995 Alexandre Julliard <julliard@sunsite.unc.edu> * [configure.in] Attempt to check for -li386 on NetBSD. Please test this. Mon Oct 30 12:40:32 EST 1995 Jim Peterson <jspeter@birch.ee.vt.edu> * [*/*] Eliminated various warnings with either explicit casts or more accurate variable/parameter declarations (e.g. INT instead of short or WORD). Changed macros 'min' and 'max' to 'MIN' and 'MAX', since they're macros. * [controls/edit.c] [windows/defdlg.c] Added '#ifdef SUPERFLUOUS_FUNCTIONS' wrappers around function definition of EDIT_KeyVScrollDoc, EDIT_TextLineNumber, and DEFDLG_FindDefButton to avoid warnings. * [controls/button.c] [controls/scroll.c] [windows/defwnd.c] [windows/message.c] [windows/nonclient.c] Converted MAKEPOINT macro call to manual conversion. * [include/windows.h] For WINELIB32, structures POINT, SIZE, and RECT have LONG members instead of INT. This also invalidates the macro MAKEPOINT(), which is not supported in Win32. Also defined the POINTS structure (SHORT members) and the MAKEPOINTS macro. * [misc/commdlg.c] Changed a lot of 'strcpy' calls to 'strncpy' calls. I'm desperate to find this memory bug, and this should be done anyway. * [controls/edit.c] Well, the alteration mentioned above didn't do it, but #ifdef'ing out a few lines in EDIT_ClearText did. This leads to bugs, but for now, it's better than bizzare memory troubles. * [toolkit/miscstubs.c] Removed warning messages in GLOBAL_CreateBlock(), GLOBAL_FreeBlock(), and RELAY32_GetEntryPoint(). These are the most popular warnings, and their current implementation seems fine. Sat Oct 28 09:39:18 1995 Jochen Karrer <cip307@wpax01.Physik.Uni-Wuerzburg.DE> * [objects/cursoricon.c] Fix for "broken" X servers that invert masked cursor colors. Fri Oct 27 19:27:21 1995 Alex Korobka <alex@phm6.pharm.sunysb.edu> * [windows/dialog.c] [windows/nonclient.c] Remove unnecessary items from the system menu. Thu Oct 26 05:03:03 MET 1995 Philippe De Muyter <phdm@info.ucl.ac.be> * [objects/color.c] [objects/palette.c] Make GetNearestColor return a RGB value instead of a pixel value. Wed Oct 25 23:33:39 1995 Martin von Loewis <loewis@informatik.hu-berlin.de> * [controls/desktop.c][controls/menu.c][include/menu.h] Changed WORD parameters to UINT parameters. * [include/wintypes.h] Made UINT 32bit for WINELIB. * [loader/main.c] Disabled RELAY32_Init and MODULE_Init for WINELIB. * [misc/main.c] Assume CPU386 for WINELIB. * [rc/winerc] add_popup: set MF_POPUP flag on menu item. * [toolkit/Makefile.in][toolkit/hello3.c][toolkit/hello3res.c] Add resource demo hello3 for WINELIB. New file README.resources. * [toolkit/miscstubs.c] Add a case for 17. Tue Oct 17 15:13:10 IST 1995 Itai Nahshon <nahshon@vnet.ibm.com> * [loader/module.c] Do not append .exe if the file name already has an extension. * [misc/profile.c] Avoid creating a file with a junk name if a .ini file does not exist. * [if1632/gdi.spec] [if1632/user.spec] [if1632/dummy.c] Added a lot of dummy stubs for Windows Hebrew version. Tue Oct 17 01:03:24 1995 William Magro <wmagro@tc.cornell.edu> * [controls/button.c] Fix for buttons with no label. * [controls/combo.c][controls/listbox.c] Fixes for scrollbar positioning. Now disappears correctly for short lists. * [controls/edit.c] Handle memory allocation differently when building as library. * [controls/static] Don't destroy old icon before drawing new icon. (Fixes landscape/ portrait toggle icon in print dialog.) * [if1632/gdi.spec] New functions SetMetaFileBits and GetMetaFileBits * [include/sysmetrics.h] [windows/sysmetrics.c] Add support for GetSystemMetrics(SM_CMETRICS) == SM_CMETRICS * [include/windows.h] META_EXTTEXTOUT, not META_SETTEXTOUT define GetCurrentTime as GetTickCount (for wine library) * [loader/main.c] Don't initialize built-in modules in wine library * [memory/local.c] LocalReAlloc was defined incorrectly. Swap flags and size arguments. * [misc/main.c] Always report CPUTYPE=4 to wine library. * [objects/dib.c] RLE8 images were missing top line when decompressed. * [objects/metafile.c] SetMetaFileBits and GetMetaFileBits implemented. Works when called from winhelp. More testing needed. Various memory leaks plugged. Various other bug fixes. New metafile operations added in PlayMetaFileRecord: CreatePalette, SetTextAlign, SelectPalette, SetMapperFlags, RealizePalette, ExtTextOut, Escape. Testing needed. * [toolkit/heap.c] LocalUnLock changed to LocalUnlock Sun Oct 15 21:55:33 1995 Anand Kumria <akumria@ozemail.com.au> * [misc/winsock.c] Return the correct error number, for host lookup operations. Also, correct the problem with send_message. Fri Oct 13 19:04:35 1995 Morten Welinder <terra@diku.dk> * [Makefile.in] Using nm's built-in sorting. * [*/*.c] Use xmalloc for malloc and xrealloc for realloc in all ungarded cases. * [debugger/dbg.y] Handle C-like expressions. Clean-up. * [debugger/debug.l] Lots of new tokens for expressions. * [debugger/info.c] Implement "list" command for disassembling. * [misc/ole2nls.c] Implement more Danish stuff. Fri Oct 6 10:39:39 1995 Ram'on Garc'ia <ramon@ie3.clubs.etsit.upm.es> * [loader/module.c] Updated self-loading modules to support for new 32 bit stack frames.
465 lines
13 KiB
C
465 lines
13 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;
|
|
int mode = 0;
|
|
|
|
dprintf_file(stddeb, "_lopen: open('%s', %X);\n", lpPathName, iReadWrite);
|
|
if ((UnixFileName = DOS_GetUnixFileName(lpPathName)) == NULL)
|
|
return HFILE_ERROR;
|
|
switch(iReadWrite & 3)
|
|
{
|
|
case OF_READ: mode = O_RDONLY; break;
|
|
case OF_WRITE: mode = O_WRONLY; break;
|
|
case OF_READWRITE: mode = O_RDWR; break;
|
|
}
|
|
handle = open( UnixFileName, mode );
|
|
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 = %p, length = %d\n",
|
|
hFile, lpBuffer, wBytes);
|
|
|
|
result = (wBytes == 0) ? 0 : read (hFile, lpBuffer, wBytes);
|
|
|
|
if (result == -1)
|
|
return HFILE_ERROR;
|
|
else
|
|
return result;
|
|
}
|
|
|
|
/****************************************************************************
|
|
_lwrite
|
|
****************************************************************************/
|
|
INT _lwrite (INT hFile, LPCSTR lpBuffer, WORD wBytes)
|
|
{
|
|
int result;
|
|
|
|
dprintf_file(stddeb, "_lwrite: handle %d, buffer = %p, length = %d\n",
|
|
hFile, lpBuffer, wBytes);
|
|
|
|
if(wBytes == 0) { /* Expand the file size if necessary */
|
|
char toWrite = 0;
|
|
off_t prev, end;
|
|
|
|
prev = lseek(hFile, 0, SEEK_CUR);
|
|
if(prev == -1) return HFILE_ERROR;
|
|
end = lseek(hFile, 0, SEEK_END);
|
|
if(end == -1) return HFILE_ERROR;
|
|
if(prev > end) {
|
|
lseek(hFile, prev-1, SEEK_SET);
|
|
result = write(hFile, &toWrite, 1) - 1;
|
|
if(result == -2) ++result;
|
|
}
|
|
else {
|
|
lseek(hFile, prev, SEEK_SET);
|
|
result = 0;
|
|
}
|
|
}
|
|
else 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 (hFile == 0 || hFile == 1 || hFile == 2) {
|
|
fprintf( stderr, "Program attempted to close stdin, stdout or stderr!\n" );
|
|
return 0;
|
|
}
|
|
if (close (hFile))
|
|
return HFILE_ERROR;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
/**************************************************************************
|
|
OpenFile
|
|
**************************************************************************/
|
|
INT OpenFile (LPCSTR lpFileName, LPOFSTRUCT ofs, UINT wStyle)
|
|
{
|
|
char filename[MAX_PATH+1];
|
|
int action;
|
|
struct stat s;
|
|
struct tm *now;
|
|
int res, handle;
|
|
int verify_time = 0;
|
|
|
|
dprintf_file(stddeb,"Openfile(%s,<struct>,%d)\n",lpFileName,wStyle);
|
|
|
|
action = wStyle & 0xff00;
|
|
|
|
/* OF_CREATE is completly different from all other options, so
|
|
handle it first */
|
|
|
|
if (action & OF_CREATE)
|
|
{
|
|
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, 0666);
|
|
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))
|
|
{
|
|
char temp[MAX_PATH + 1];
|
|
|
|
if(index(lpFileName,'\\') || index(lpFileName,'/') ||
|
|
index(lpFileName,':'))
|
|
{
|
|
strcpy (filename,lpFileName);
|
|
goto found;
|
|
}
|
|
/* Try current directory */
|
|
if (DOS_FindFile(temp, MAX_PATH, lpFileName, NULL, ".")) {
|
|
strcpy(filename, DOS_GetDosFileName(temp));
|
|
goto found;
|
|
}
|
|
|
|
/* Try Windows directory */
|
|
GetWindowsDirectory(filename, MAX_PATH);
|
|
if (DOS_FindFile(temp, MAX_PATH, lpFileName, NULL, filename)) {
|
|
strcpy(filename, DOS_GetDosFileName(temp));
|
|
goto found;
|
|
}
|
|
|
|
/* Try Windows system directory */
|
|
GetSystemDirectory(filename, MAX_PATH);
|
|
if (DOS_FindFile(temp, MAX_PATH, lpFileName, NULL, filename)) {
|
|
strcpy(filename, DOS_GetDosFileName(temp));
|
|
goto found;
|
|
}
|
|
|
|
/* Try the path of the current executable */
|
|
if (GetCurrentTask())
|
|
{
|
|
char *p;
|
|
GetModuleFileName( GetCurrentTask(), filename, MAX_PATH );
|
|
if ((p = strrchr( filename, '\\' )))
|
|
{
|
|
p[1] = '\0';
|
|
if (DOS_FindFile(temp, MAX_PATH, lpFileName, NULL, filename)) {
|
|
strcpy(filename, DOS_GetDosFileName(temp));
|
|
goto found;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Try all directories in path */
|
|
|
|
if (DOS_FindFile(temp,MAX_PATH,lpFileName,NULL,WindowsPath))
|
|
{
|
|
strcpy(filename, DOS_GetDosFileName(temp));
|
|
goto found;
|
|
}
|
|
/* ??? shouldn't we give an error here? */
|
|
strcpy (filename, lpFileName);
|
|
|
|
found:
|
|
|
|
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 ((handle = _lopen( ofs->szPathName, wStyle )) == -1)
|
|
{
|
|
ofs->nErrCode = 2; /* not found */
|
|
return -1;
|
|
}
|
|
if (action & OF_EXIST) close(handle);
|
|
return handle;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
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_RDWR, 0666);
|
|
|
|
if (handle == -1)
|
|
return HFILE_ERROR;
|
|
else
|
|
return handle;
|
|
}
|
|
|
|
/***************************************************************************
|
|
GetDriveType
|
|
***************************************************************************/
|
|
WORD GetDriveType(INT drive)
|
|
{
|
|
|
|
dprintf_file(stddeb,"GetDriveType %c:\n",'A'+drive);
|
|
|
|
/* File Damager thinks that only return code 0 is bad enough
|
|
* -Al K
|
|
*/
|
|
|
|
if (!DOS_ValidDrive(drive))
|
|
return DRIVE_CANNOTDETERMINE;
|
|
|
|
if (drive == 0 || drive == 1)
|
|
return DRIVE_REMOVABLE;
|
|
|
|
return DRIVE_FIXED;
|
|
}
|
|
|
|
/***************************************************************************
|
|
GetTempDrive
|
|
***************************************************************************/
|
|
BYTE GetTempDrive(BYTE chDriveLetter)
|
|
{
|
|
dprintf_file(stddeb,"GetTempDrive (%d)\n",chDriveLetter);
|
|
if (TempDirectory[1] == ':') return TempDirectory[0];
|
|
else 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);
|
|
|
|
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);
|
|
|
|
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, LPSTR hpvBuffer, LONG cbBuffer)
|
|
{
|
|
return (cbBuffer == 0) ? 0 : read(hf, hpvBuffer, cbBuffer);
|
|
}
|
|
/***************************************************************************
|
|
_hwrite
|
|
***************************************************************************/
|
|
LONG _hwrite(INT hf, LPCSTR hpvBuffer, LONG cbBuffer)
|
|
{
|
|
return (cbBuffer == 0) ? 0 : write(hf, hpvBuffer, cbBuffer);
|
|
}
|