You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/10/11 12:10:37 UTC
svn commit: r824046 - in /commons/sandbox/runtime/trunk/src/main/native:
Makefile.msc.in include/acr_file.h include/arch/windows/acr_arch.h
os/unix/finfo.c os/win32/dir.c os/win32/dirent.c os/win32/finfo.c
Author: mturk
Date: Sun Oct 11 10:10:37 2009
New Revision: 824046
URL: http://svn.apache.org/viewvc?rev=824046&view=rev
Log:
Implement windows FileInfo and Directory API
Modified:
commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h
commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h
commons/sandbox/runtime/trunk/src/main/native/os/unix/finfo.c
commons/sandbox/runtime/trunk/src/main/native/os/win32/dir.c
commons/sandbox/runtime/trunk/src/main/native/os/win32/dirent.c
commons/sandbox/runtime/trunk/src/main/native/os/win32/finfo.c
Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in?rev=824046&r1=824045&r2=824046&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in Sun Oct 11 10:10:37 2009
@@ -118,7 +118,6 @@
$(SRCDIR)/os/win32/fsysio.$(OBJ) \
$(SRCDIR)/os/win32/main.$(OBJ) \
$(SRCDIR)/os/win32/platform.$(OBJ) \
- $(SRCDIR)/os/win32/pipe.$(OBJ) \
$(SRCDIR)/os/win32/proc.$(OBJ) \
$(SRCDIR)/os/win32/os.$(OBJ) \
$(SRCDIR)/os/win32/ios.$(OBJ) \
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h?rev=824046&r1=824045&r2=824046&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h Sun Oct 11 10:10:37 2009
@@ -298,8 +298,11 @@
* @param fname FileInfo.Name field.
* @param type FileInfo.Type field.
*/
-ACR_DECLARE(jobject) ACR_NewFileInfoObject(JNIEnv *env,
- const acr_pchar_t *fname, int type);
+ACR_DECLARE(jobject) ACR_NewFileInfoObjectA(JNIEnv *env,
+ const char *fname, int type);
+
+ACR_DECLARE(jobject) ACR_NewFileInfoObjectW(JNIEnv *env,
+ const wchar_t *fname, int type);
#ifdef __cplusplus
}
Modified: commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h?rev=824046&r1=824045&r2=824046&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h Sun Oct 11 10:10:37 2009
@@ -308,6 +308,17 @@
return;
}
+static ACR_INLINE void FileTimeToMsecTime(acr_time_t *result, LPFILETIME input)
+{
+ /* Convert FILETIME one 64 bit number so we can work with it. */
+ *result = ((LARGE_INTEGER *)input)->QuadPart;
+ /* Convert from 100 nano-sec periods to micro-seconds. */
+ *result /= 10000;
+ /* Convert from Windows epoch to Unix epoch */
+ *result -= ACR_DELTA_EPOCH_IN_USEC;
+ return;
+}
+
static ACR_INLINE void UsecTimeToFileTime(LPFILETIME result, acr_time_t t)
{
@@ -315,6 +326,12 @@
return;
}
+static ACR_INLINE void MsecTimeToFileTime(LPFILETIME result, acr_time_t t)
+{
+ ((LARGE_INTEGER *)result)->QuadPart = (t + ACR_DELTA_EPOCH_IN_USEC) * 10000;
+ return;
+}
+
static ACR_INLINE void x_free(void *p)
{
if (p != NULL) {
@@ -419,6 +436,17 @@
*/
} DIR;
+/** Dirent API
+ */
+DIR *opendir(const char *);
+int closedir(DIR *);
+void rewinddir(DIR *);
+off_t telldir(DIR *);
+int readdir_r(DIR *, struct dirent *, struct dirent **r);
+void seekdir(DIR *, off_t);
+
+
+
#define _NSIG 32 /* counting 0; could be 33 (mask is 1-32) */
#define SIGHUP 1 /* hangup */
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/finfo.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/finfo.c?rev=824046&r1=824045&r2=824046&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/finfo.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/finfo.c Sun Oct 11 10:10:37 2009
@@ -165,8 +165,8 @@
ACR_UnloadClass(_E, &_clazzn);
}
-ACR_DECLARE(jobject) ACR_NewFileInfoObject(JNIEnv *_E, const char *fname,
- int type)
+ACR_DECLARE(jobject) ACR_NewFileInfoObjectA(JNIEnv *_E, const char *fname,
+ int type)
{
jstring name;
if ((name = ACR_NewJavaStringA(_E, fname)))
@@ -175,6 +175,16 @@
return NULL;
}
+ACR_DECLARE(jobject) ACR_NewFileInfoObjectW(JNIEnv *_E, const wchar_t *fname,
+ int type)
+{
+ jstring name;
+ if ((name = ACR_NewJavaStringW(_E, fname)))
+ return (*_E)->NewObject(_E, _clazzn.i, J4MID(0001), type);
+ else
+ return NULL;
+}
+
static void _fill0(ACR_JNISTDARGS, struct_stat_t *info, jboolean full)
{
SET_IFIELD_I(0000, _O, ACR_UnixModeToPerms(info->st_mode));
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/dir.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/dir.c?rev=824046&r1=824045&r2=824046&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/dir.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/dir.c Sun Oct 11 10:10:37 2009
@@ -1,19 +1,3 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
#include "acr.h"
#include "acr_private.h"
#include "acr_arch.h"
@@ -25,6 +9,280 @@
#include "acr_port.h"
/**
- * Windows file info functions
+ * Windows directory functions
*
*/
+
+static int descriptor_cleanup(ACR_JNISTDARGS,
+ acr_descriptor_cb_type_e cm,
+ acr_descriptor_cb_t *dp)
+{
+ int rc = ACR_SUCCESS;
+ switch (cm) {
+ case ACR_DESC_FINALIZE:
+ case ACR_DESC_CLOSE:
+ if (dp->dp != NULL) {
+ if (closedir((DIR *)dp->dp))
+ rc = ACR_GET_OS_ERROR();
+ }
+ else
+ rc = ACR_EBADF;
+ break;
+ default:
+ rc = ACR_ENOTIMPL;
+ break;
+ }
+ return rc;
+}
+
+ACR_IO_EXPORT_DECLARE(jobject, Directory, open0)(ACR_JNISTDARGS, jstring name)
+{
+ DIR *dir;
+ jobject dd = NULL;
+ int rc = 0;
+
+ WITH_CSTR(name) {
+ if ((dir = opendir(J2S(name)))) {
+ dd = ACR_DescriptorCreate(_E, ACR_DT_DIR, -1, dir,
+ descriptor_cleanup);
+ }
+ else
+ rc = ACR_GET_OS_ERROR();
+ } END_WITH_CSTR(name);
+ ACR_THROW_IO_IF_ERR(rc);
+ return dd;
+}
+
+ACR_IO_EXPORT_DECLARE(jstring, Directory, read0)(ACR_JNISTDARGS, jobject dd)
+{
+ DIR *dir;
+ int rc = 0;
+ jstring rv = NULL;
+
+ dir = (DIR *)ACR_DescriptorGetPtr(_E, dd);
+ if (dir) {
+ struct dirent ds;
+ struct dirent *dp;
+ for (;;) {
+ if (!readdir_r(dir, &ds, &dp)) {
+ if (dp) {
+ if (*(dp->d_name) == '.' && (*(dp->d_name + 1) == '\0' ||
+ (*(dp->d_name + 1) == '.' &&
+ *(dp->d_name + 2) == '\0'))) {
+ /* Skip . and .. directory entires
+ */
+ continue;
+ }
+ /* Not at end of dir */
+ rv = ACR_NewJavaStringA(_E, dp->d_name);
+ }
+ else
+ break;
+ }
+ else {
+ /* readdir_r failed */
+ rc = ACR_GET_OS_ERROR();
+ break;
+ }
+ }
+ }
+ ACR_THROW_IO_IF_ERR(rc);
+ return rv;
+}
+
+ACR_IO_EXPORT_DECLARE(jobject, Directory, read1)(ACR_JNISTDARGS, jobject dd)
+{
+ DIR *dir;
+ int rc = 0;
+ jobject rv = NULL;
+
+ dir = (DIR *)ACR_DescriptorGetPtr(_E, dd);
+ if (dir) {
+ struct dirent ds;
+ struct dirent *dp;
+ for (;;) {
+ if (!readdir_r(dir, &ds, &dp)) {
+ if (dp) {
+ int type;
+ if (*(dp->d_name) == '.' && (*(dp->d_name + 1) == '\0' ||
+ (*(dp->d_name + 1) == '.' &&
+ *(dp->d_name + 2) == '\0'))) {
+ /* Skip . and .. directory entires
+ */
+ continue;
+ }
+ /* Determine the type of the enty
+ */
+ if (dp->d_type & FILE_ATTRIBUTE_DIRECTORY)
+ type = ACR_FT_DIR;
+ else if (dp->d_type & FILE_ATTRIBUTE_REPARSE_POINT)
+ type = ACR_FT_LNK;
+ else if (dp->d_type & FILE_ATTRIBUTE_DEVICE)
+ type = ACR_FT_CHR;
+ else
+ type = ACR_FT_REG;
+ rv = ACR_NewFileInfoObjectA(_E, dp->d_name, type);
+ }
+ else
+ break;
+ }
+ else {
+ /* readdir_r failed */
+ rc = ACR_GET_OS_ERROR();
+ break;
+ }
+ }
+ }
+ ACR_THROW_IO_IF_ERR(rc);
+ return rv;
+}
+
+ACR_IO_EXPORT_DECLARE(void, Directory, rewind0)(ACR_JNISTDARGS, jobject dd)
+{
+ DIR *dir;
+ if (( dir = (DIR *)ACR_DescriptorGetPtr(_E, dd))) {
+ rewinddir(dir);
+ }
+}
+
+ACR_IO_EXPORT_DECLARE(jlong, Directory, tell0)(ACR_JNISTDARGS, jobject dd)
+{
+ DIR *dir;
+ off_t pos = -1;
+ int rc = 0;
+
+ if (( dir = (DIR *)ACR_DescriptorGetPtr(_E, dd))) {
+ pos = telldir(dir);
+ if (pos == -1)
+ rc = ACR_GET_OS_ERROR();
+ }
+ else
+ rc = ACR_EBADF;
+ ACR_THROW_IO_IF_ERR(rc);
+ return (jlong)pos;
+}
+
+ACR_IO_EXPORT_DECLARE(void, Directory, seek0)(ACR_JNISTDARGS, jobject dd,
+ jlong off)
+{
+ DIR *dir;
+
+ if (( dir = (DIR *)ACR_DescriptorGetPtr(_E, dd))) {
+ seekdir(dir, (off_t)off);
+ }
+}
+
+static int _mkdir0(const wchar_t *name, int perms)
+{
+ SECURITY_ATTRIBUTES sa;
+
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ /* Allow access only to owner and Administrators Group */
+ sa.lpSecurityDescriptor = ACR_StdSecurityDescriptor(INVALID_HANDLE_VALUE,
+ ACR_DT_FILE, perms);
+
+ if (CreateDirectoryW(name, &sa))
+ return 0;
+ else
+ return ACR_GET_OS_ERROR();
+}
+
+static __inline void FS2BS(wchar_t *path)
+{
+ while (*path) {
+ if (*path == L'/')
+ *path = L'\\';
+ path++;
+ }
+}
+
+static int _mkdir1(const wchar_t *name, int perms)
+{
+ int rc;
+
+ rc = _mkdir0(name, perms);
+ if (rc == ERROR_ALREADY_EXISTS)
+ return 0;
+ if (rc == ERROR_PATH_NOT_FOUND) { /* Missing an intermediate dir */
+ wchar_t *pos;
+ wchar_t *dir = ACR_StrdupW(INVALID_HANDLE_VALUE, THROW_NMARK, name);
+ if (!dir)
+ return ACR_ENOMEM;
+ FS2BS(dir);
+ if ((pos = wcsrchr(dir, L'\\'))) {
+ *pos = L'\0';
+ if (*dir) {
+ rc = _mkdir1(dir, perms);
+ }
+ }
+ x_free(dir);
+ }
+ return rc;
+}
+
+ACR_IO_EXPORT_DECLARE(jint, Directory, mkdir0)(ACR_JNISTDARGS, jstring name,
+ jint perms)
+{
+ int rc = 0;
+
+ WITH_WSTR(name) {
+ rc = _mkdir0(J2W(name), perms);
+ } END_WITH_WSTR(name);
+ return rc;
+}
+
+ACR_IO_EXPORT_DECLARE(jint, Directory, mkdir1)(ACR_JNISTDARGS, jstring name,
+ jint perms)
+{
+ int rc = 0;
+
+ WITH_WSTR(name) {
+ rc = _mkdir1(J2W(name), perms);
+ } END_WITH_WSTR(name);
+ return rc;
+}
+
+ACR_IO_EXPORT_DECLARE(jstring, Directory, tmpdir0)(ACR_JNISTDARGS, jstring path,
+ jstring prefix)
+{
+ int rc = 0;
+ wchar_t *tmpd = NULL;
+
+ UNREFERENCED_O;
+
+ WITH_ZWSTR(path) {
+ WITH_ZWSTR(prefix) {
+ /* Provide INVALID_HANDLE_VALUE for JNIEnv
+ * so that in case of failure, exception doesn't get thrown
+ */
+ tmpd = ACR_TempDirMake(INVALID_HANDLE_VALUE, J2W(path), J2W(prefix));
+ if (!tmpd)
+ rc = ACR_GET_OS_ERROR();
+ } END_WITH_WSTR(prefix);
+ } END_WITH_WSTR(path);
+ if (rc) {
+ ACR_THROW_IO_IF_ERR(rc);
+ return NULL;
+ }
+ else {
+ jstring rv = ACR_NewJavaStringW(_E, tmpd);
+ x_free(tmpd);
+ return rv;
+ }
+}
+
+ACR_IO_EXPORT_DECLARE(jstring, Directory, tmpdir1)(ACR_JNISTDARGS,
+ jstring paths)
+{
+ const wchar_t *tmpd = NULL;
+
+ UNREFERENCED_O;
+
+ WITH_ZWSTR(paths) {
+ tmpd = ACR_TempPathGet(INVALID_HANDLE_VALUE, J2W(paths));
+ } END_WITH_WSTR(paths);
+ if (tmpd)
+ return ACR_NewJavaStringW(_E, tmpd);
+ else
+ return NULL;
+}
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/dirent.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/dirent.c?rev=824046&r1=824045&r2=824046&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/dirent.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/dirent.c Sun Oct 11 10:10:37 2009
@@ -181,7 +181,7 @@
if (mblen == 0 || mblen > 1024)
return GetLastError();
entry->d_ino = 0;
- entry->d_type = 0;
+ entry->d_type = wfind.dwFileAttributes;
entry->d_off = dir->d_stat;
entry->d_reclen = (unsigned short)(mblen - 1);
*result = entry;
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/finfo.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/finfo.c?rev=824046&r1=824045&r2=824046&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/finfo.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/finfo.c Sun Oct 11 10:10:37 2009
@@ -14,15 +14,17 @@
* limitations under the License.
*/
+
#include "acr.h"
#include "acr_private.h"
#include "acr_arch.h"
+#include "acr_clazz.h"
+#include "acr_descriptor.h"
#include "acr_port.h"
#include "acr_error.h"
#include "acr_string.h"
-#include "acr_descriptor.h"
+#include "acr_users.h"
#include "acr_file.h"
-#include "acr_port.h"
/**
* Windows file info functions
@@ -121,6 +123,12 @@
J_DECLARE_M_ID(0001) = {
NULL,
+ "<init>",
+ "(Ljava/lang/String;I)V"
+};
+
+J_DECLARE_M_ID(0002) = {
+ NULL,
"setType",
"(I)V"
};
@@ -146,6 +154,7 @@
J_LOAD_IFIELD(0012);
J_LOAD_METHOD(0000);
J_LOAD_METHOD(0001);
+ J_LOAD_METHOD(0002);
return ACR_SUCCESS;
}
@@ -154,3 +163,348 @@
{
ACR_UnloadClass(_E, &_clazzn);
}
+
+ACR_DECLARE(jobject) ACR_NewFileInfoObjectA(JNIEnv *_E, const char *fname,
+ int type)
+{
+ jstring name;
+ if ((name = ACR_NewJavaStringA(_E, fname)))
+ return (*_E)->NewObject(_E, _clazzn.i, J4MID(0001), type);
+ else
+ return NULL;
+}
+
+ACR_DECLARE(jobject) ACR_NewFileInfoObjectW(JNIEnv *_E, const wchar_t *fname,
+ int type)
+{
+ jstring name;
+ if ((name = ACR_NewJavaStringW(_E, fname)))
+ return (*_E)->NewObject(_E, _clazzn.i, J4MID(0001), type);
+ else
+ return NULL;
+}
+
+static void _fill0(ACR_JNISTDARGS, BY_HANDLE_FILE_INFORMATION *info)
+{
+ acr_time_t time;
+ ULARGE_INTEGER u;
+
+ SET_IFIELD_I(0003, _O, info->nNumberOfLinks);
+ u.LowPart = info->nFileSizeLow;
+ u.HighPart = info->nFileSizeHigh;
+ SET_IFIELD_J(0004, _O, u.QuadPart);
+ SET_IFIELD_J(0005, _O, u.QuadPart);
+ FileTimeToMsecTime(&time, &info->ftLastAccessTime);
+ SET_IFIELD_J(0006, _O, time);
+ FileTimeToMsecTime(&time, &info->ftLastWriteTime);
+ SET_IFIELD_J(0007, _O, time);
+ FileTimeToMsecTime(&time, &info->ftCreationTime);
+ SET_IFIELD_J(0008, _O, time);
+ u.LowPart = info->nFileIndexLow;
+ u.HighPart = info->nFileIndexHigh;
+ u.QuadPart += ((UINT64)info->dwVolumeSerialNumber << 30);
+ SET_IFIELD_J(0011, _O, u.QuadPart);
+ SET_IFIELD_J(0012, _O, info->dwVolumeSerialNumber);
+
+}
+
+extern PSID acr_everyone_sid;
+
+/* Left bit shifts from World scope to given scope */
+typedef enum prot_scope_e {
+ prot_scope_world = 0,
+ prot_scope_group = 4,
+ prot_scope_user = 8
+} prot_scope_e;
+
+static int convert_prot(ACCESS_MASK acc, prot_scope_e scope)
+{
+ /* These choices are based on the single filesystem bit that controls
+ * the given behavior. They are -not- recommended for any set protection
+ * function, such a function should -set- use GENERIC_READ/WRITE/EXECUTE
+ */
+ int prot = 0;
+ if (acc & FILE_EXECUTE)
+ prot |= ACR_FPROT_WEXECUTE;
+ if (acc & FILE_WRITE_DATA)
+ prot |= ACR_FPROT_WWRITE;
+ if (acc & FILE_READ_DATA)
+ prot |= ACR_FPROT_WREAD;
+ return (prot << scope);
+}
+
+static int resolve_prot(PSID user, PSID group, PACL dacl)
+{
+ TRUSTEE_W ident = { NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID };
+ ACCESS_MASK acc;
+ int protection = 0;
+ /*
+ * This function is only invoked for WinNT,
+ * there is no reason for os_level testing here.
+ */
+ if (user) {
+ ident.TrusteeType = TRUSTEE_IS_USER;
+ ident.ptstrName = user;
+ /* GetEffectiveRightsFromAcl isn't supported under Win9x,
+ * which shouldn't come as a surprize. Since we are passing
+ * TRUSTEE_IS_SID, always skip the A->W layer.
+ */
+ if (GetEffectiveRightsFromAclW(dacl, &ident, &acc) == ERROR_SUCCESS) {
+ protection |= convert_prot(acc, prot_scope_user);
+ }
+ }
+ /* Windows NT: did not return group rights.
+ * Windows 2000 returns group rights information.
+ * Since WinNT kernels don't follow the unix model of
+ * group associations, this all all pretty mute.
+ */
+ if (group) {
+ ident.TrusteeType = TRUSTEE_IS_GROUP;
+ ident.ptstrName = group;
+ if (GetEffectiveRightsFromAclW(dacl, &ident, &acc) == ERROR_SUCCESS) {
+ protection |= convert_prot(acc, prot_scope_group);
+ }
+ }
+ if (acr_everyone_sid) {
+ ident.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+ ident.ptstrName = acr_everyone_sid;
+ if (GetEffectiveRightsFromAclW(dacl, &ident, &acc) == ERROR_SUCCESS) {
+ protection |= convert_prot(acc, prot_scope_world);
+ }
+ }
+ return protection;
+}
+
+static int _fill1(ACR_JNISTDARGS, HANDLE ih, DWORD attrs, jboolean full)
+{
+ int rc;
+ int prot;
+ PSID usr = NULL;
+ PSID grp = NULL;
+ PACL acl = NULL;
+ SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
+ PSECURITY_DESCRIPTOR sd = NULL;
+
+ if (full)
+ si |= (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION);
+ rc = GetSecurityInfo(ih,
+ SE_FILE_OBJECT,
+ si,
+ full ? &usr : NULL,
+ full ? &grp : NULL,
+ &acl,
+ NULL,
+ &sd);
+ if (rc != ERROR_SUCCESS) {
+ return rc;
+ }
+ if (full) {
+ SET_IFIELD_O(0001, _O, ACR_UserObjectCreateFromId(_E, usr));
+ SET_IFIELD_O(0002, _O, ACR_GroupObjectCreateFromId(_E, grp));
+ }
+ prot = resolve_prot(usr, grp, acl);
+ if (attrs & FILE_ATTRIBUTE_READONLY) {
+ /* Clear any WRITE attributes */
+ prot &= ~ACR_FPROT_UWRITE;
+ prot &= ~ACR_FPROT_GWRITE;
+ prot &= ~ACR_FPROT_WWRITE;
+ }
+ if (attrs & FILE_ATTRIBUTE_HIDDEN) {
+ /* XXX: Hidden files are non-executable? */
+ prot &= ~ACR_FPROT_UEXECUTE;
+ prot &= ~ACR_FPROT_GEXECUTE;
+ prot &= ~ACR_FPROT_WEXECUTE;
+ }
+ SET_IFIELD_I(0000, _O, prot);
+
+ LocalFree(sd);
+ return 0;
+}
+
+static int _ftype0(DWORD attrs)
+{
+ int type = ACR_FT_REG;
+
+ if (attrs & FILE_ATTRIBUTE_DIRECTORY)
+ type = ACR_FT_DIR;
+ else if (attrs & FILE_ATTRIBUTE_REPARSE_POINT)
+ type = ACR_FT_LNK;
+ else if (attrs & FILE_ATTRIBUTE_DEVICE)
+ type = ACR_FT_CHR;
+ return type;
+}
+
+static jobject _stat0(JNIEnv *_E, const wchar_t *fname,
+ jboolean link, jboolean full)
+{
+ jobject fi;
+ BY_HANDLE_FILE_INFORMATION info;
+ HANDLE ih;
+ int rc = 0;
+ int type;
+
+ ih = CreateFileW(fname,
+ 0, /* Query attributes without accessing the file */
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+ if (IS_INVALID_HANDLE(ih)) {
+ ACR_THROW_IO_ERRNO();
+ return NULL;
+ }
+ if (!GetFileInformationByHandle(ih, &info)) {
+ rc = ACR_GET_OS_ERROR();
+ goto finally;
+ }
+ type = _ftype0(info.dwFileAttributes);
+
+ fi = (*_E)->NewObject(_E, _clazzn.i, J4MID(0000), type);
+ if (!fi) {
+ CloseHandle(ih);
+ return NULL;
+ }
+ if (full) {
+ /* Resolve full path name
+ */
+ wchar_t *path;
+ wchar_t *name = acr_GetAbsolutePath(_E, ih, fname);
+ SET_IFIELD_W(0009, fi, name);
+ if ((path = wcsrchr(name, L'\\')))
+ SET_IFIELD_W(0010, fi, path);
+ else {
+ if ((path = wcsrchr(name, L'/')))
+ SET_IFIELD_W(0010, fi, path);
+ else
+ SET_IFIELD_W(0010, fi, name);
+ }
+ x_free(name);
+ }
+ _fill0(_E, fi, &info);
+ rc = _fill1(_E, fi, ih, info.dwFileAttributes, full);
+
+finally:
+ CloseHandle(ih);
+ if (rc) {
+ ACR_THROW_IO_IF_ERR(rc);
+ fi = NULL;
+ }
+ return fi;
+}
+
+static jobject _stat1(JNIEnv *_E, int file, jboolean full)
+{
+ jobject fi;
+ BY_HANDLE_FILE_INFORMATION info;
+ int rc = 0;
+ int type;
+ acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file);
+
+ if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) {
+ ACR_THROW_IO_IF_ERR(ACR_EFTYPE);
+ return NULL;
+ }
+ if (IS_INVALID_HANDLE(f)) {
+ ACR_THROW_IO_IF_ERR(ACR_EBADF);
+ return NULL;
+ }
+
+
+ if (!GetFileInformationByHandle(f->fd, &info)) {
+ rc = ACR_GET_OS_ERROR();
+ goto finally;
+ }
+ type = _ftype0(info.dwFileAttributes);
+
+ fi = (*_E)->NewObject(_E, _clazzn.i, J4MID(0000), type);
+ if (!fi) {
+ return NULL;
+ }
+ if (full) {
+ /* Resolve base name
+ */
+ wchar_t *path;
+ SET_IFIELD_W(0009, fi, f->name);
+ if ((path = wcsrchr(f->name, L'\\')))
+ SET_IFIELD_W(0010, fi, path + 1);
+ else {
+ if ((path = wcsrchr(f->name, L'/')))
+ SET_IFIELD_W(0010, fi, path + 1);
+ else
+ SET_IFIELD_W(0010, fi, f->name);
+ }
+ }
+ _fill0(_E, fi, &info);
+ rc = _fill1(_E, fi, f->fd, info.dwFileAttributes, full);
+
+finally:
+ if (rc) {
+ ACR_THROW_IO_IF_ERR(rc);
+ fi = NULL;
+ }
+ return fi;
+}
+
+static int _stat2(ACR_JNISTDARGS, const wchar_t *fname, jboolean link)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ HANDLE ih;
+ int rc = 0;
+
+ ih = CreateFileW(fname,
+ 0, /* Query attributes without accessing the file */
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+ if (IS_INVALID_HANDLE(ih)) {
+ return ACR_GET_OS_ERROR();
+ }
+ if (!GetFileInformationByHandle(ih, &info)) {
+ rc = ACR_GET_OS_ERROR();
+ goto finally;
+ }
+ CALL_VMETHOD1(0002, _O, _ftype0(info.dwFileAttributes));
+ _fill0(_E, _O, &info);
+ rc = _fill1(_E, _O, ih, info.dwFileAttributes, JNI_TRUE);
+
+finally:
+ CloseHandle(ih);
+ return rc;
+}
+
+
+ACR_IO_EXPORT_DECLARE(jobject, File, stat0)(ACR_JNISTDARGS,
+ jstring fname,
+ jboolean link,
+ jboolean full)
+{
+ jobject fi = NULL;
+ WITH_WSTR(fname) {
+ fi = _stat0(_E, J2W(fname), link, full);
+ } END_WITH_WSTR(fname);
+
+ return fi;
+}
+
+
+ACR_IO_EXPORT_DECLARE(jint, FileInfo, stat0)(ACR_JNISTDARGS,
+ jstring fname,
+ jboolean link)
+{
+ int rc = 0;
+ WITH_WSTR(fname) {
+ rc = _stat2(_E, _O, J2W(fname), link);
+ } END_WITH_WSTR(fname);
+
+ return rc;
+}
+
+ACR_IO_EXPORT_DECLARE(jobject, FileWrapper, stat0)(ACR_JNISTDARGS,
+ jint fd,
+ jboolean full)
+{
+ return _stat1(_E, fd, full);
+}