in src/main/cpp/jnilib/windows/src/jni_WindowsNativeUtils.c [328:398]
JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_checkAccessTokenAccessLevel0(JNIEnv *jEnv, jobject jObj, jstring jPath, jint jLevel) {
unsigned short * path = getWideChars(jEnv, jPath);
PSECURITY_DESCRIPTOR pSD;
DWORD nLength;
PRIVILEGE_SET PrivilegeSet;
DWORD PrivSetSize = sizeof (PRIVILEGE_SET);
HANDLE hToken;
GENERIC_MAPPING GenericMapping;
DWORD DesiredAccess = (DWORD) jLevel ;
BOOL bAccessGranted;
DWORD GrantedAccess;
// create memory for storing user's security descriptor
GetFileSecurityW(path, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, NULL, 0, &nLength);
pSD = (PSECURITY_DESCRIPTOR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength);
if (pSD == NULL) {
throwException(jEnv, "Unable to allocate memory to store security descriptor.\n");
return -1;
}
// Get the security descriptor
if (!GetFileSecurityW(path, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, pSD, nLength, &nLength)) {
throwException(jEnv, "Unable to obtain security descriptor.\n");
FREE(path);
return (-3);
}
FREE(path);
/* Perform security impersonation of the user and open */
/* the resulting thread token. */
if (!ImpersonateSelf(SecurityImpersonation)) {
throwException(jEnv, "Unable to perform security impersonation.\n");
HeapFree(GetProcessHeap(), 0, pSD);
return (-4);
}
if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, FALSE, &hToken)) {
throwException(jEnv, "Unable to get current thread's token.\n");
HeapFree(GetProcessHeap(), 0, pSD);
return (-5);
}
RevertToSelf();
ZERO(&GenericMapping, sizeof (GENERIC_MAPPING));
DesiredAccess = DesiredAccess | STANDARD_RIGHTS_READ;
GenericMapping.GenericRead = FILE_GENERIC_READ;
if(jLevel & FILE_WRITE_DATA) {
GenericMapping.GenericWrite = FILE_GENERIC_WRITE;
}
MapGenericMask(&DesiredAccess, &GenericMapping);
/* Perform access check using the token. */
if (!AccessCheck(pSD, hToken, DesiredAccess, &GenericMapping, &PrivilegeSet, &PrivSetSize, &GrantedAccess, &bAccessGranted)) {
throwException(jEnv, "Unable to perform access check.\n");
CloseHandle(hToken);
HeapFree(GetProcessHeap(), 0, pSD);
return (-6);
}
/* Clean up. */
HeapFree(GetProcessHeap(), 0, pSD);
CloseHandle(hToken);
return (bAccessGranted);
}