Jump to content
  • Advertisement
Sign in to follow this  
5MinuteGaming

[java] Getting File attributes

This topic is 4650 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This question is a little odd and platform specific but I am stumped on this one. I'm working on Windows XP Professional using JDK 1.1 with JFC Swing 1.1.1 I am trying to get the Windows specific file attribute 'owner' which gives you the account name that last modifed the file which you can access directly using the windows file browser and displaying files details. I would like to be able to access this information using a Java program however the File class to be platform independant does not offer the option of figuring out who the owner of the file is. I'm wondering if anyone here knows a way to access the information and bring it in to a Java Program I would like a function with the following declaration that does the job. public String getOwner( File ); Any help that you can provide is most appreciated! Note: I have posted this in other forums on the internet for java programming just thought I'd check here cause people here seem to know a lot about Java.

Share this post


Link to post
Share on other sites
Advertisement
Well, it doesn't seem to be possible from pure Java. However, you could use JNI to accomplish what you want. You can learn about JNI here.

And here's some relevant Win32 code to find a file's owner.


Finding the Owner of a File Object in C++
The following example uses the GetSecurityInfo and LookupAccountSid functions to find and print the name of the owner of a file. The file exists in the current working directory on the local server.



#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include "accctrl.h"
#include "aclapi.h"

int main(int argc, char **argv)
{
DWORD dwRtnCode = 0;
PSID pSidOwner;
BOOL bRtnBool = TRUE;
LPTSTR AcctName, DomainName;
DWORD dwAcctName = 1, dwDomainName = 1;
SID_NAME_USE eUse = SidTypeUnknown;
HANDLE hFile;
PSECURITY_DESCRIPTOR pSD;

// Get the handle of the file object.
hFile = CreateFile(
"myfile.txt",
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

// Check GetLastError for CreateFile error code.
if (hFile == INVALID_HANDLE_VALUE) {
DWORD dwErrorCode = 0;

dwErrorCode = GetLastError();
_tprintf(TEXT("CreateFile error = %d\n"), dwErrorCode);
return -1;
}

// Allocate memory for the SID structure.
pSidOwner = (PSID)GlobalAlloc(
GMEM_FIXED,
sizeof(PSID));

// Allocate memory for the security descriptor structure.
pSD = (PSECURITY_DESCRIPTOR)GlobalAlloc(
GMEM_FIXED,
sizeof(PSECURITY_DESCRIPTOR));

// Get the owner SID of the file.
dwRtnCode = GetSecurityInfo(
hFile,
SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION,
&pSidOwner,
NULL,
NULL,
NULL,
&pSD);

// Check GetLastError for GetSecurityInfo error condition.
if (dwRtnCode != ERROR_SUCCESS) {
DWORD dwErrorCode = 0;

dwErrorCode = GetLastError();
_tprintf(TEXT("GetSecurityInfo error = %d\n"), dwErrorCode);
return -1;
}

// First call to LookupAccountSid to get the buffer sizes.
bRtnBool = LookupAccountSid(
NULL, // local computer
pSidOwner,
AcctName,
(LPDWORD)&dwAcctName,
DomainName,
(LPDWORD)&dwDomainName,
&eUse);

// Reallocate memory for the buffers.
AcctName = (char *)GlobalAlloc(
GMEM_FIXED,
dwAcctName);

// Check GetLastError for GlobalAlloc error condition.
if (AcctName == NULL) {
DWORD dwErrorCode = 0;

dwErrorCode = GetLastError();
_tprintf(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
return -1;
}

DomainName = (char *)GlobalAlloc(
GMEM_FIXED,
dwDomainName);

// Check GetLastError for GlobalAlloc error condition.
if (DomainName == NULL) {
DWORD dwErrorCode = 0;

dwErrorCode = GetLastError();
_tprintf(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
return -1;

}

// Second call to LookupAccountSid to get the account name.
bRtnBool = LookupAccountSid(
NULL, // name of local or remote computer
pSidOwner, // security identifier
AcctName, // account name buffer
(LPDWORD)&dwAcctName, // size of account name buffer
DomainName, // domain name
(LPDWORD)&dwDomainName, // size of domain name buffer
&eUse); // SID type

// Check GetLastError for LookupAccountSid error condition.
if (bRtnBool == FALSE) {
DWORD dwErrorCode = 0;

dwErrorCode = GetLastError();

if (dwErrorCode == ERROR_NONE_MAPPED)
_tprintf(TEXT("Account owner not found for specified SID.\n"));
else
_tprintf(TEXT("Error in LookupAccountSid.\n"));
return -1;

} else if (bRtnBool == TRUE)

// Print the account name.
_tprintf(TEXT("Account owner = %s\n"), AcctName);

return 0;



Share this post


Link to post
Share on other sites
thanks Optus I had that idea a little while after posting my question. Didn't use JNI though. I could it wouldn't be hard at all but instead I did something a little different.

I wrote another program using the code you provided in C/C++ pretty much just as is except that the programs last line I changed to:

printf(TEXT("%s\n"), AcctName);

So that I don't have to do any String parsing or tokenizing.
Then I wrote the method I wanted as follows:


public static String getOwner( File f ) {

String toRet = null;

//form command string
String cmd[] = new String[2];
cmd[0] = "getOwner ";
cmd[1] = f.getAbsolutePath();

try {

//setup the Process and buffer
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader buffr = new BufferedReader( new InputStreamReader( p.getInputStream() ) );

String line = null;
while( (line = buffr.readLine()) != null ) {
toRet = line;
}

}catch( IOException ioe ) {
System.err.print( "Unknown IO Error in function getOwner(): ");
System.err.println(ioe.getMessage() );
}

return toRet;
}



The application that I created in C/C++ was named getOwner.exe I used the Dev-Cpp IDE with gcc 3.4.2 and the code found from MSDN: Reference Link

The only thing really applicable to games here would be the use of Runtime.exec( String []cmd ) for those that aren't aware of it. For cross platform applications you might want to check the platform and have alternate command line arrays built depending on either Unix script, Batch script, or whatever. Your app also needs security permissions to be able to execute commands. You use the Process class to get the Input, Output, and Err stream of the command line process that you run which also will run independantly of your application.

If someone finds a better way of getting the Owner or other type of file attributes that are platform dependant please let me know.

Share this post


Link to post
Share on other sites
I think the calls to GlobalAlloc should be changed to: GlobalAlloc(GMEM_FIXED, sizeof(SID)) and GlobalAlloc(GMEM_FIXED, sizeof(SECURITY_DESCRIPTOR)).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!