JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_checkAccessTokenAccessLevel0()

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);
}