зеркало из https://github.com/mozilla/pjs.git
Bug 162358: added NSPR file I/O functions that take UTF16 pathnames. The
patch is contributed by Roy Yokoyama <yokoyama@netscape.com>. Modified Files: config/config.mk prio.h prtypes.h _win95.h primpl.h prdir.c prfile.c w95io.c ptio.c
This commit is contained in:
Родитель
9998107b73
Коммит
1dcd628e75
|
@ -127,6 +127,10 @@ ifeq ($(USE_IPV6),1)
|
|||
DEFINES += -D_PR_INET6
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_UNICODE),1)
|
||||
DEFINES += -DMOZ_UNICODE
|
||||
endif
|
||||
|
||||
####################################################################
|
||||
#
|
||||
# Configuration for the release process
|
||||
|
|
|
@ -112,6 +112,16 @@ struct _MDDir {
|
|||
PRUint32 magic; /* for debugging */
|
||||
};
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
struct _MDDirUTF16 {
|
||||
HANDLE d_hdl;
|
||||
WIN32_FIND_DATAW d_entry;
|
||||
PRBool firstEntry; /* Is this the entry returned
|
||||
* by FindFirstFileW()? */
|
||||
PRUint32 magic; /* for debugging */
|
||||
};
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
struct _MDCVar {
|
||||
PRUint32 magic;
|
||||
struct PRThread *waitHead, *waitTail; /* the wait queue: a doubly-
|
||||
|
@ -213,6 +223,15 @@ extern PRInt32 _MD_CloseFile(PRInt32 osfd);
|
|||
#define _MD_TLOCKFILE _PR_MD_TLOCKFILE
|
||||
#define _MD_UNLOCKFILE _PR_MD_UNLOCKFILE
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
/* --- UTF16 IO stuff --- */
|
||||
#define _MD_OPEN_FILE_UTF16 _PR_MD_OPEN_FILE_UTF16
|
||||
#define _MD_OPEN_DIR_UTF16 _PR_MD_OPEN_DIR_UTF16
|
||||
#define _MD_READ_DIR_UTF16 _PR_MD_READ_DIR_UTF16
|
||||
#define _MD_CLOSE_DIR_UTF16 _PR_MD_CLOSE_DIR_UTF16
|
||||
#define _MD_GETFILEINFO64_UTF16 _PR_MD_GETFILEINFO64_UTF16
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
/* --- Socket IO stuff --- */
|
||||
#define _MD_EACCES WSAEACCES
|
||||
#define _MD_EADDRINUSE WSAEADDRINUSE
|
||||
|
|
|
@ -52,6 +52,10 @@ PR_BEGIN_EXTERN_C
|
|||
/* Typedefs */
|
||||
typedef struct PRDir PRDir;
|
||||
typedef struct PRDirEntry PRDirEntry;
|
||||
#ifdef MOZ_UNICODE
|
||||
typedef struct PRDirUTF16 PRDirUTF16;
|
||||
typedef struct PRDirEntryUTF16 PRDirEntryUTF16;
|
||||
#endif /* MOZ_UNICODE */
|
||||
typedef struct PRFileDesc PRFileDesc;
|
||||
typedef struct PRFileInfo PRFileInfo;
|
||||
typedef struct PRFileInfo64 PRFileInfo64;
|
||||
|
@ -650,6 +654,14 @@ NSPR_API(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode);
|
|||
NSPR_API(PRFileDesc*) PR_OpenFile(
|
||||
const char *name, PRIntn flags, PRIntn mode);
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
/*
|
||||
* EXPERIMENTAL: This function may be removed in a future release.
|
||||
*/
|
||||
NSPR_API(PRFileDesc*) PR_OpenFileUTF16(
|
||||
const PRUnichar *name, PRIntn flags, PRIntn mode);
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
* FUNCTION: PR_Close
|
||||
|
@ -830,6 +842,13 @@ struct PRFileInfo64 {
|
|||
NSPR_API(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info);
|
||||
NSPR_API(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info);
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
/*
|
||||
* EXPERIMENTAL: This function may be removed in a future release.
|
||||
*/
|
||||
NSPR_API(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info);
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
* FUNCTION: PR_GetOpenFileInfo, PR_GetOpenFileInfo64
|
||||
|
@ -984,6 +1003,13 @@ struct PRDirEntry {
|
|||
const char *name; /* name of entry, relative to directory name */
|
||||
};
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
struct PRDirEntryUTF16 {
|
||||
const PRUnichar *name; /* name of entry in UTF16, relative to
|
||||
* directory name */
|
||||
};
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
#if !defined(NO_NSPR_10_SUPPORT)
|
||||
#define PR_DirName(dirEntry) (dirEntry->name)
|
||||
#endif
|
||||
|
@ -1010,6 +1036,13 @@ struct PRDirEntry {
|
|||
|
||||
NSPR_API(PRDir*) PR_OpenDir(const char *name);
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
/*
|
||||
* EXPERIMENTAL: This function may be removed in a future release.
|
||||
*/
|
||||
NSPR_API(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name);
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
* FUNCTION: PR_ReadDir
|
||||
|
@ -1043,6 +1076,13 @@ typedef enum PRDirFlags {
|
|||
|
||||
NSPR_API(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags);
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
/*
|
||||
* EXPERIMENTAL: This function may be removed in a future release.
|
||||
*/
|
||||
NSPR_API(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags);
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
* FUNCTION: PR_CloseDir
|
||||
|
@ -1062,6 +1102,13 @@ NSPR_API(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags);
|
|||
|
||||
NSPR_API(PRStatus) PR_CloseDir(PRDir *dir);
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
/*
|
||||
* EXPERIMENTAL: This function may be removed in a future release.
|
||||
*/
|
||||
NSPR_API(PRStatus) PR_CloseDirUTF16(PRDirUTF16 *dir);
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
* FUNCTION: PR_MkDir
|
||||
|
|
|
@ -144,6 +144,9 @@ typedef struct _MDThread _MDThread;
|
|||
typedef struct _MDThreadStack _MDThreadStack;
|
||||
typedef struct _MDSemaphore _MDSemaphore;
|
||||
typedef struct _MDDir _MDDir;
|
||||
#ifdef MOZ_UNICODE
|
||||
typedef struct _MDDirUTF16 _MDDirUTF16;
|
||||
#endif /* MOZ_UNICODE */
|
||||
typedef struct _MDFileDesc _MDFileDesc;
|
||||
typedef struct _MDProcess _MDProcess;
|
||||
typedef struct _MDFileMap _MDFileMap;
|
||||
|
@ -1144,6 +1147,24 @@ extern PRInt32 _PR_MD_MAKE_DIR(const char *name, PRIntn mode);
|
|||
extern PRInt32 _PR_MD_RMDIR(const char *name);
|
||||
#define _PR_MD_RMDIR _MD_RMDIR
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
/* UTF16 File I/O related */
|
||||
extern PRStatus _PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *md, const PRUnichar *name);
|
||||
#define _PR_MD_OPEN_DIR_UTF16 _MD_OPEN_DIR_UTF16
|
||||
|
||||
extern PRInt32 _PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, PRIntn mode);
|
||||
#define _PR_MD_OPEN_FILE_UTF16 _MD_OPEN_FILE_UTF16
|
||||
|
||||
extern PRUnichar * _PR_MD_READ_DIR_UTF16(_MDDirUTF16 *md, PRIntn flags);
|
||||
#define _PR_MD_READ_DIR_UTF16 _MD_READ_DIR_UTF16
|
||||
|
||||
extern PRInt32 _PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *md);
|
||||
#define _PR_MD_CLOSE_DIR_UTF16 _MD_CLOSE_DIR_UTF16
|
||||
|
||||
extern PRInt32 _PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info);
|
||||
#define _PR_MD_GETFILEINFO64_UTF16 _MD_GETFILEINFO64_UTF16
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
/* Socket I/O related */
|
||||
extern void _PR_MD_INIT_IO(void);
|
||||
#define _PR_MD_INIT_IO _MD_INIT_IO
|
||||
|
@ -1736,6 +1757,13 @@ struct PRDir {
|
|||
_MDDir md;
|
||||
};
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
struct PRDirUTF16 {
|
||||
PRDirEntry d;
|
||||
_MDDirUTF16 md;
|
||||
};
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
extern void _PR_InitSegs(void);
|
||||
extern void _PR_InitStacks(void);
|
||||
extern void _PR_InitTPD(void);
|
||||
|
|
|
@ -464,6 +464,16 @@ typedef PRUint8 PRPackedBool;
|
|||
*/
|
||||
typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus;
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
/*
|
||||
* EXPERIMENTAL: This type may be removed in a future release.
|
||||
*/
|
||||
#ifndef __PRUNICHAR__
|
||||
#define __PRUNICHAR__
|
||||
typedef PRUint16 PRUnichar;
|
||||
#endif
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
/*
|
||||
** WARNING: The undocumented data types PRWord and PRUword are
|
||||
** only used in the garbage collection and arena code. Do not
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roy Yokoyama <yokoyama@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
|
@ -109,3 +110,52 @@ PRInt32 rv;
|
|||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
/*
|
||||
* UTF16 Interface
|
||||
*/
|
||||
PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name)
|
||||
{
|
||||
PRDirUTF16 *dir;
|
||||
PRStatus sts;
|
||||
|
||||
dir = PR_NEW(PRDirUTF16);
|
||||
if (dir) {
|
||||
sts = _PR_MD_OPEN_DIR_UTF16(&dir->md,name);
|
||||
if (sts != PR_SUCCESS) {
|
||||
PR_DELETE(dir);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags)
|
||||
{
|
||||
/*
|
||||
* _MD_READ_DIR_UTF16 return a PRUnichar* to the name; allocation in
|
||||
* machine-dependent code
|
||||
*/
|
||||
PRUnichar* name = _PR_MD_READ_DIR_UTF16(&dir->md, flags);
|
||||
dir->d.name = name;
|
||||
return name ? &dir->d : NULL;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_CloseDirUTF16(PRDirUTF16 *dir)
|
||||
{
|
||||
PRInt32 rv;
|
||||
|
||||
if (dir) {
|
||||
rv = _PR_MD_CLOSE_DIR_UTF16(&dir->md);
|
||||
PR_DELETE(dir);
|
||||
if (rv < 0)
|
||||
return PR_FAILURE;
|
||||
else
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
|
|
@ -779,3 +779,51 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe(
|
|||
return PR_FAILURE;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
/* ================ UTF16 Interfaces ================================ */
|
||||
PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16(
|
||||
const PRUnichar *name, PRIntn flags, PRIntn mode)
|
||||
{
|
||||
PRInt32 osfd;
|
||||
PRFileDesc *fd = 0;
|
||||
#if !defined(XP_UNIX) /* BugZilla: 4090 */
|
||||
PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
|
||||
#endif
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
|
||||
/* Map pr open flags and mode to os specific flags */
|
||||
osfd = _PR_MD_OPEN_FILE_UTF16(name, flags, mode);
|
||||
if (osfd != -1) {
|
||||
fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
|
||||
if (!fd) {
|
||||
(void) _PR_MD_CLOSE_FILE(osfd);
|
||||
} else {
|
||||
#if !defined(XP_UNIX) /* BugZilla: 4090 */
|
||||
fd->secret->appendMode = appendMode;
|
||||
#endif
|
||||
_PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info)
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
#pragma unused (fn, info)
|
||||
#endif
|
||||
PRInt32 rv;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
rv = _PR_MD_GETFILEINFO64_UTF16(fn, info);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================ UTF16 Interfaces ================================ */
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
|
|
@ -41,6 +41,9 @@
|
|||
#include "primpl.h"
|
||||
#include <direct.h>
|
||||
#include <mbstring.h>
|
||||
#ifdef MOZ_UNICODE
|
||||
#include <wchar.h>
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
|
||||
struct _MDLock _pr_ioq_lock;
|
||||
|
@ -74,6 +77,10 @@ static const PRTime _pr_filetime_offset = 116444736000000000LL;
|
|||
static const PRTime _pr_filetime_offset = 116444736000000000i64;
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
static void InitUnicodeSupport(void);
|
||||
#endif
|
||||
|
||||
void
|
||||
_PR_MD_INIT_IO()
|
||||
{
|
||||
|
@ -110,6 +117,10 @@ _PR_MD_INIT_IO()
|
|||
#endif /* DEBUG */
|
||||
|
||||
_PR_NT_InitSids();
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
InitUnicodeSupport();
|
||||
#endif
|
||||
}
|
||||
|
||||
PRStatus
|
||||
|
@ -1088,3 +1099,410 @@ _PR_MD_PIPEAVAILABLE(PRFileDesc *fd)
|
|||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
|
||||
typedef HANDLE (WINAPI *CreateFileWFn) (LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
|
||||
static CreateFileWFn createFileW = NULL;
|
||||
typedef HANDLE (WINAPI *FindFirstFileWFn) (LPCWSTR, LPWIN32_FIND_DATAW);
|
||||
static FindFirstFileWFn findFirstFileW = NULL;
|
||||
typedef BOOL (WINAPI *FindNextFileWFn) (HANDLE, LPWIN32_FIND_DATAW);
|
||||
static FindNextFileWFn findNextFileW = NULL;
|
||||
typedef DWORD (WINAPI *GetFullPathNameWFn) (LPCWSTR, DWORD, LPWSTR, LPWSTR *);
|
||||
static GetFullPathNameWFn getFullPathNameW = NULL;
|
||||
typedef UINT (WINAPI *GetDriveTypeWFn) (LPCWSTR);
|
||||
static GetDriveTypeWFn getDriveTypeW = NULL;
|
||||
|
||||
static void InitUnicodeSupport(void)
|
||||
{
|
||||
HMODULE module;
|
||||
|
||||
/*
|
||||
* The W functions do not exist on Win9x. NSPR won't run on Win9x
|
||||
* if we call the W functions directly. Use GetProcAddress() to
|
||||
* look up their addresses at run time.
|
||||
*/
|
||||
|
||||
module = GetModuleHandle("Kernel32.dll");
|
||||
if (!module) {
|
||||
return;
|
||||
}
|
||||
|
||||
createFileW = (CreateFileWFn)GetProcAddress(module, "CreateFileW");
|
||||
findFirstFileW = (FindFirstFileWFn)GetProcAddress(module, "FindFirstFileW");
|
||||
findNextFileW = (FindNextFileWFn)GetProcAddress(module, "FindNextFileW");
|
||||
getDriveTypeW = (GetDriveTypeWFn)GetProcAddress(module, "GetDriveTypeW");
|
||||
getFullPathNameW = (GetFullPathNameWFn)GetProcAddress(module, "GetFullPathNameW");
|
||||
}
|
||||
|
||||
/* ================ UTF16 Interfaces ================================ */
|
||||
void FlipSlashesW(PRUnichar *cp, int len)
|
||||
{
|
||||
while (--len >= 0) {
|
||||
if (cp[0] == L'/') {
|
||||
cp[0] = L'\\';
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
} /* end FlipSlashesW() */
|
||||
|
||||
PRInt32
|
||||
_PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, int mode)
|
||||
{
|
||||
HANDLE file;
|
||||
PRInt32 access = 0;
|
||||
PRInt32 flags = 0;
|
||||
PRInt32 flag6 = 0;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
LPSECURITY_ATTRIBUTES lpSA = NULL;
|
||||
PSECURITY_DESCRIPTOR pSD = NULL;
|
||||
PACL pACL = NULL;
|
||||
|
||||
if (!createFileW) {
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (osflags & PR_CREATE_FILE) {
|
||||
if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable,
|
||||
&pSD, &pACL) == PR_SUCCESS) {
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = pSD;
|
||||
sa.bInheritHandle = FALSE;
|
||||
lpSA = &sa;
|
||||
}
|
||||
}
|
||||
|
||||
if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
|
||||
|
||||
if (osflags & PR_RDONLY || osflags & PR_RDWR)
|
||||
access |= GENERIC_READ;
|
||||
if (osflags & PR_WRONLY || osflags & PR_RDWR)
|
||||
access |= GENERIC_WRITE;
|
||||
|
||||
if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
|
||||
flags = CREATE_NEW;
|
||||
else if (osflags & PR_CREATE_FILE) {
|
||||
if (osflags & PR_TRUNCATE)
|
||||
flags = CREATE_ALWAYS;
|
||||
else
|
||||
flags = OPEN_ALWAYS;
|
||||
} else {
|
||||
if (osflags & PR_TRUNCATE)
|
||||
flags = TRUNCATE_EXISTING;
|
||||
else
|
||||
flags = OPEN_EXISTING;
|
||||
}
|
||||
|
||||
file = createFileW(name,
|
||||
access,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
lpSA,
|
||||
flags,
|
||||
flag6,
|
||||
NULL);
|
||||
if (lpSA != NULL) {
|
||||
_PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
|
||||
}
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
_PR_MD_MAP_OPEN_ERROR(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (PRInt32)file;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *d, const PRUnichar *name)
|
||||
{
|
||||
PRUnichar filename[ MAX_PATH ];
|
||||
int len;
|
||||
|
||||
if (!findFirstFileW) {
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
len = wcslen(name);
|
||||
/* Need 5 bytes for \*.* and the trailing null byte. */
|
||||
if (len + 5 > MAX_PATH) {
|
||||
PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
wcscpy(filename, name);
|
||||
|
||||
/*
|
||||
* If 'name' ends in a slash or backslash, do not append
|
||||
* another backslash.
|
||||
*/
|
||||
if (filename[len - 1] == L'/' || filename[len - 1] == L'\\') {
|
||||
len--;
|
||||
}
|
||||
wcscpy(&filename[len], L"\\*.*");
|
||||
FlipSlashesW( filename, wcslen(filename) );
|
||||
|
||||
d->d_hdl = findFirstFileW( filename, &(d->d_entry) );
|
||||
if ( d->d_hdl == INVALID_HANDLE_VALUE ) {
|
||||
_PR_MD_MAP_OPENDIR_ERROR(GetLastError());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
d->firstEntry = PR_TRUE;
|
||||
d->magic = _MD_MAGIC_DIR;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRUnichar *
|
||||
_PR_MD_READ_DIR_UTF16(_MDDirUTF16 *d, PRIntn flags)
|
||||
{
|
||||
PRInt32 err;
|
||||
BOOL rv;
|
||||
PRUnichar *fileName;
|
||||
|
||||
if (!findNextFileW) {
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( d ) {
|
||||
while (1) {
|
||||
if (d->firstEntry) {
|
||||
d->firstEntry = PR_FALSE;
|
||||
rv = 1;
|
||||
} else {
|
||||
rv = findNextFileW(d->d_hdl, &(d->d_entry));
|
||||
}
|
||||
if (rv == 0) {
|
||||
break;
|
||||
}
|
||||
fileName = GetFileFromDIR(d);
|
||||
if ( (flags & PR_SKIP_DOT) &&
|
||||
(fileName[0] == L'.') && (fileName[1] == L'\0'))
|
||||
continue;
|
||||
if ( (flags & PR_SKIP_DOT_DOT) &&
|
||||
(fileName[0] == L'.') && (fileName[1] == L'.') &&
|
||||
(fileName[2] == L'\0'))
|
||||
continue;
|
||||
if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d))
|
||||
continue;
|
||||
return fileName;
|
||||
}
|
||||
err = GetLastError();
|
||||
PR_ASSERT(NO_ERROR != err);
|
||||
_PR_MD_MAP_READDIR_ERROR(err);
|
||||
return NULL;
|
||||
}
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *d)
|
||||
{
|
||||
if ( d ) {
|
||||
if (FindClose(d->d_hdl)) {
|
||||
d->magic = (PRUint32)-1;
|
||||
return PR_SUCCESS;
|
||||
} else {
|
||||
_PR_MD_MAP_CLOSEDIR_ERROR(GetLastError());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
}
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
#define _PR_IS_W_SLASH(ch) ((ch) == L'/' || (ch) == L'\\')
|
||||
|
||||
/*
|
||||
* IsRootDirectoryW --
|
||||
*
|
||||
* Return PR_TRUE if the pathname 'fn' is a valid root directory,
|
||||
* else return PR_FALSE. The PRUnichar buffer pointed to by 'fn' must
|
||||
* be writable. During the execution of this function, the contents
|
||||
* of the buffer pointed to by 'fn' may be modified, but on return
|
||||
* the original contents will be restored. 'buflen' is the size of
|
||||
* the buffer pointed to by 'fn', in PRUnichars.
|
||||
*
|
||||
* Root directories come in three formats:
|
||||
* 1. / or \, meaning the root directory of the current drive.
|
||||
* 2. C:/ or C:\, where C is a drive letter.
|
||||
* 3. \\<server name>\<share point name>\ or
|
||||
* \\<server name>\<share point name>, meaning the root directory
|
||||
* of a UNC (Universal Naming Convention) name.
|
||||
*/
|
||||
|
||||
static PRBool
|
||||
IsRootDirectoryW(PRUnichar *fn, size_t buflen)
|
||||
{
|
||||
PRUnichar *p;
|
||||
PRBool slashAdded = PR_FALSE;
|
||||
PRBool rv = PR_FALSE;
|
||||
|
||||
if (_PR_IS_W_SLASH(fn[0]) && fn[1] == L'\0') {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (iswalpha(fn[0]) && fn[1] == L':' && _PR_IS_W_SLASH(fn[2])
|
||||
&& fn[3] == L'\0') {
|
||||
rv = getDriveTypeW(fn) > 1 ? PR_TRUE : PR_FALSE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* The UNC root directory */
|
||||
|
||||
if (_PR_IS_W_SLASH(fn[0]) && _PR_IS_W_SLASH(fn[1])) {
|
||||
/* The 'server' part should have at least one character. */
|
||||
p = &fn[2];
|
||||
if (*p == L'\0' || _PR_IS_W_SLASH(*p)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* look for the next slash */
|
||||
do {
|
||||
p++;
|
||||
} while (*p != L'\0' && !_PR_IS_W_SLASH(*p));
|
||||
if (*p == L'\0') {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* The 'share' part should have at least one character. */
|
||||
p++;
|
||||
if (*p == L'\0' || _PR_IS_W_SLASH(*p)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* look for the final slash */
|
||||
do {
|
||||
p++;
|
||||
} while (*p != L'\0' && !_PR_IS_W_SLASH(*p));
|
||||
if (_PR_IS_W_SLASH(*p) && p[1] != L'\0') {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (*p == L'\0') {
|
||||
/*
|
||||
* GetDriveType() doesn't work correctly if the
|
||||
* path is of the form \\server\share, so we add
|
||||
* a final slash temporarily.
|
||||
*/
|
||||
if ((p + 1) < (fn + buflen)) {
|
||||
*p++ = L'\\';
|
||||
*p = L'\0';
|
||||
slashAdded = PR_TRUE;
|
||||
} else {
|
||||
return PR_FALSE; /* name too long */
|
||||
}
|
||||
}
|
||||
rv = getDriveTypeW(fn) > 1 ? PR_TRUE : PR_FALSE;
|
||||
/* restore the 'fn' buffer */
|
||||
if (slashAdded) {
|
||||
*--p = L'\0';
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info)
|
||||
{
|
||||
HANDLE hFindFile;
|
||||
WIN32_FIND_DATAW findFileData;
|
||||
PRUnichar pathbuf[MAX_PATH + 1];
|
||||
|
||||
if (!findFirstFileW || !getFullPathNameW || !getDriveTypeW) {
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == fn || L'\0' == *fn) {
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* FindFirstFile() expands wildcard characters. So
|
||||
* we make sure the pathname contains no wildcard.
|
||||
*/
|
||||
if (NULL != wcspbrk(fn, L"?*")) {
|
||||
PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hFindFile = findFirstFileW(fn, &findFileData);
|
||||
if (INVALID_HANDLE_VALUE == hFindFile) {
|
||||
DWORD len;
|
||||
PRUnichar *filePart;
|
||||
|
||||
/*
|
||||
* FindFirstFile() does not work correctly on root directories.
|
||||
* It also doesn't work correctly on a pathname that ends in a
|
||||
* slash. So we first check to see if the pathname specifies a
|
||||
* root directory. If not, and if the pathname ends in a slash,
|
||||
* we remove the final slash and try again.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the pathname does not contain ., \, and /, it cannot be
|
||||
* a root directory or a pathname that ends in a slash.
|
||||
*/
|
||||
if (NULL == wcspbrk(fn, L".\\/")) {
|
||||
_PR_MD_MAP_OPENDIR_ERROR(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
len = getFullPathNameW(fn, sizeof(pathbuf)/sizeof(pathbuf[0]), pathbuf,
|
||||
&filePart);
|
||||
if (0 == len) {
|
||||
_PR_MD_MAP_OPENDIR_ERROR(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
if (len > sizeof(pathbuf)/sizeof(pathbuf[0])) {
|
||||
PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
if (IsRootDirectoryW(pathbuf, sizeof(pathbuf)/sizeof(pathbuf[0]))) {
|
||||
info->type = PR_FILE_DIRECTORY;
|
||||
info->size = 0;
|
||||
/*
|
||||
* These timestamps don't make sense for root directories.
|
||||
*/
|
||||
info->modifyTime = 0;
|
||||
info->creationTime = 0;
|
||||
return 0;
|
||||
}
|
||||
if (!_PR_IS_W_SLASH(pathbuf[len - 1])) {
|
||||
_PR_MD_MAP_OPENDIR_ERROR(GetLastError());
|
||||
return -1;
|
||||
} else {
|
||||
pathbuf[len - 1] = L'\0';
|
||||
hFindFile = findFirstFileW(pathbuf, &findFileData);
|
||||
if (INVALID_HANDLE_VALUE == hFindFile) {
|
||||
_PR_MD_MAP_OPENDIR_ERROR(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FindClose(hFindFile);
|
||||
|
||||
if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
info->type = PR_FILE_DIRECTORY;
|
||||
} else {
|
||||
info->type = PR_FILE_FILE;
|
||||
}
|
||||
|
||||
info->size = findFileData.nFileSizeHigh;
|
||||
info->size = (info->size << 32) + findFileData.nFileSizeLow;
|
||||
|
||||
_PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime);
|
||||
|
||||
if (0 == findFileData.ftCreationTime.dwLowDateTime &&
|
||||
0 == findFileData.ftCreationTime.dwHighDateTime) {
|
||||
info->creationTime = info->modifyTime;
|
||||
} else {
|
||||
_PR_FileTimeToPRTime(&findFileData.ftCreationTime,
|
||||
&info->creationTime);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* ================ end of UTF16 Interfaces ================================ */
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
|
|
@ -4786,4 +4786,39 @@ retry:
|
|||
}
|
||||
#endif /* defined(_PR_PTHREADS) */
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
/* ================ UTF16 Interfaces ================================ */
|
||||
PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16(
|
||||
const PRUnichar *name, PRIntn flags, PRIntn mode)
|
||||
{
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_CloseDirUTF16(PRDir *dir)
|
||||
{
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name)
|
||||
{
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags)
|
||||
{
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info)
|
||||
{
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
/* ================ UTF16 Interfaces ================================ */
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
/* ptio.c */
|
||||
|
|
Загрузка…
Ссылка в новой задаче