msvcrt: Forward ANSI open functions to their Unicode counterparts instead of the other way around. Implement _wfreopen.

This commit is contained in:
Hans Leidekker 2009-01-19 11:41:15 +01:00 committed by Alexandre Julliard
parent b33792235e
commit d2a383b658
2 changed files with 156 additions and 88 deletions

View File

@ -978,9 +978,9 @@ void CDECL MSVCRT_rewind(MSVCRT_FILE* file)
MSVCRT_clearerr(file);
}
static int msvcrt_get_flags(const char* mode, int *open_flags, int* stream_flags)
static int msvcrt_get_flags(const MSVCRT_wchar_t* mode, int *open_flags, int* stream_flags)
{
int plus = strchr(mode, '+') != NULL;
int plus = strchrW(mode, '+') != NULL;
switch(*mode++)
{
@ -1023,6 +1023,22 @@ static int msvcrt_get_flags(const char* mode, int *open_flags, int* stream_flags
* _fdopen (MSVCRT.@)
*/
MSVCRT_FILE* CDECL MSVCRT__fdopen(int fd, const char *mode)
{
MSVCRT_FILE *ret;
MSVCRT_wchar_t *modeW = NULL;
if (mode && !(modeW = msvcrt_wstrdupa(mode))) return NULL;
ret = MSVCRT__wfdopen(fd, modeW);
MSVCRT_free(modeW);
return ret;
}
/*********************************************************************
* _wfdopen (MSVCRT.@)
*/
MSVCRT_FILE* CDECL MSVCRT__wfdopen(int fd, const MSVCRT_wchar_t *mode)
{
int open_flags, stream_flags;
MSVCRT_FILE* file;
@ -1037,45 +1053,12 @@ MSVCRT_FILE* CDECL MSVCRT__fdopen(int fd, const char *mode)
file->_flag = 0;
file = NULL;
}
else TRACE(":fd (%d) mode (%s) FILE* (%p)\n",fd,mode,file);
else TRACE(":fd (%d) mode (%s) FILE* (%p)\n", fd, debugstr_w(mode), file);
UNLOCK_FILES();
return file;
}
/*********************************************************************
* _wfdopen (MSVCRT.@)
*/
MSVCRT_FILE* CDECL MSVCRT__wfdopen(int fd, const MSVCRT_wchar_t *mode)
{
unsigned mlen = strlenW(mode);
char *modea = MSVCRT_calloc(mlen + 1, 1);
MSVCRT_FILE* file = NULL;
int open_flags, stream_flags;
if (modea &&
WideCharToMultiByte(CP_ACP,0,mode,mlen,modea,mlen,NULL,NULL))
{
if (msvcrt_get_flags(modea, &open_flags, &stream_flags) == -1) return NULL;
LOCK_FILES();
if (!(file = msvcrt_alloc_fp()))
file = NULL;
else if (msvcrt_init_fp(file, fd, stream_flags) == -1)
{
file->_flag = 0;
file = NULL;
}
else
{
if (file)
MSVCRT_rewind(file); /* FIXME: is this needed ??? */
TRACE(":fd (%d) mode (%s) FILE* (%p)\n",fd,debugstr_w(mode),file);
}
UNLOCK_FILES();
}
return file;
}
/*********************************************************************
* _filelength (MSVCRT.@)
*/
@ -1514,26 +1497,97 @@ int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... )
*/
int CDECL MSVCRT__wsopen( const MSVCRT_wchar_t* path, int oflags, int shflags, ... )
{
const unsigned int len = strlenW(path);
char *patha = MSVCRT_calloc(len + 1,1);
__ms_va_list ap;
int pmode;
DWORD access = 0, creation = 0, attrib;
DWORD sharing;
int wxflag = 0, fd;
HANDLE hand;
SECURITY_ATTRIBUTES sa;
TRACE(":file (%s) oflags: 0x%04x shflags: 0x%04x\n",
debugstr_w(path), oflags, shflags);
wxflag = split_oflags(oflags);
switch (oflags & (MSVCRT__O_RDONLY | MSVCRT__O_WRONLY | MSVCRT__O_RDWR))
{
case MSVCRT__O_RDONLY: access |= GENERIC_READ; break;
case MSVCRT__O_WRONLY: access |= GENERIC_WRITE; break;
case MSVCRT__O_RDWR: access |= GENERIC_WRITE | GENERIC_READ; break;
}
if (oflags & MSVCRT__O_CREAT)
{
__ms_va_start(ap, shflags);
pmode = va_arg(ap, int);
__ms_va_end(ap);
if (patha && WideCharToMultiByte(CP_ACP,0,path,len,patha,len,NULL,NULL))
if(pmode & ~(MSVCRT__S_IREAD | MSVCRT__S_IWRITE))
FIXME(": pmode 0x%04x ignored\n", pmode);
else
WARN(": pmode 0x%04x ignored\n", pmode);
if (oflags & MSVCRT__O_EXCL)
creation = CREATE_NEW;
else if (oflags & MSVCRT__O_TRUNC)
creation = CREATE_ALWAYS;
else
creation = OPEN_ALWAYS;
}
else /* no MSVCRT__O_CREAT */
{
int retval = MSVCRT__sopen(patha,oflags,shflags,pmode);
MSVCRT_free(patha);
return retval;
if (oflags & MSVCRT__O_TRUNC)
creation = TRUNCATE_EXISTING;
else
creation = OPEN_EXISTING;
}
switch( shflags )
{
case MSVCRT__SH_DENYRW:
sharing = 0L;
break;
case MSVCRT__SH_DENYWR:
sharing = FILE_SHARE_READ;
break;
case MSVCRT__SH_DENYRD:
sharing = FILE_SHARE_WRITE;
break;
case MSVCRT__SH_DENYNO:
sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
break;
default:
ERR( "Unhandled shflags 0x%x\n", shflags );
return -1;
}
attrib = FILE_ATTRIBUTE_NORMAL;
if (oflags & MSVCRT__O_TEMPORARY)
{
attrib |= FILE_FLAG_DELETE_ON_CLOSE;
access |= DELETE;
sharing |= FILE_SHARE_DELETE;
}
sa.nLength = sizeof( SECURITY_ATTRIBUTES );
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = (oflags & MSVCRT__O_NOINHERIT) ? FALSE : TRUE;
hand = CreateFileW(path, access, sharing, &sa, creation, attrib, 0);
if (hand == INVALID_HANDLE_VALUE) {
WARN(":failed-last error (%d)\n",GetLastError());
msvcrt_set_errno(GetLastError());
return -1;
}
fd = msvcrt_alloc_fd(hand, wxflag);
TRACE(":fd (%d) handle (%p)\n",fd, hand);
return fd;
}
/*********************************************************************
* _open (MSVCRT.@)
*/
@ -1558,24 +1612,18 @@ int CDECL MSVCRT__open( const char *path, int flags, ... )
*/
int CDECL _wopen(const MSVCRT_wchar_t *path,int flags,...)
{
const unsigned int len = strlenW(path);
char *patha = MSVCRT_calloc(len + 1,1);
__ms_va_list ap;
int pmode;
if (flags & MSVCRT__O_CREAT)
{
int pmode;
__ms_va_start(ap, flags);
pmode = va_arg(ap, int);
__ms_va_end(ap);
if (patha && WideCharToMultiByte(CP_ACP,0,path,len,patha,len,NULL,NULL))
{
int retval = MSVCRT__open(patha,flags,pmode);
MSVCRT_free(patha);
return retval;
return MSVCRT__wsopen( path, flags, MSVCRT__SH_DENYNO, pmode );
}
msvcrt_set_errno(GetLastError());
return -1;
else
return MSVCRT__wsopen( path, flags, MSVCRT__SH_DENYNO);
}
/*********************************************************************
@ -2428,26 +2476,26 @@ MSVCRT_wint_t CDECL _fputwchar(MSVCRT_wint_t wc)
}
/*********************************************************************
* _fsopen (MSVCRT.@)
* _wfsopen (MSVCRT.@)
*/
MSVCRT_FILE * CDECL MSVCRT__fsopen(const char *path, const char *mode, int share)
MSVCRT_FILE * CDECL MSVCRT__wfsopen(const MSVCRT_wchar_t *path, const MSVCRT_wchar_t *mode, int share)
{
MSVCRT_FILE* file;
int open_flags, stream_flags, fd;
TRACE("(%s,%s)\n",path,mode);
TRACE("(%s,%s)\n", debugstr_w(path), debugstr_w(mode));
/* map mode string to open() flags. "man fopen" for possibilities. */
if (msvcrt_get_flags(mode, &open_flags, &stream_flags) == -1)
return NULL;
LOCK_FILES();
fd = MSVCRT__sopen(path, open_flags, share, MSVCRT__S_IREAD | MSVCRT__S_IWRITE);
fd = MSVCRT__wsopen(path, open_flags, share, MSVCRT__S_IREAD | MSVCRT__S_IWRITE);
if (fd < 0)
file = NULL;
else if ((file = msvcrt_alloc_fp()) && msvcrt_init_fp(file, fd, stream_flags)
!= -1)
TRACE(":fd (%d) mode (%s) FILE* (%p)\n",fd,mode,file);
TRACE(":fd (%d) mode (%s) FILE* (%p)\n", fd, debugstr_w(mode), file);
else if (file)
{
file->_flag = 0;
@ -2462,28 +2510,25 @@ MSVCRT_FILE * CDECL MSVCRT__fsopen(const char *path, const char *mode, int share
}
/*********************************************************************
* _wfsopen (MSVCRT.@)
* _fsopen (MSVCRT.@)
*/
MSVCRT_FILE * CDECL MSVCRT__wfsopen(const MSVCRT_wchar_t *path, const MSVCRT_wchar_t *mode, int share)
MSVCRT_FILE * CDECL MSVCRT__fsopen(const char *path, const char *mode, int share)
{
const unsigned int plen = strlenW(path), mlen = strlenW(mode);
char *patha = MSVCRT_calloc(plen + 1, 1);
char *modea = MSVCRT_calloc(mlen + 1, 1);
MSVCRT_FILE *ret;
MSVCRT_wchar_t *pathW = NULL, *modeW = NULL;
TRACE("(%s,%s)\n",debugstr_w(path),debugstr_w(mode));
if (patha && modea &&
WideCharToMultiByte(CP_ACP,0,path,plen,patha,plen,NULL,NULL) &&
WideCharToMultiByte(CP_ACP,0,mode,mlen,modea,mlen,NULL,NULL))
if (path && !(pathW = msvcrt_wstrdupa(path))) return NULL;
if (mode && !(modeW = msvcrt_wstrdupa(mode)))
{
MSVCRT_FILE *retval = MSVCRT__fsopen(patha,modea,share);
MSVCRT_free(patha);
MSVCRT_free(modea);
return retval;
MSVCRT_free(pathW);
return NULL;
}
msvcrt_set_errno(GetLastError());
return NULL;
ret = MSVCRT__wfsopen(pathW, modeW, share);
MSVCRT_free(pathW);
MSVCRT_free(modeW);
return ret;
}
/*********************************************************************
@ -2635,14 +2680,14 @@ MSVCRT_size_t CDECL MSVCRT_fread(void *ptr, MSVCRT_size_t size, MSVCRT_size_t nm
}
/*********************************************************************
* freopen (MSVCRT.@)
* _wfreopen (MSVCRT.@)
*
*/
MSVCRT_FILE* CDECL MSVCRT_freopen(const char *path, const char *mode,MSVCRT_FILE* file)
MSVCRT_FILE* CDECL _wfreopen(const MSVCRT_wchar_t *path, const MSVCRT_wchar_t *mode, MSVCRT_FILE* file)
{
int open_flags, stream_flags, fd;
TRACE(":path (%p) mode (%s) file (%p) fd (%d)\n",path,mode,file,file->_file);
TRACE(":path (%p) mode (%s) file (%p) fd (%d)\n", debugstr_w(path), debugstr_w(mode), file, file->_file);
LOCK_FILES();
if (!file || ((fd = file->_file) < 0) || fd > MSVCRT_fdend)
@ -2655,7 +2700,7 @@ MSVCRT_FILE* CDECL MSVCRT_freopen(const char *path, const char *mode,MSVCRT_FILE
file = NULL;
else
{
fd = MSVCRT__open(path, open_flags, MSVCRT__S_IREAD | MSVCRT__S_IWRITE);
fd = _wopen(path, open_flags, MSVCRT__S_IREAD | MSVCRT__S_IWRITE);
if (fd < 0)
file = NULL;
else if (msvcrt_init_fp(file, fd, stream_flags) == -1)
@ -2671,6 +2716,29 @@ MSVCRT_FILE* CDECL MSVCRT_freopen(const char *path, const char *mode,MSVCRT_FILE
return file;
}
/*********************************************************************
* freopen (MSVCRT.@)
*
*/
MSVCRT_FILE* CDECL MSVCRT_freopen(const char *path, const char *mode, MSVCRT_FILE* file)
{
MSVCRT_FILE *ret;
MSVCRT_wchar_t *pathW = NULL, *modeW = NULL;
if (path && !(pathW = msvcrt_wstrdupa(path))) return NULL;
if (mode && !(modeW = msvcrt_wstrdupa(mode)))
{
MSVCRT_free(pathW);
return NULL;
}
ret = _wfreopen(pathW, modeW, file);
MSVCRT_free(pathW);
MSVCRT_free(modeW);
return ret;
}
/*********************************************************************
* fsetpos (MSVCRT.@)
*/

View File

@ -543,7 +543,7 @@
@ cdecl _wfindnext(long ptr) MSVCRT__wfindnext
@ cdecl _wfindnexti64(long ptr) MSVCRT__wfindnexti64
@ cdecl _wfopen(wstr wstr) MSVCRT__wfopen
@ stub _wfreopen #(wstr wstr ptr) MSVCRT__wfreopen
@ cdecl _wfreopen(wstr wstr ptr)
@ cdecl _wfsopen(wstr wstr long) MSVCRT__wfsopen
@ cdecl _wfullpath(ptr wstr long)
@ cdecl _wgetcwd(wstr long)