

![]() | Start a set with this search |
![]() | Include this search in one of my sets |
![]() | Exclude this search from one of my sets |
![]() | Permalink to these results Paste this link in email or IM: |
| Atom feed for tracking future search results Paste this URL into your reader: |
7 messages in net.java.dev.jna.usersRe: [jna-users] Finding Access violat...| From | Sent On | Attachments |
|---|---|---|
| Thomas Börkel | May 21, 2008 8:07 am | |
| Timothy Wall | May 22, 2008 1:41 pm | |
| Timothy Wall | May 22, 2008 1:43 pm | |
| Thomas Börkel | May 22, 2008 11:53 pm | |
| Thomas Börkel | May 23, 2008 12:32 am | |
| Timothy Wall | May 23, 2008 6:14 am | |
| Thomas Börkel | May 28, 2008 9:53 pm |

![]() | Permalink for this message Paste this link in email or IM: |
![]() | Permalink for this thread Paste this link in email or IM: |
| Atom feed for this thread Paste this URL into your reader: |
| Subject: | Re: [jna-users] Finding Access violations | Actions... |
|---|---|---|
| From: | Thomas Börkel (tho...@boerkel.de) | |
| Date: | May 23, 2008 12:32:11 am | |
| List: | net.java.dev.jna.users | |
HI!
Timothy Wall wrote:
do { ret = netapi32.NetQueryDisplayInformation(DOMAIN_CONTROLLER_NAME, 3, index, 1000, LMCONS.MAX_PREFERRED_LENGTH, returnedEntries, sortedBuf);
if(ret == WINERROR.NO_ERROR || ret == WINERROR.ERROR_MORE_DATA) { displayGroup = new Netapi32.NET_DISPLAY_GROUP(sortedBuf.getValue()); displayGroups = displayGroup.toArray(returnedEntries.getValue());
for(i = 0; i < returnedEntries.getValue(); i++) { displayGroup = (Netapi32.NET_DISPLAY_GROUP)displayGroups[i]; domainGroups.add(displayGroup.grpi3_name); index = displayGroup.grpi3_next_index; } netapi32.NetApiBufferFree(sortedBuf.getValue());
Here you are freeing native memory without first clearing the Java object which references it. "displayGroup" is depending on the sortedBuf pointer value. You should set displayGroup/displayGroups to null prior to freeing the native memory.
I do not understand quite what that would accomplish. This does not mean that the GC removes the object immediately and on the other hand, I am not using it anymore after freeing it.
Or do I have to make a COPY of displayGroup.grpi3_name for storing in my own TreeSet domainGroups?
I don't think that's the cause of your access exceptions, though. What does grpi3_next_index do? You seem to have removed its actual usage in the code snippet above.
The index is used as a parameter for the next call to NetQueryDisplayInformation() to give the function a new offset for the next batch of groups to return. It returns 100 groups each call and so you can iterate over all groups.
In the meantime, I discovered (by attaching WinDbg to other Java programs, like SwingSet2), that unhandled access violation seem to be normal in Java applications!
The heap corruption, that I got in my application is now gone, after I changed another function:
Old:
----
Declaration: public boolean LookupAccountSid(String lpSystemName, byte[] Sid, char[] lpName, IntByReference cchName, char[] ReferencedDomainName, IntByReference cchReferencedDomainName, PointerByReference peUse);
First method: Advapi32 advapi32; IntByReference cbSid; IntByReference cchReferencedDomainName; PointerByReference peUse;
byte[] sid; char[] referencedDomainName;
advapi32 = Advapi32.INSTANCE;
cbSid = new IntByReference(255); cchReferencedDomainName = new IntByReference(255); sid = new byte[255]; referencedDomainName = new char[255]; peUse = new PointerByReference();
if(advapi32.LookupAccountName(null, account, sid, cbSid, referencedDomainName, cchReferencedDomainName, peUse)) { return(sid); // buffer is longer than actual sid, which may cause problems with next method }
Second method (uses input from first method): PointerByReference stringSid; String sidString = null;
advapi32 = Advapi32.INSTANCE;
stringSid = new PointerByReference();
if(advapi32.ConvertSidToStringSid(sid, stringSid)) { sidString = stringSid.getValue().getString(0, true); Kernel32b.INSTANCE.LocalFree(stringSid.getValue()); } return(sidString);
New:
---- Using IntByReference instead of PointerByReference for peUse and returning a byte[] with the correct length for the second method.
Declaration: public boolean LookupAccountSid(String lpSystemName, byte[] Sid, char[] lpName, IntByReference cchName, char[] ReferencedDomainName, IntByReference cchReferencedDomainName, IntByReference peUse);
First method: Advapi32 advapi32; IntByReference cbSid; IntByReference cchReferencedDomainName; PointerByReference peUse;
byte[] sid; char[] referencedDomainName;
advapi32 = Advapi32.INSTANCE;
cbSid = new IntByReference(255); cchReferencedDomainName = new IntByReference(255); sid = new byte[255]; referencedDomainName = new char[255]; peUse = new PointerByReference();
if(advapi32.LookupAccountName(null, account, sid, cbSid, referencedDomainName, cchReferencedDomainName, peUse)) { return(Arrays.copyOf(sid, cbSid.getValue())); // buffer is now exactly as long as the sid }
Second method (uses input from first method): PointerByReference stringSid; String sidString = null;
advapi32 = Advapi32.INSTANCE;
stringSid = new PointerByReference();
if(advapi32.ConvertSidToStringSid(sid, stringSid)) { sidString = stringSid.getValue().getString(0, true); Kernel32b.INSTANCE.LocalFree(stringSid.getValue()); } return(sidString);
Thomas







