/************************************************************************ * 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 #include #include #include #include #include #include #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 (LPSTR lpFileName, LPOFSTRUCT ofs, WORD 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,,%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 (action & OF_EXIST) return 0; if ((handle = _lopen( ofs->szPathName, wStyle )) == -1) { ofs->nErrCode = 2; /* not found */ return -1; } 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 %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); }