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:
wtc%netscape.com 2002-11-27 03:17:13 +00:00
Родитель 9998107b73
Коммит 1dcd628e75
9 изменённых файлов: 659 добавлений и 0 удалений

Просмотреть файл

@ -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 */