Add WindowsAclFileAttributeViewsTest (Part 2)
This change adds support for faking Windows JNA calls
and uses faked JNA interfaces to test the
WindowsAclFileAttributeViews.getAclViews() method.
TODO: Add tests for Share ACL, and DFS ACLs.
Code Review: http://codereview.appspot.com/82070043
diff --git a/test/com/google/enterprise/adaptor/fs/AclView.java b/test/com/google/enterprise/adaptor/fs/AclView.java
index 233061e..1398e63 100644
--- a/test/com/google/enterprise/adaptor/fs/AclView.java
+++ b/test/com/google/enterprise/adaptor/fs/AclView.java
@@ -173,15 +173,18 @@
return name;
}
+ // This implementation of equals() is a bit unusual, because I may compare
+ // instances of two different implementations of the interface and I do not
+ // want to match GroupPrincipals (which extend UserPrincipals).
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
- if (getClass() != obj.getClass()) {
+ if (!(obj instanceof UserPrincipal) || obj instanceof GroupPrincipal) {
return false;
}
- return name.equals(obj.toString());
+ return getName().equals(((UserPrincipal) obj).getName());
}
}
@@ -189,5 +192,18 @@
Group(String name) {
super(name);
}
+
+ // This implementation of equals() is a bit unusual, because I may compare
+ // instances of two different implementations of the interface.
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof GroupPrincipal)) {
+ return false;
+ }
+ return getName().equals(((GroupPrincipal) obj).getName());
+ }
}
}
diff --git a/test/com/google/enterprise/adaptor/fs/UnsupportedAdvapi32.java b/test/com/google/enterprise/adaptor/fs/UnsupportedAdvapi32.java
new file mode 100644
index 0000000..3af7592
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/UnsupportedAdvapi32.java
@@ -0,0 +1,390 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Licensed 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.
+
+package com.google.enterprise.adaptor.fs;
+
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.WString;
+import com.sun.jna.platform.win32.Advapi32;
+import com.sun.jna.platform.win32.WinBase.FILETIME;
+import com.sun.jna.platform.win32.WinBase.PROCESS_INFORMATION;
+import com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES;
+import com.sun.jna.platform.win32.WinBase.STARTUPINFO;
+import com.sun.jna.platform.win32.WinNT.HANDLE;
+import com.sun.jna.platform.win32.WinNT.HANDLEByReference;
+import com.sun.jna.platform.win32.WinNT.LUID;
+import com.sun.jna.platform.win32.WinNT.PSID;
+import com.sun.jna.platform.win32.WinNT.PSIDByReference;
+import com.sun.jna.platform.win32.WinNT.TOKEN_PRIVILEGES;
+import com.sun.jna.platform.win32.WinReg.HKEY;
+import com.sun.jna.platform.win32.WinReg.HKEYByReference;
+import com.sun.jna.platform.win32.Winsvc.SC_HANDLE;
+import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS;
+import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS_PROCESS;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.LongByReference;
+import com.sun.jna.ptr.PointerByReference;
+
+/**
+ * An Implementation of the Advapi32 Interface that throws
+ * UnsupportedOperationException for everything. Tests may
+ * subclass this and override those methods used by the object
+ * under test.
+ */
+public class UnsupportedAdvapi32 implements Advapi32 {
+
+ @Override
+ public boolean GetUserNameW(char[] buffer, IntByReference len) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean LookupAccountName(String lpSystemName, String lpAccountName,
+ PSID Sid, IntByReference cbSid, char[] ReferencedDomainName,
+ IntByReference cchReferencedDomainName, PointerByReference peUse) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean LookupAccountSid(String lpSystemName, PSID Sid,
+ char[] lpName, IntByReference cchName, char[] ReferencedDomainName,
+ IntByReference cchReferencedDomainName, PointerByReference peUse) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean ConvertSidToStringSid(PSID Sid, PointerByReference StringSid) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean ConvertStringSidToSid(String StringSid, PSIDByReference Sid) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int GetLengthSid(PSID pSid) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean IsValidSid(PSID pSid) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean IsWellKnownSid(PSID pSid, int wellKnownSidType) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean CreateWellKnownSid(int wellKnownSidType, PSID domainSid,
+ PSID pSid, IntByReference cbSid) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean LogonUser(String lpszUsername, String lpszDomain,
+ String lpszPassword, int logonType, int logonProvider,
+ HANDLEByReference phToken) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean OpenThreadToken(HANDLE ThreadHandle, int DesiredAccess,
+ boolean OpenAsSelf, HANDLEByReference TokenHandle) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean OpenProcessToken(HANDLE ProcessHandle, int DesiredAccess,
+ HANDLEByReference TokenHandle) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean DuplicateToken(HANDLE ExistingTokenHandle,
+ int ImpersonationLevel, HANDLEByReference DuplicateTokenHandle) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean DuplicateTokenEx(HANDLE hExistingToken, int dwDesiredAccess,
+ SECURITY_ATTRIBUTES lpTokenAttributes, int ImpersonationLevel,
+ int TokenType, HANDLEByReference phNewToken) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GetTokenInformation(HANDLE tokenHandle,
+ int tokenInformationClass, Structure tokenInformation,
+ int tokenInformationLength, IntByReference returnLength) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean ImpersonateLoggedOnUser(HANDLE hToken) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean ImpersonateSelf(int ImpersonationLevel) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean RevertToSelf() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegOpenKeyEx(HKEY hKey, String lpSubKey, int ulOptions,
+ int samDesired, HKEYByReference phkResult) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved,
+ IntByReference lpType, char[] lpData, IntByReference lpcbData) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved,
+ IntByReference lpType, byte[] lpData, IntByReference lpcbData) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved,
+ IntByReference lpType, IntByReference lpData,
+ IntByReference lpcbData) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved,
+ IntByReference lpType, LongByReference lpData,
+ IntByReference lpcbData) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved,
+ IntByReference lpType, Pointer lpData, IntByReference lpcbData) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegCloseKey(HKEY hKey) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegDeleteValue(HKEY hKey, String lpValueName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegSetValueEx(HKEY hKey, String lpValueName, int Reserved,
+ int dwType, char[] lpData, int cbData) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegSetValueEx(HKEY hKey, String lpValueName, int Reserved,
+ int dwType, byte[] lpData, int cbData) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegCreateKeyEx(HKEY hKey, String lpSubKey, int Reserved,
+ String lpClass, int dwOptions, int samDesired,
+ SECURITY_ATTRIBUTES lpSecurityAttributes,
+ HKEYByReference phkResult, IntByReference lpdwDisposition) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegDeleteKey(HKEY hKey, String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegEnumKeyEx(HKEY hKey, int dwIndex, char[] lpName,
+ IntByReference lpcName, IntByReference reserved, char[] lpClass,
+ IntByReference lpcClass, FILETIME lpftLastWriteTime) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegEnumValue(HKEY hKey, int dwIndex, char[] lpValueName,
+ IntByReference lpcchValueName, IntByReference reserved,
+ IntByReference lpType, byte[] lpData, IntByReference lpcbData) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegQueryInfoKey(HKEY hKey, char[] lpClass,
+ IntByReference lpcClass, IntByReference lpReserved,
+ IntByReference lpcSubKeys, IntByReference lpcMaxSubKeyLen,
+ IntByReference lpcMaxClassLen, IntByReference lpcValues,
+ IntByReference lpcMaxValueNameLen, IntByReference lpcMaxValueLen,
+ IntByReference lpcbSecurityDescriptor,
+ FILETIME lpftLastWriteTime) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int RegGetValue(HKEY hkey, String lpSubKey, String lpValue,
+ int dwFlags, IntByReference pdwType, byte[] pvData,
+ IntByReference pcbData) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HANDLE RegisterEventSource(String lpUNCServerName,
+ String lpSourceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean DeregisterEventSource(HANDLE hEventLog) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HANDLE OpenEventLog(String lpUNCServerName, String lpSourceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean CloseEventLog(HANDLE hEventLog) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GetNumberOfEventLogRecords(HANDLE hEventLog,
+ IntByReference NumberOfRecords) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean ReportEvent(HANDLE hEventLog, int wType, int wCategory,
+ int dwEventID, PSID lpUserSid, int wNumStrings, int dwDataSize,
+ String[] lpStrings, Pointer lpRawData) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean ClearEventLog(HANDLE hEventLog, String lpBackupFileName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean BackupEventLog(HANDLE hEventLog, String lpBackupFileName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HANDLE OpenBackupEventLog(String lpUNCServerName, String lpFileName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean ReadEventLog(HANDLE hEventLog, int dwReadFlags,
+ int dwRecordOffset, Pointer lpBuffer, int nNumberOfBytesToRead,
+ IntByReference pnBytesRead, IntByReference pnMinNumberOfBytesNeeded) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GetOldestEventLogRecord(HANDLE hEventLog,
+ IntByReference OldestRecord) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean QueryServiceStatusEx(SC_HANDLE hService, int InfoLevel,
+ SERVICE_STATUS_PROCESS lpBuffer, int cbBufSize,
+ IntByReference pcbBytesNeeded) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean ControlService(SC_HANDLE hService, int dwControl,
+ SERVICE_STATUS lpServiceStatus) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean StartService(SC_HANDLE hService, int dwNumServiceArgs,
+ String[] lpServiceArgVectors) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean CloseServiceHandle(SC_HANDLE hSCObject) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public SC_HANDLE OpenService(SC_HANDLE hSCManager, String lpServiceName,
+ int dwDesiredAccess) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public SC_HANDLE OpenSCManager(String lpMachineName, String lpDatabaseName,
+ int dwDesiredAccess) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean CreateProcessAsUser(HANDLE hToken, String lpApplicationName,
+ String lpCommandLine, SECURITY_ATTRIBUTES lpProcessAttributes,
+ SECURITY_ATTRIBUTES lpThreadAttributes, boolean bInheritHandles,
+ int dwCreationFlags, String lpEnvironment,
+ String lpCurrentDirectory, STARTUPINFO lpStartupInfo,
+ PROCESS_INFORMATION lpProcessInformation) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean AdjustTokenPrivileges(HANDLE TokenHandle,
+ boolean DisableAllPrivileges, TOKEN_PRIVILEGES NewState,
+ int BufferLength, TOKEN_PRIVILEGES PreviousState,
+ IntByReference ReturnLength) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean LookupPrivilegeName(String lpSystemName, LUID lpLuid,
+ char[] lpName, IntByReference cchName) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public boolean LookupPrivilegeValue(String lpSystemName, String lpName,
+ LUID lpLuid) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GetFileSecurity(WString lpFileName,
+ int RequestedInformation, Pointer pointer, int nLength,
+ IntByReference lpnLengthNeeded) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/UnsupportedKernel32.java b/test/com/google/enterprise/adaptor/fs/UnsupportedKernel32.java
new file mode 100644
index 0000000..4703742
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/UnsupportedKernel32.java
@@ -0,0 +1,509 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Licensed 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.
+
+package com.google.enterprise.adaptor.fs;
+
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.platform.win32.Kernel32;
+import com.sun.jna.platform.win32.Tlhelp32.PROCESSENTRY32;
+import com.sun.jna.platform.win32.WinBase.FILETIME;
+import com.sun.jna.platform.win32.WinBase.OVERLAPPED;
+import com.sun.jna.platform.win32.WinBase.PROCESS_INFORMATION;
+import com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES;
+import com.sun.jna.platform.win32.WinBase.STARTUPINFO;
+import com.sun.jna.platform.win32.WinBase.SYSTEMTIME;
+import com.sun.jna.platform.win32.WinNT.FILE_NOTIFY_INFORMATION;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.LongByReference;
+import com.sun.jna.ptr.PointerByReference;
+
+import java.nio.Buffer;
+
+/**
+ * An implementation of the Kernel32 Interface that throws
+ * UnsupportedOperationException for everything. Tests may
+ * subclass this and override those methods used by the object
+ * under test.
+ */
+public class UnsupportedKernel32 implements Kernel32 {
+
+ @Override
+ public int FormatMessage(int dwFlags, Pointer lpSource, int dwMessageId,
+ int dwLanguageId, Buffer lpBuffer, int nSize, Pointer va_list) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean ReadFile(HANDLE hFile, Buffer lpBuffer,
+ int nNumberOfBytesToRead, IntByReference lpNumberOfBytesRead,
+ OVERLAPPED lpOverlapped) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Pointer LocalFree(Pointer hLocal) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Pointer GlobalFree(Pointer hGlobal) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HMODULE GetModuleHandle(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void GetSystemTime(SYSTEMTIME lpSystemTime) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void GetLocalTime(SYSTEMTIME lpSystemTime) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int GetTickCount() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int GetCurrentThreadId() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HANDLE GetCurrentThread() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int GetCurrentProcessId() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HANDLE GetCurrentProcess() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int GetProcessId(HANDLE process) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int GetProcessVersion(int processId) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GetExitCodeProcess(HANDLE hProcess,
+ IntByReference lpExitCode) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean TerminateProcess(HANDLE hProcess, int uExitCode) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int GetLastError() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void SetLastError(int dwErrCode) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int GetDriveType(String lpRootPathName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int FormatMessage(int dwFlags, Pointer lpSource, int dwMessageId,
+ int dwLanguageId, Pointer lpBuffer, int nSize, Pointer va_list) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int FormatMessage(int dwFlags, Pointer lpSource, int dwMessageId,
+ int dwLanguageId, PointerByReference lpBuffer, int nSize,
+ Pointer va_list) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HANDLE CreateFile(String lpFileName, int dwDesiredAccess,
+ int dwShareMode, SECURITY_ATTRIBUTES lpSecurityAttributes,
+ int dwCreationDisposition, int dwFlagsAndAttributes,
+ HANDLE hTemplateFile) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean CopyFile(String lpExistingFileName, String lpNewFileName,
+ boolean bFailIfExists) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean MoveFile(String lpExistingFileName, String lpNewFileName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean MoveFileEx(String lpExistingFileName, String lpNewFileName,
+ DWORD dwFlags) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean CreateDirectory(String lpPathName,
+ SECURITY_ATTRIBUTES lpSecurityAttributes) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean ReadFile(HANDLE hFile, Pointer lpBuffer,
+ int nNumberOfBytesToRead, IntByReference lpNumberOfBytesRead,
+ OVERLAPPED lpOverlapped) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HANDLE CreateIoCompletionPort(HANDLE FileHandle,
+ HANDLE ExistingCompletionPort, Pointer CompletionKey,
+ int NumberOfConcurrentThreads) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GetQueuedCompletionStatus(HANDLE CompletionPort,
+ IntByReference lpNumberOfBytes,
+ ULONG_PTRByReference lpCompletionKey,
+ PointerByReference lpOverlapped, int dwMilliseconds) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean PostQueuedCompletionStatus(HANDLE CompletionPort,
+ int dwNumberOfBytesTransferred, Pointer dwCompletionKey,
+ OVERLAPPED lpOverlapped) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int WaitForSingleObject(HANDLE hHandle, int dwMilliseconds) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int WaitForMultipleObjects(int nCount, HANDLE[] hHandle,
+ boolean bWaitAll, int dwMilliseconds) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean DuplicateHandle(HANDLE hSourceProcessHandle,
+ HANDLE hSourceHandle, HANDLE hTargetProcessHandle,
+ HANDLEByReference lpTargetHandle,
+ int dwDesiredAccess, boolean bInheritHandle, int dwOptions) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean CloseHandle(HANDLE hObject) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean ReadDirectoryChangesW(HANDLE directory,
+ FILE_NOTIFY_INFORMATION info, int length,
+ boolean watchSubtree, int notifyFilter,
+ IntByReference bytesReturned, OVERLAPPED overlapped,
+ OVERLAPPED_COMPLETION_ROUTINE completionRoutine) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int GetShortPathName(String lpszLongPath, char[] lpdzShortPath,
+ int cchBuffer) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Pointer LocalAlloc(int uFlags, int uBytes) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean WriteFile(HANDLE hFile, byte[] lpBuffer,
+ int nNumberOfBytesToWrite, IntByReference lpNumberOfBytesWritten,
+ OVERLAPPED lpOverlapped) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HANDLE CreateEvent(SECURITY_ATTRIBUTES lpEventAttributes,
+ boolean bManualReset, boolean bInitialState, String lpName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean SetEvent(HANDLE hEvent) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean PulseEvent(HANDLE hEvent) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HANDLE CreateFileMapping(HANDLE hFile,
+ SECURITY_ATTRIBUTES lpAttributes, int flProtect,
+ int dwMaximumSizeHigh, int dwMaximumSizeLow, String lpName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Pointer MapViewOfFile(HANDLE hFileMappingObject, int dwDesiredAccess,
+ int dwFileOffsetHigh, int dwFileOffsetLow, int dwNumberOfBytesToMap) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean UnmapViewOfFile(Pointer lpBaseAddress) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GetComputerName(char[] buffer, IntByReference lpnSize) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HANDLE OpenThread(int dwDesiredAccess, boolean bInheritHandle,
+ int dwThreadId) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean CreateProcess(String lpApplicationName, String lpCommandLine,
+ SECURITY_ATTRIBUTES lpProcessAttributes,
+ SECURITY_ATTRIBUTES lpThreadAttributes,
+ boolean bInheritHandles, DWORD dwCreationFlags,
+ Pointer lpEnvironment, String lpCurrentDirectory,
+ STARTUPINFO lpStartupInfo,
+ PROCESS_INFORMATION lpProcessInformation) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean CreateProcessW(String lpApplicationName, char[] lpCommandLine,
+ SECURITY_ATTRIBUTES lpProcessAttributes,
+ SECURITY_ATTRIBUTES lpThreadAttributes,
+ boolean bInheritHandles, DWORD dwCreationFlags,
+ Pointer lpEnvironment, String lpCurrentDirectory,
+ STARTUPINFO lpStartupInfo,
+ PROCESS_INFORMATION lpProcessInformation) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HANDLE OpenProcess(int fdwAccess, boolean fInherit, int IDProcess) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public DWORD GetTempPath(DWORD nBufferLength, char[] buffer) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public DWORD GetVersion() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GetVersionEx(OSVERSIONINFO lpVersionInfo) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GetVersionEx(OSVERSIONINFOEX lpVersionInfo) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void GetSystemInfo(SYSTEM_INFO lpSystemInfo) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void GetNativeSystemInfo(SYSTEM_INFO lpSystemInfo) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean IsWow64Process(HANDLE hProcess, IntByReference Wow64Process) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GetLogicalProcessorInformation(Pointer buffer,
+ DWORDByReference returnLength) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GlobalMemoryStatusEx(MEMORYSTATUSEX lpBuffer) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GetFileTime(HANDLE hFile, FILETIME lpCreationTime,
+ FILETIME lpLastAccessTime, FILETIME lpLastWriteTime) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int SetFileTime(HANDLE hFile, FILETIME lpCreationTime,
+ FILETIME lpLastAccessTime, FILETIME lpLastWriteTime) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean SetFileAttributes(String lpFileName, DWORD dwFileAttributes) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public DWORD GetLogicalDriveStrings(DWORD nBufferLength, char[] lpBuffer) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GetDiskFreeSpaceEx(String lpDirectoryName,
+ LARGE_INTEGER lpFreeBytesAvailable,
+ LARGE_INTEGER lpTotalNumberOfBytes,
+ LARGE_INTEGER lpTotalNumberOfFreeBytes) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean DeleteFile(String filename) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean CreatePipe(HANDLEByReference hReadPipe,
+ HANDLEByReference hWritePipe, SECURITY_ATTRIBUTES lpPipeAttributes,
+ int nSize) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean SetHandleInformation(HANDLE hObject, int dwMask, int dwFlags) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int GetFileAttributes(String lpFileName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int GetFileType(HANDLE hFile) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean DeviceIoControl(HANDLE hDevice, int dwIoControlCode,
+ Pointer lpInBuffer, int nInBufferSize, Pointer lpOutBuffer,
+ int nOutBufferSize, IntByReference lpBytesReturned,
+ Pointer lpOverlapped) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean GetDiskFreeSpaceEx(String lpDirectoryName,
+ LongByReference lpFreeBytesAvailable,
+ LongByReference lpTotalNumberOfBytes,
+ LongByReference lpTotalNumberOfFreeBytes) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HANDLE CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean Process32First(HANDLE hSnapshot, PROCESSENTRY32 lppe) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean Process32Next(HANDLE hSnapshot, PROCESSENTRY32 lppe) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean SetEnvironmentVariable(String lpName, String lpValue) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int GetEnvironmentVariable(String lpName, char[] lpBuffer, int nSize) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public LCID GetSystemDefaultLCID() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public LCID GetUserDefaultLCID() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int GetPrivateProfileInt(String appName, String keyName,
+ int defaultValue, String fileName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public DWORD GetPrivateProfileString(String lpAppName, String lpKeyName,
+ String lpDefault, char[] lpReturnedString, DWORD nSize,
+ String lpFileName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean WritePrivateProfileString(String lpAppName, String lpKeyName,
+ String lpString, String lpFileName) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViewsTest.java b/test/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViewsTest.java
index 2b87cbe..8852150 100644
--- a/test/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViewsTest.java
+++ b/test/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViewsTest.java
@@ -14,25 +14,54 @@
package com.google.enterprise.adaptor.fs;
+import static com.google.enterprise.adaptor.fs.AclView.user;
+import static com.google.enterprise.adaptor.fs.AclView.group;
+import static com.google.enterprise.adaptor.fs.AclView.GenericPermission.*;
+
import static org.junit.Assert.*;
import static org.junit.Assume.*;
+import static java.nio.file.attribute.AclEntryFlag.*;
+import static java.nio.file.attribute.AclEntryPermission.*;
+import static java.nio.file.attribute.AclEntryType.*;
+
+import com.google.common.base.Preconditions;
+
+import com.google.enterprise.adaptor.fs.WinApi.Netapi32Ex;
+import com.google.enterprise.adaptor.fs.WinApi.Shlwapi;
+
import org.junit.*;
import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import com.sun.jna.Memory;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.WString;
+import com.sun.jna.platform.win32.Advapi32;
import com.sun.jna.platform.win32.Advapi32Util.Account;
+import com.sun.jna.platform.win32.Kernel32;
+import com.sun.jna.platform.win32.W32Errors;
import com.sun.jna.platform.win32.Win32Exception;
import com.sun.jna.platform.win32.WinError;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.platform.win32.WinNT.SID_NAME_USE;
+import com.sun.jna.ptr.IntByReference;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.attribute.AclEntry;
import java.nio.file.attribute.AclEntryFlag;
import java.nio.file.attribute.AclEntryPermission;
import java.nio.file.attribute.AclEntryType;
+import java.nio.file.attribute.AclFileAttributeView;
import java.nio.file.attribute.GroupPrincipal;
import java.nio.file.attribute.UserPrincipal;
+import java.util.Arrays;
import java.util.EnumSet;
+import java.util.List;
import java.util.Set;
/** Tests for {@link WindowsAclFileAttributeViews} */
@@ -41,12 +70,36 @@
private final WindowsAclFileAttributeViews wafav =
new TestAclFileAttributeViews();
+ private Path tempRoot;
+
@Rule
public ExpectedException thrown = ExpectedException.none();
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Before
+ public void setUp() throws Exception {
+ tempRoot = temp.getRoot().getCanonicalFile().toPath();
+ }
+
+ private Path newTempDir(String name) throws IOException {
+ return temp.newFolder(name).toPath().toRealPath();
+ }
+
+ private Path newTempFile(String name) throws IOException {
+ return temp.newFile(name).toPath().toRealPath();
+ }
+
+ private Path newTempFile(Path parent, String name) throws IOException {
+ Preconditions.checkArgument(parent.startsWith(tempRoot));
+ return Files.createFile(parent.resolve(name));
+ }
+
@Test
public void testNewAclEntryUnsupportedAccessType() throws Exception {
WinNT.ACCESS_ACEStructure ace = new AceBuilder()
+ .setSid(new AccountSid())
.setType(WinNT.SYSTEM_AUDIT_ACE_TYPE).build();
assertNull(wafav.newAclEntry(ace));
}
@@ -55,7 +108,7 @@
public void testNewAclEntryUnresolvableSid() throws Exception {
TestHelper.assumeOsIsWindows(); // For new Win32Exception().
WinNT.ACCESS_ACEStructure ace = new AceBuilder()
- .setSid(new AccountSid(null)).build();
+ .setSid(new AccountSid()).build();
assertNull(wafav.newAclEntry(ace));
}
@@ -227,60 +280,262 @@
assertEquals(expected, aclEntry.flags());
}
+ @Test
+ public void testGetAclViewsEmptyAcl() throws Exception {
+ AclFileAttributeViews aclViews = getAclViews();
+ assertNotNull(aclViews);
+ assertTrue(aclViews.getDirectAclView().getAcl().isEmpty());
+ assertTrue(aclViews.getInheritedAclView().getAcl().isEmpty());
+ }
+
+ @Test
+ public void testGetAclViewsSingleDirectAce() throws Exception {
+ AclFileAttributeView expected = new AclView(
+ user("domain\\user").type(ALLOW).perms(GENERIC_READ)
+ .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+ WinNT.ACCESS_ACEStructure ace = new AceBuilder()
+ .setSid(AccountSid.user("user", "domain"))
+ .setPerms(WinNT.GENERIC_READ)
+ .setFlags(WinNT.OBJECT_INHERIT_ACE, WinNT.CONTAINER_INHERIT_ACE)
+ .build();
+ AclFileAttributeViews aclViews = getAclViews(ace);
+ assertNotNull(aclViews);
+ assertTrue(aclViews.getInheritedAclView().getAcl().isEmpty());
+ assertEquals(expected.getAcl(), aclViews.getDirectAclView().getAcl());
+ }
+
+ @Test
+ public void testGetAclViewsSingleInheritedAce() throws Exception {
+ AclFileAttributeView expected = new AclView(
+ user("domain\\user").type(ALLOW).perms(GENERIC_READ)
+ .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+ WinNT.ACCESS_ACEStructure ace = new AceBuilder()
+ .setSid(AccountSid.user("user", "domain"))
+ .setPerms(WinNT.GENERIC_READ)
+ .setFlags(WinNT.OBJECT_INHERIT_ACE, WinNT.CONTAINER_INHERIT_ACE,
+ WinNT.INHERITED_ACE)
+ .build();
+ AclFileAttributeViews aclViews = getAclViews(ace);
+ assertNotNull(aclViews);
+ assertTrue(aclViews.getDirectAclView().getAcl().isEmpty());
+ assertEquals(expected.getAcl(), aclViews.getInheritedAclView().getAcl());
+ }
+
+ @Test
+ public void testGetAclViewsInheritedAndDirectAces() throws Exception {
+ AclFileAttributeView expectedInherited = new AclView(
+ group("Everyone").type(ALLOW).perms(GENERIC_READ)
+ .flags(FILE_INHERIT, DIRECTORY_INHERIT),
+ group("Administrators").type(ALLOW).perms(GENERIC_ALL)
+ .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+ AclFileAttributeView expectedDirect = new AclView(
+ user("BEDROCK\\Fred").type(ALLOW).perms(GENERIC_EXECUTE)
+ .flags(FILE_INHERIT),
+ user("BEDROCK\\Barney").type(DENY).perms(GENERIC_WRITE)
+ .flags(DIRECTORY_INHERIT));
+ AclFileAttributeViews aclViews = getAclViews(new AceBuilder()
+ .setSid(AccountSid.user("Fred", "BEDROCK"))
+ .setPerms(WinNT.GENERIC_EXECUTE)
+ .setFlags(WinNT.OBJECT_INHERIT_ACE)
+ .build(),
+ new AceBuilder()
+ .setSid(AccountSid.group("Everyone", null))
+ .setPerms(WinNT.GENERIC_READ)
+ .setFlags(WinNT.OBJECT_INHERIT_ACE, WinNT.CONTAINER_INHERIT_ACE,
+ WinNT.INHERITED_ACE)
+ .build(),
+ new AceBuilder()
+ .setSid(AccountSid.group("Administrators", null))
+ .setPerms(WinNT.GENERIC_ALL)
+ .setFlags(WinNT.OBJECT_INHERIT_ACE, WinNT.CONTAINER_INHERIT_ACE,
+ WinNT.INHERITED_ACE)
+ .build(),
+ new AceBuilder()
+ .setSid(AccountSid.user("Barney", "BEDROCK"))
+ .setType(WinNT.ACCESS_DENIED_ACE_TYPE)
+ .setPerms(WinNT.GENERIC_WRITE)
+ .setFlags(WinNT.CONTAINER_INHERIT_ACE)
+ .build());
+
+ assertNotNull(aclViews);
+ assertEquals(expectedDirect.getAcl(), aclViews.getDirectAclView().getAcl());
+ assertEquals(expectedInherited.getAcl(),
+ aclViews.getInheritedAclView().getAcl());
+ }
+
+ private AclFileAttributeViews getAclViews(WinNT.ACCESS_ACEStructure... aces)
+ throws Exception {
+ WinNT.ACL acl = new WinNT.ACL();
+ WinNT.SECURITY_DESCRIPTOR_RELATIVE securityDescriptor =
+ new WinNT.SECURITY_DESCRIPTOR_RELATIVE();
+ int totalSize = securityDescriptor.size() + acl.size();
+ for (WinNT.ACCESS_ACEStructure ace : aces) {
+ totalSize += ace.AceSize;
+ }
+
+ // Serialize the structures into a buffer.
+ final byte[] buffer = new byte[totalSize];
+ int offset = 0;
+ // The start of the ACL follows the securityDescriptor in memory.
+ securityDescriptor.Dacl = securityDescriptor.size();
+ securityDescriptor.write();
+ securityDescriptor.getPointer().read(0, buffer, offset,
+ securityDescriptor.size());
+ offset += securityDescriptor.size();
+ acl.AceCount = (short) aces.length;
+ acl.write();
+ acl.getPointer().read(0, buffer, offset, acl.size());
+ offset += acl.size();
+ for (WinNT.ACCESS_ACEStructure ace : aces) {
+ ace.write();
+ ace.getPointer().read(0, buffer, offset, ace.AceSize);
+ offset += ace.AceSize;
+ }
+
+ Kernel32 kernel32 = new UnsupportedKernel32() {
+ @Override
+ public int GetLastError() {
+ // For when GetFileSecurity returns false.
+ return W32Errors.ERROR_INSUFFICIENT_BUFFER;
+ }
+ };
+ Advapi32 advapi32 = new UnsupportedAdvapi32() {
+ @Override
+ public boolean GetFileSecurity(WString lpFileName,
+ int RequestedInformation, Pointer pointer, int nLength,
+ IntByReference lpnLengthNeeded) {
+ if (nLength < buffer.length) {
+ lpnLengthNeeded.setValue(buffer.length);
+ return false;
+ } else {
+ pointer.write(0, buffer, 0, nLength);
+ return true;
+ }
+ }
+ };
+
+ WindowsAclFileAttributeViews wafav =
+ new TestAclFileAttributeViews(advapi32, kernel32, null, null, null);
+ return wafav.getAclViews(newTempFile("test"));
+ }
+
+ /**
+ * Test the first IOException that can be thrown out of getFileSecurity().
+ * In that method, the first call to advapi32.GetFileSecurity() is
+ * expected to return W32Errors.ERROR_INSUFFICIENT_BUFFER and the
+ * required buffer size. This test returns a different error, which
+ * gets rethrown as an IOException.
+ */
+ @Test
+ public void testGetAclViewsException1() throws Exception {
+ TestHelper.assumeOsIsWindows(); // For new Win32Exception().
+ thrown.expect(IOException.class);
+ testGetAclViewsException(W32Errors.ERROR_MORE_DATA);
+ }
+
+ /**
+ * Test the second IOException that can be thrown out of getFileSecurity().
+ * In that method, the second call to advapi32.GetFileSecurity() is
+ * not expected to return any error. This test returns an error on both
+ * calls - the expected error for the first call and that same error for the
+ * second call.
+ */
+ @Test
+ public void testGetAclViewsException2() throws Exception {
+ TestHelper.assumeOsIsWindows(); // For new Win32Exception().
+ thrown.expect(IOException.class);
+ testGetAclViewsException(W32Errors.ERROR_INSUFFICIENT_BUFFER);
+ }
+
+ private void testGetAclViewsException(final int errorCode) throws Exception {
+ Kernel32 kernel32 = new UnsupportedKernel32() {
+ @Override
+ public int GetLastError() {
+ return errorCode;
+ }
+ };
+ Advapi32 advapi32 = new UnsupportedAdvapi32() {
+ @Override
+ public boolean GetFileSecurity(WString lpFileName,
+ int RequestedInformation, Pointer pointer, int nLength,
+ IntByReference lpnLengthNeeded) {
+ lpnLengthNeeded.setValue(10);
+ return false;
+ }
+ };
+ WindowsAclFileAttributeViews wafav =
+ new TestAclFileAttributeViews(advapi32, kernel32, null, null, null);
+ wafav.getAclViews(newTempFile("test"));
+ }
+
static class AceBuilder {
- private Ace ace = new Ace();
+ private byte type;
+ private byte flags;
+ private int perms;
+ private AccountSid sid;
public AceBuilder setType(byte type) {
- ace.AceType = type;
+ this.type = type;
return this;
}
public AceBuilder setFlags(byte... flags) {
for (byte flag : flags) {
- ace.AceFlags |= flag;
+ this.flags |= flag;
}
return this;
}
public AceBuilder setPerms(int... perms) {
for (int perm : perms) {
- ace.Mask |= perm;
+ this.perms |= perm;
}
return this;
}
- public AceBuilder setSid(WinNT.PSID sid) {
- ace.setSID(sid);
+ public AceBuilder setSid(AccountSid sid) {
+ this.sid = sid;
return this;
}
public WinNT.ACCESS_ACEStructure build() {
+ // Because ACCESS_ACEStructure does not allow me to set the SID
+ // directly, I must create a serialized ACE containing a Pointer
+ // to my AccountSid, then create a new ACE from that memory.
+ WinNT.ACCESS_ACEStructure ace = new Ace();
+ ace.AceType = type;
+ ace.AceFlags = flags;
+ ace.Mask = perms;
+ ace.AceSize = (short)(ace.size() + Pointer.SIZE);
+ ace.write();
+ byte[] buffer = new byte[ace.AceSize];
+ ace.getPointer().read(0, buffer, 0, ace.size());
+ Memory memory = new Memory(buffer.length);
+ memory.write(0, buffer, 0, ace.size());
+ sid.write();
+ // See ACCESS_ACEStructure(Pointer p) constructor for mystery offsets.
+ memory.setPointer(4 + 4, sid.getPointer());
+ ace = new Ace(memory);
+ assertEquals(ace.getSID().sid, sid.getPointer());
return ace;
}
}
static class Ace extends WinNT.ACCESS_ACEStructure {
- // psid is not publicly settable in ACCESS_ACEStructure.
- private WinNT.PSID sid;
-
- public void setSID(WinNT.PSID sid) {
- this.sid = sid;
+ public Ace() {
}
- @Override
- public WinNT.PSID getSID() {
- return (sid != null) ? sid : super.getSID();
+ public Ace(Pointer p) {
+ super(p);
}
@Override
public String getSidString() {
- return (sid != null) ? sid.toString() : super.getSidString();
+ return new AccountSid(getSID().sid).toString();
}
}
- /** A SID implemention that wraps an Account, avoiding AD lookup. */
- static class AccountSid extends WinNT.PSID {
- private final Account account;
+ public static class AccountSid extends Structure {
public static AccountSid user(String name, String domain) {
return new AccountSid(SID_NAME_USE.SidTypeUser, name, domain);
@@ -290,31 +545,47 @@
return new AccountSid(SID_NAME_USE.SidTypeGroup, name, domain);
}
- public AccountSid(Account account) {
- this.account = account;
+ @Override
+ protected List getFieldOrder() {
+ return Arrays.asList(new String[] { "type", "name", "domain" });
+ }
+
+ public int type;
+ public String name;
+ public String domain;
+
+ public AccountSid() {
+ }
+
+ public AccountSid(Pointer p) {
+ super(p);
+ read();
}
public AccountSid(int type, String name, String domain) {
- account = new Account();
- account.accountType = type;
- account.name = name;
- account.domain = domain;
+ this.type = type;
+ this.name = name;
+ this.domain = domain;
}
public Account getAccount() throws Win32Exception {
- if (account == null) {
+ if (name == null && domain == null) {
throw new Win32Exception(WinError.ERROR_NONE_MAPPED);
+ } else {
+ Account account = new Account();
+ account.accountType = type;
+ account.name = name;
+ account.domain = domain;
+ return account;
}
- return account;
}
@Override
public String toString() {
- if (account == null) {
+ if (name == null && domain == null) {
return "null";
} else {
- return (account.domain == null) ? account.name
- : account.domain + "\\" + account.name;
+ return (domain == null) ? name : domain + "\\" + name;
}
}
}
@@ -328,13 +599,14 @@
super(null, null, null, null, null);
}
+ public TestAclFileAttributeViews(Advapi32 advapi32, Kernel32 kernel32,
+ Mpr mpr, Netapi32Ex netapi32, Shlwapi shlwapi) {
+ super(advapi32, kernel32, mpr, netapi32, shlwapi);
+ }
+
@Override
Account getAccountBySid(WinNT.PSID sid) throws Win32Exception {
- if (sid instanceof AccountSid) {
- return ((AccountSid) sid).getAccount();
- } else {
- return super.getAccountBySid(sid);
- }
+ return new AccountSid(sid.sid).getAccount();
}
}
}