/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* Access APIs for WinXP and above */
#ifndef _WIN32_WINNT
#endif
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <direct.h>
#include <windows.h>
#include <io.h>
#include "jni.h"
#include "io_util.h"
#include "jlong.h"
#include "io_util_md.h"
#include "dirent_md.h"
#include "java_io_FileSystem.h"
static struct {
} ids;
/**
* GetFinalPathNameByHandle is available on Windows Vista and newer
*/
{
if (!fileClass) return;
// GetFinalPathNameByHandle requires Windows Vista or newer
{
}
}
/* -- Path operations -- */
extern int wcanonicalizeWithPrefix(const WCHAR *canonicalPrefix, const WCHAR *pathWithCanonicalPrefix, WCHAR *out, int len);
/**
* Retrieves the fully resolved (final) path for the given path or NULL
* if the function fails.
*/
{
HANDLE h;
/* Need Windows Vista or newer to get the final path */
if (GetFinalPathNameByHandle_func == NULL)
return NULL;
h = CreateFileW(path,
NULL,
NULL);
if (h == INVALID_HANDLE_VALUE)
return NULL;
/**
* Allocate a buffer for the resolved path. For a long path we may need
* to allocate a larger buffer.
*/
/* retry with a buffer of the right size */
} else {
len = 0;
}
}
if (len > 0) {
/**
* Strip prefix (should be \\?\ or \\?\UNC)
*/
{
/* actual result length (includes terminator) */
/* copy result without prefix into new buffer */
len = 0;
} else {
p += prefixLen;
if (isUnc) {
p2[0] = L'\\';
p2++;
} else {
}
}
}
}
/* unable to get final path */
}
}
error = GetLastError();
if (CloseHandle(h))
return result;
}
/**
* Retrieves file information for the specified file. If the file is
* symbolic link then the information on fully resolved target is
* returned.
*/
{
NULL,
NULL);
if (h == INVALID_HANDLE_VALUE)
return FALSE;
error = GetLastError();
if (CloseHandle(h))
return result;
}
/**
* If the given attributes are the attributes of a reparse point, then
* read and return the attributes of the special cases.
*/
{
if ((a != INVALID_FILE_ATTRIBUTES) &&
((a & FILE_ATTRIBUTE_REPARSE_POINT) != 0))
{
}
return a;
}
/**
* Take special cases into account when retrieving the attributes
* of path
*/
{
HANDLE h;
} else if (GetLastError() == ERROR_SHARING_VIOLATION &&
FindClose(h);
}
return attr;
}
{
/*we estimate the max length of memory needed as
"currentDir. length + pathname.length"
*/
}
}
} else
}
}
return rv;
}
{
if (len > MAX_PATH_LENGTH) {
}
}
} else
canonicalPath, MAX_PATH_LENGTH) >= 0) {
}
}
return rv;
}
/* -- Attribute accessors -- */
/* Check whether or not the file name in "path" is a Windows reserved
device name (CON, PRN, AUX, NUL, COM[1-9], LPT[1-9]) based on the
returned result from GetFullPathName, which should be in thr form of
"\\.\[ReservedDeviceName]" if the path represents a reserved device
name.
Note1: GetFullPathName doesn't think "CLOCK$" (which is no longer
important anyway) is a device name, so we don't check it here.
200X.
Note2: Theoretically the implementation could just lookup the table
below linearly if the first 4 characters of the fullpath returned
from GetFullPathName are "\\.\". The current implementation should
achieve the same result. If Microsoft add more names into their
reserved device name repository in the future, which probably will
never happen, we will need to revisit the lookup implementation.
static WCHAR* ReservedDEviceNames[] = {
L"CON", L"PRN", L"AUX", L"NUL",
L"COM1", L"COM2", L"COM3", L"COM4", L"COM5", L"COM6", L"COM7", L"COM8", L"COM9",
L"LPT1", L"LPT2", L"LPT3", L"LPT4", L"LPT5", L"LPT6", L"LPT7", L"LPT8", L"LPT9",
L"CLOCK$"
};
*/
buf,
&lpf);
return TRUE;
return TRUE;
}
return FALSE;
}
{
return rv;
if (!isReservedDeviceNameW(pathbuf)) {
if (a != INVALID_FILE_ATTRIBUTES) {
| ((a & FILE_ATTRIBUTE_DIRECTORY)
| ((a & FILE_ATTRIBUTE_HIDDEN)
? java_io_FileSystem_BA_HIDDEN : 0));
}
}
return rv;
}
{
return JNI_FALSE;
if (attr == INVALID_FILE_ATTRIBUTES)
return JNI_FALSE;
switch (access) {
return JNI_TRUE;
/* Read-only attribute ignored on directories */
if ((attr & FILE_ATTRIBUTE_DIRECTORY) ||
(attr & FILE_ATTRIBUTE_READONLY) == 0)
return JNI_TRUE;
else
return JNI_FALSE;
default:
assert(0);
return JNI_FALSE;
}
}
{
DWORD a;
if (access == java_io_FileSystem_ACCESS_READ ||
return enable;
}
return JNI_FALSE;
a = GetFileAttributesW(pathbuf);
/* if reparse point, get final target */
if ((a != INVALID_FILE_ATTRIBUTES) &&
((a & FILE_ATTRIBUTE_REPARSE_POINT) != 0))
{
} else {
a = GetFileAttributesW(pathbuf);
}
}
if ((a != INVALID_FILE_ATTRIBUTES) &&
((a & FILE_ATTRIBUTE_DIRECTORY) == 0))
{
if (enable)
a = a & ~FILE_ATTRIBUTE_READONLY;
else
a = a | FILE_ATTRIBUTE_READONLY;
if (SetFileAttributesW(pathbuf, a))
}
return rv;
}
{
FILETIME t;
HANDLE h;
return rv;
h = CreateFileW(pathbuf,
/* Device query access */
0,
/* Share it */
/* No security attributes */
NULL,
/* Open existing or fail */
/* Backup semantics for directories */
/* No template file */
NULL);
if (h != INVALID_HANDLE_VALUE) {
rv -= 11644473600000;
}
CloseHandle(h);
}
return rv;
}
{
return rv;
&wfad)) {
} else {
/* file is a reparse point so read attributes of final target */
}
}
} else {
if (GetLastError() == ERROR_SHARING_VIOLATION) {
must exists. Try _wstati64, we know this at least works
for pagefile.sys and hiberfil.sys.
*/
}
}
}
return rv;
}
/* -- File operations -- */
{
return JNI_FALSE;
if (isReservedDeviceNameW(pathbuf)) {
return JNI_FALSE;
}
h = CreateFileW(
pathbuf, /* Wide char path name */
NULL, /* Security attributes */
CREATE_NEW, /* creation disposition */
FILE_FLAG_OPEN_REPARSE_POINT, /* flags and attributes */
NULL);
if (h == INVALID_HANDLE_VALUE) {
// return false rather than throwing an exception when there is
// an existing file.
if (a == INVALID_FILE_ATTRIBUTES) {
}
}
return JNI_FALSE;
}
CloseHandle(h);
return JNI_TRUE;
}
static int
{
/* Returns 0 on success */
DWORD a;
a = GetFileAttributesW(path);
if (a == INVALID_FILE_ATTRIBUTES) {
return 1;
} else if (a & FILE_ATTRIBUTE_DIRECTORY) {
return !RemoveDirectoryW(path);
} else {
return !DeleteFileW(path);
}
}
{
return JNI_FALSE;
}
if (removeFileOrDirectory(pathbuf) == 0) {
}
return rv;
}
{
return NULL;
if (search_path == 0) {
return NULL;
}
if (fattr == INVALID_FILE_ATTRIBUTES) {
return NULL;
} else if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
return NULL;
}
/* Remove trailing space chars from directory name */
len--;
}
search_path[len] = 0;
/* Append "*", or possibly "\\*", to path */
/* No '\\' needed for cases like "\" or "Z:" or "Z:\" */
} else {
}
/* Open handle to the first file */
if (handle == INVALID_HANDLE_VALUE) {
if (GetLastError() != ERROR_FILE_NOT_FOUND) {
// error
return NULL;
} else {
// No files found - return an empty array
return rv;
}
}
/* Allocate an initial String array */
len = 0;
maxlen = 16;
return NULL;
/* Scan the directory */
do {
continue;
return NULL; // error;
return NULL; // error
}
if (GetLastError() != ERROR_NO_MORE_FILES)
return NULL; // error
/* Copy the final results into an appropriately-sized array */
return NULL; /* error */
return NULL; /* error */
return rv;
}
{
/* Exception is pending */
return JNI_FALSE;
}
if (h == 0) {
return JNI_FALSE;
}
return JNI_TRUE;
}
{
return JNI_FALSE;
}
return rv;
}
{
HANDLE h;
return JNI_FALSE;
h = CreateFileW(pathbuf,
NULL,
0);
if (h != INVALID_HANDLE_VALUE) {
FILETIME t;
}
CloseHandle(h);
}
return rv;
}
{
DWORD a;
return JNI_FALSE;
a = GetFileAttributesW(pathbuf);
/* if reparse point, get final target */
if ((a != INVALID_FILE_ATTRIBUTES) &&
((a & FILE_ATTRIBUTE_REPARSE_POINT) != 0))
{
} else {
a = GetFileAttributesW(pathbuf);
}
}
if ((a != INVALID_FILE_ATTRIBUTES) &&
((a & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
}
return rv;
}
/* -- Filesystem interface -- */
{
return ret;
}
{
switch(t) {
break;
break;
break;
default:
assert(0);
}
}
}
return rv;
}