Accessing Windows Registry [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
read/write to Windows Registry using Java
I need to access Windows registry from Java.. Also I need to copy some registry entries and may have to enter new registry variables using Java..
some one help me please...

I'd recommend the Java Native Access (JNA) library. It's a pretty nice wrapper around JNI. According to this mailing list post, they've already got a contributed wrapper around the native Windows registry function calls.
If you add the JNA libraries to your project, the relevant source you'll want is the Registry.java class. From there, just call methods on that class to investigate the Windows registry.
As a side note, make sure when you use JNA that you use Platform.isXxx() to make sure your code can actually query the registry on the particular platform.

An example will be like this:
import com.ice.jni.registry.*;
public class DeleteEnvironmentVar{
public DeleteEnvironmentVar(String variable, String value) throws Exception {
RegistryKey machine = Registry.getTopLevelKey("HKEY_LOCAL_MACHINE");
RegistryKey environment = machine.openSubKey("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", RegistryKey.ACCESS_WRITE);
try {
if ( value == null ) { //Delete the variable in case value is empty
environment.deleteValue(variable);
}
}
catch( NoSuchValueException nsve ) {}
catch( NoSuchKeyException nske ) {}
}
}

The Preferences class is the Java preferred way of writing to the registry. However, I haven't actually used it, so I don't know if it allows access to the entire registry or just a section specific to the JVM or your application. If it doesn't, then it sounds like for your purpose you'll be needing to look at the JNI solutions posited by others here. If it does work, then you have a platform-independent method of storing off your settings if you ever port it.

Related

How to use CreateProcessWithTokenW in Java using JNA

We are using createProcessAsUser function to create a child process running in the context of logged in/Impersonated user using waffle and JNA libraries.
But we need to load the user profile after the impersonation, but the LoadUserProfile function is not available in a JNA library.
As we found that CreateProcessWithTokenW is capable of loading the user profile. But this function also not available in the JNA/Waffle library.
Could anyone help us how to load the user profile or how to use the CreateProcessWithTokenW in Java application.
To use CreateProcessWithTokenW from java with JNA you need to bind the function. JNA is just a layer, that makes it possible to call directly native library functions. For this to work JNA uses java descriptions of the native interface, which are then used to do the actual call.
The jna-platform contrib project (released together with the main project) contains a big number of already bound win32 functions and indeed in Advapi32.java there are already bindings for CreateProcessAsUser and CreateProcessWithLogonW. Based on that I would try this (UNTESTED!):
public interface Advapi32Ext extends StdCallLibrary {
Advapi32Ext INSTANCE = Native.load("Advapi32", Advapi32Ext.class, W32APIOptions.DEFAULT_OPTIONS);
boolean CreateProcessWithToken(
HANDLE hToken,
int dwLogonFlags,
String lpApplicationName,
String lpCommandLine,
int dwCreationFlags,
Pointer lpEnvironment,
String lpCurrentDirectory,
STARTUPINFO lpStartupInfo,
PROCESS_INFORMATION lpProcessInfo
);
}
This assumes that you run with the system property w32.ascii set to false or unset, which is the recommend setup. In that case the W32APIFunctionMapper.UNICODE is used, which appends the "W" suffix automatically. The then also selected W32APITypeMapper.UNICODE ensures, that java String objects are mapped to wchars or in case of a function call to LP*WSTR.

How does a native calling application get a return value from JNLP?

I am launching a JNLP java application from a native client app (i.e. not a browser). When the JNLP finishes it's task, I need it to return a string to the calling app? How can I do this? Is it possible to return a value to a calling app - or do I need to have the calling app listen on a port and have the JNLP app write the value to that port through sockets?
Answering my own question!
I write to stdout from the child process (the JNLP)
The parent launches the child process
Process::Start
Read stdout from Parent
string ret = process.StandardOutput.ReadToEnd();
Process::WaitForExit();
Anyone sees any problem in this?
I like your idea to use sockets and think this is could be an easy solution.
It is not possible to get return values from a WebStart-application. Just see the help message from
javaws --help
There is no return-code available. (Sorry)
Have you thougth on a temporary file instead of the sockets?
It's a bit old but as fas as i know this is the exiting options to intercommunicate two process link.
I think the easiest way to solve your problem is use rmi, or jmx if you can, or just a simple socket
If the all-permissions element is specified, you could try to set an environment variable which you can read from your C# application.
Set environment variable in Java:
System.getenv().put("returnValue", "yourValue");
Read environment variable in C#:
ProcessStartInfo p = new ProcessStartInfo("start ....");
....
string returnValue = p.EnvironmentVariables["returnValue"];

Java Create Undeletable File

Is there any method to create a file in java that cannot be deleted.
I have googled it and found processes involving the cmd.
However, I require a pure "java" way that can be done on any platform.
Thanks in advance.
Thank you for your help.
I finally got it right.
I used the following code to deny access to user
public static void main() throws IOException
{
Path file = Paths.get("c:/b.txt");
AclFileAttributeView aclAttr = Files.getFileAttributeView(file, AclFileAttributeView.class);
//System.out.println();
UserPrincipalLookupService upls = file.getFileSystem().getUserPrincipalLookupService();
UserPrincipal user = upls.lookupPrincipalByName(System.getProperty("user.name"));
AclEntry.Builder builder = AclEntry.newBuilder();
builder.setPermissions(EnumSet.of(AclEntryPermission.APPEND_DATA, AclEntryPermission.DELETE, AclEntryPermission.DELETE_CHILD, AclEntryPermission.EXECUTE, AclEntryPermission.READ_ACL, AclEntryPermission.READ_ATTRIBUTES, AclEntryPermission.READ_DATA, AclEntryPermission.READ_NAMED_ATTRS, AclEntryPermission.SYNCHRONIZE, AclEntryPermission.WRITE_ACL, AclEntryPermission.WRITE_ATTRIBUTES, AclEntryPermission.WRITE_DATA, AclEntryPermission.WRITE_NAMED_ATTRS, AclEntryPermission.WRITE_OWNER));
builder.setPrincipal(user);
builder.setType(AclEntryType.DENY);
aclAttr.setAcl(Collections.singletonList(builder.build()));
}
Try the method setPosixFilePermissions() and set the permissions to read only for all the classes of users. Refer this - http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#setPosixFilePermissions%28java.nio.file.Path,%20java.util.Set%29
If you want to create a file that can't be accidentally overwritten, then look at the various answers to this: How do i programmatically change file permissions?
If you want to create a file that the current program cannot delete at all (but a privileged one could), it might be possible by setting permissions appropriately on the parent directory, or possibly using SELinux Mandatory Access Control cleverness.
If you want to create a truly undeleteable file, then you are out of luck. I am not aware of any operating system that supports creation of files that can never be deleted. It would be an "anti-feature".
I would also agree with #Teifi's comment. Create a file that cannot ever be deleted on the user's machine is not acceptable ... unless done by, or with the authorization of the system's administrators. I would call any software that did that "malicious" too.

Using Windows API call in Java using "native"

I've tried to solve this issue by referring possible duplicates but none of them seem to be helpful.
Here's a code that I'm using to call Win API methods in Java to get current Windows User Name, and a native Windows MessageBox, but I'm getting UnsatisfiedLinkError that says that my code is unable to locate the native method I'm trying to call.
public class TestNative
{
public static void main(String[] args)
{
long[] buffer= { 128 };
StringBuffer username = new StringBuffer((int)buffer[0]);
GetUserNameA(username,buffer);
System.out.println("Current User : "+username);
MessageBoxA(0,"UserName : "+username,"Box from Java",0);
}
/** #dll.import("ADVAPI32") */
static native void GetUserNameA(StringBuffer username,long[] buffer);
/** #dll.import("USER32") */
private static native int MessageBoxA(int h,String txt,String title,int style);
}
What can be my possible (relatively simple) solution to call native Windows methods in Java. I realize that it will kill the very reason of Java being a cross-platform language, but I need to work on a project for Windows, to be developed in Java.
Thanks.
Update
As David Heffernan suggested, I've tried changing the method signature of MessageBox to MessageBoxA, but still it's not working.
I would guess it's related to the signatures not matching completely.
The GetUserName function takes two parameters: a LPTSTR and a LPDWORD. Java will likely not handle the StringBuffer acting as a TCHAR array for you.
Also, why bother using the Windows API for this? Java can probably get the user's logon name (quick google says: System.getProperty("user.name")), and Swing can make a message box (even one that looks like a Windows one).
Have you tried https://github.com/twall/jna. I have heard good things and its supposed to make jni that bit easier with many conveniences and simplifications.
Do you have a -Djava.library.path VM arg set with the path to your DLL's? Alternatively, you can have it in your system PATH.
The error is because there is no MessageBox. You presumably mean MessageBoxA.

How to disable Java security manager?

Is there any way to completely disable Java security manager?
I'm experimenting with source code of db4o. It uses reflection to persist objects and it seems that security manager doesn't allow reflection to read and write private or protected fields.
My code:
public static void main(String[] args) throws IOException {
System.out.println("start");
new File( DB_FILE_NAME ).delete();
ObjectContainer container = Db4o.openFile( DB_FILE_NAME );
String ob = new String( "test" );
container.store( ob );
ObjectSet result = container.queryByExample( String.class );
System.out.println( "retrieved (" + result.size() + "):" );
while( result.hasNext() ) {
System.out.println( result.next() );
}
container.close();
System.out.println("finish");
}
Output:
start
[db4o 7.4.68.12069 2009-04-18 00:21:30]
AccessibleObject#setAccessible() is not available. Private fields can not be stored.
retrieved (0):
finish
This thread suggests modifying java.policy file to allow reflection but it doesn't seem to work for me.
I'm starting JVM with arguments
-Djava.security.manager -Djava.security.policy==/home/pablo/.java.policy
so specified policy file will be the only policy file used
The file looks like this:
grant {
permission java.security.AllPermission;
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
};
I spent last 3 hrs on this and don't have any ideas how to make this work.
Any help appreciated.
You could try adding this to the main() of your program:
System.setSecurityManager(null);
Worked for me for a "trusted" WebStart application when I was having security manager issues. Not sure if it will work for your db4o case, but it might be worth a try.
EDIT: I'm not suggesting that this is a general solution to security manager problems. I was just proposing it as a way to help debug the original poster's problem. Clearly, if you want to benefit from a security manager then you should not disable it.
Do you really have two '=' signs in your java.security.policy command line option? That won't work. Make sure you are setting the property as
-Djava.security.policy=/home/pablo/.java.policy
To actually disable the SecurityManager, simply leaving off the java.security.manager system property altogether should be enough.
Update: As I was reading the documentation for policy files to learn more about the "==" syntax, I noticed that unless the policy file is in the current working directory, it needs to be specified as a URL (including scheme). Have you tried prefixing the policy path with the "file:" scheme?
I was also puzzled because (assuming you are running as user "pablo"), it looks like that policy should be loaded by default from your home directory, so you shouldn't need to specify it at all. On the other hand, if you are not running as the user "pablo", maybe the file is not readable.
I found this example of how to make private fields and methods accessible to your code. Basically, it distills down to the use of Field.setAccessible(true) and Method.setAccessible(true)
Field example:
Field privateStringField = PrivateObject.class.
getDeclaredField("privateString");
privateStringField.setAccessible(true);
Method example:
Method privateStringMethod = PrivateObject.class.
getDeclaredMethod("getPrivateString", null);
privateStringMethod.setAccessible(true);
You could also look at using Groovy with your Java code as it (currently) circumvents much of the access level restrictions of Java code. Although, this message board posting seems to suggest this 'feature' may change in future versions of Groovy.

Categories

Resources