mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-02 17:35:18 +00:00
Added the X64 utility class, currently just has a method for detecting 64bit Windows. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2627 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
723 lines
19 KiB
Java
723 lines
19 KiB
Java
/*
|
|
* Copyright (C) 2005 Alfresco, Inc.
|
|
*
|
|
* Licensed under the Mozilla Public License version 1.1
|
|
* with a permitted attribution clause. You may obtain a
|
|
* copy of the License at
|
|
*
|
|
* http://www.alfresco.org/legal/license.txt
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
* either express or implied. See the License for the specific
|
|
* language governing permissions and limitations under the
|
|
* License.
|
|
*/
|
|
package org.alfresco.filesys.netbios.win32;
|
|
|
|
import java.net.InetAddress;
|
|
import java.net.NetworkInterface;
|
|
import java.net.SocketException;
|
|
import java.util.Enumeration;
|
|
import java.util.Hashtable;
|
|
|
|
import org.alfresco.filesys.netbios.NetBIOSName;
|
|
import org.alfresco.filesys.util.DataBuffer;
|
|
import org.alfresco.filesys.util.IPAddress;
|
|
import org.alfresco.filesys.util.X64;
|
|
|
|
/**
|
|
* Win32 NetBIOS Native Call Wrapper Class
|
|
*/
|
|
public class Win32NetBIOS
|
|
{
|
|
|
|
// Constants
|
|
//
|
|
// FIND_NAME_BUFFER structure length
|
|
|
|
protected final static int FindNameBufferLen = 33;
|
|
|
|
// Exception if the native code DLL load failed
|
|
|
|
private static Throwable m_loadDLLException;
|
|
|
|
/**
|
|
* Check if the native code was loaded successfully
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public static final boolean isInitialized()
|
|
{
|
|
return m_loadDLLException == null ? true : false;
|
|
}
|
|
|
|
/**
|
|
* Return the native code load exception
|
|
*
|
|
* @return Throwable
|
|
*/
|
|
public static final Throwable getInitializationException()
|
|
{
|
|
return m_loadDLLException;
|
|
}
|
|
|
|
/**
|
|
* Check if NetBIOS is enabled on any network adapters
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public static final boolean isAvailable() {
|
|
|
|
// Check if the DLL was loaded successfully
|
|
|
|
if ( isInitialized() == false)
|
|
return false;
|
|
|
|
// Check if there are any valid LANAs, if not then NetBIOS is not enabled or network
|
|
// adapters that have NetBIOS enabled are not currently enabled
|
|
|
|
int[] lanas = LanaEnum();
|
|
if ( lanas != null && lanas.length > 0)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Add a NetBIOS name to the local name table
|
|
*
|
|
* @param lana int
|
|
* @param name byte[]
|
|
* @return int
|
|
*/
|
|
public static native int AddName(int lana, byte[] name);
|
|
|
|
/**
|
|
* Add a group NetBIOS name to the local name table
|
|
*
|
|
* @param lana int
|
|
* @param name byte[]
|
|
* @return int
|
|
*/
|
|
public static native int AddGroupName(int lana, byte[] name);
|
|
|
|
/**
|
|
* Find a NetBIOS name, return the name buffer
|
|
*
|
|
* @param lana int
|
|
* @param name byte[]
|
|
* @param nameBuf byte[]
|
|
* @param bufLen int
|
|
* @return int
|
|
*/
|
|
public static native int FindNameRaw(int lana, byte[] name, byte[] nameBuf, int bufLen);
|
|
|
|
/**
|
|
* Find a NetBIOS name
|
|
*
|
|
* @param lana int
|
|
* @param name NetBIOSName
|
|
* @return int
|
|
*/
|
|
public static int FindName(int lana, NetBIOSName nbName)
|
|
{
|
|
|
|
// Allocate a buffer to receive the name details
|
|
|
|
byte[] nameBuf = new byte[nbName.isGroupName() ? 65535 : 4096];
|
|
|
|
// Get the raw NetBIOS name data
|
|
|
|
int sts = FindNameRaw(lana, nbName.getNetBIOSName(), nameBuf, nameBuf.length);
|
|
|
|
if (sts != NetBIOS.NRC_GoodRet)
|
|
return -sts;
|
|
|
|
// Unpack the FIND_NAME_HEADER structure
|
|
|
|
DataBuffer buf = new DataBuffer(nameBuf, 0, nameBuf.length);
|
|
|
|
int nodeCount = buf.getShort();
|
|
buf.skipBytes(1);
|
|
boolean isGroupName = buf.getByte() == 0 ? false : true;
|
|
|
|
// Unpack the FIND_NAME_BUFFER structures
|
|
|
|
int curPos = buf.getPosition();
|
|
|
|
for (int i = 0; i < nodeCount; i++)
|
|
{
|
|
|
|
// FIND_NAME_BUFFER:
|
|
// UCHAR length
|
|
// UCHAR access_control
|
|
// UCHAR frame_control
|
|
// UCHAR destination_addr[6]
|
|
// UCHAR source_addr[6]
|
|
// UCHAR routing_info[18]
|
|
|
|
// Skip to the source_addr field
|
|
|
|
buf.skipBytes(9);
|
|
|
|
// Source address field format should be 0.0.n.n.n.n for TCP/IP address
|
|
|
|
if (buf.getByte() == 0 && buf.getByte() == 0)
|
|
{
|
|
|
|
// Looks like a TCP/IP format address, unpack it
|
|
|
|
byte[] ipAddr = new byte[4];
|
|
|
|
ipAddr[0] = (byte) buf.getByte();
|
|
ipAddr[1] = (byte) buf.getByte();
|
|
ipAddr[2] = (byte) buf.getByte();
|
|
ipAddr[3] = (byte) buf.getByte();
|
|
|
|
// Add the address to the list of TCP/IP addresses for the NetBIOS name
|
|
|
|
nbName.addIPAddress(ipAddr);
|
|
|
|
// Skip to the start of the next FIND_NAME_BUFFER structure
|
|
|
|
curPos += FindNameBufferLen;
|
|
buf.setPosition(curPos);
|
|
}
|
|
}
|
|
|
|
// Return the node count
|
|
|
|
return nodeCount;
|
|
}
|
|
|
|
/**
|
|
* Delete a NetBIOS name from the local name table
|
|
*
|
|
* @param lana int
|
|
* @param name byte[]
|
|
* @return int
|
|
*/
|
|
public static native int DeleteName(int lana, byte[] name);
|
|
|
|
/**
|
|
* Enumerate the available LANAs
|
|
*
|
|
* @return int[]
|
|
*/
|
|
public static int[] LanaEnumerate()
|
|
{
|
|
// Make sure that there is an active network adapter as making calls to the LanaEnum native call
|
|
// causes problems when there are no active network adapters.
|
|
|
|
boolean adapterAvail = false;
|
|
|
|
try
|
|
{
|
|
// Enumerate the available network adapters and check for an active adapter, not including
|
|
// the loopback adapter
|
|
|
|
Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
|
|
|
|
while ( nis.hasMoreElements() && adapterAvail == false)
|
|
{
|
|
NetworkInterface ni = nis.nextElement();
|
|
if ( ni.getName().equals("lo") == false)
|
|
{
|
|
// Make sure the adapter has a valid IP address
|
|
|
|
Enumeration<InetAddress> addrs = ni.getInetAddresses();
|
|
if ( addrs.hasMoreElements())
|
|
adapterAvail = true;
|
|
}
|
|
}
|
|
|
|
}
|
|
catch ( SocketException ex)
|
|
{
|
|
}
|
|
|
|
// Check if there are network adapter(s) available
|
|
|
|
if ( adapterAvail == false)
|
|
return null;
|
|
|
|
// Call the native code to return the available LANA list
|
|
|
|
return LanaEnum();
|
|
}
|
|
|
|
/**
|
|
* Enumerate the available LANAs
|
|
*
|
|
* @return int[]
|
|
*/
|
|
private static native int[] LanaEnum();
|
|
|
|
/**
|
|
* Reset the NetBIOS environment
|
|
*
|
|
* @param lana int
|
|
* @return int
|
|
*/
|
|
public static native int Reset(int lana);
|
|
|
|
/**
|
|
* Listen for an incoming session request
|
|
*
|
|
* @param lana int
|
|
* @param toName byte[]
|
|
* @param fromName byte[]
|
|
* @param callerName byte[]
|
|
* @return int
|
|
*/
|
|
public static native int Listen(int lana, byte[] toName, byte[] fromName, byte[] callerName);
|
|
|
|
/**
|
|
* Receive a data packet on a session
|
|
*
|
|
* @param lana int
|
|
* @param lsn int
|
|
* @param buf byte[]
|
|
* @param off int
|
|
* @param maxLen int
|
|
* @return int
|
|
*/
|
|
public static native int Receive(int lana, int lsn, byte[] buf, int off, int maxLen);
|
|
|
|
/**
|
|
* Send a data packet on a session
|
|
*
|
|
* @param lana int
|
|
* @param lsn int
|
|
* @param buf byte[]
|
|
* @param off int
|
|
* @param len int
|
|
* @return int
|
|
*/
|
|
public static native int Send(int lana, int lsn, byte[] buf, int off, int len);
|
|
|
|
/**
|
|
* Send a datagram to a specified name
|
|
*
|
|
* @param lana int
|
|
* @param srcNum int
|
|
* @param destName byte[]
|
|
* @param buf byte[]
|
|
* @param off int
|
|
* @param len int
|
|
* @return int
|
|
*/
|
|
public static native int SendDatagram(int lana, int srcNum, byte[] destName, byte[] buf, int off, int len);
|
|
|
|
/**
|
|
* Send a broadcast datagram
|
|
*
|
|
* @param lana
|
|
* @param buf byte[]
|
|
* @param off int
|
|
* @param len int
|
|
* @return int
|
|
*/
|
|
public static native int SendBroadcastDatagram(int lana, byte[] buf, int off, int len);
|
|
|
|
/**
|
|
* Receive a datagram on a specified name
|
|
*
|
|
* @param lana int
|
|
* @param nameNum int
|
|
* @param buf byte[]
|
|
* @param off int
|
|
* @param maxLen int
|
|
* @return int
|
|
*/
|
|
public static native int ReceiveDatagram(int lana, int nameNum, byte[] buf, int off, int maxLen);
|
|
|
|
/**
|
|
* Receive a broadcast datagram
|
|
*
|
|
* @param lana int
|
|
* @param nameNum int
|
|
* @param buf byte[]
|
|
* @param off int
|
|
* @param maxLen int
|
|
* @return int
|
|
*/
|
|
public static native int ReceiveBroadcastDatagram(int lana, int nameNum, byte[] buf, int off, int maxLen);
|
|
|
|
/**
|
|
* Hangup a session
|
|
*
|
|
* @param lsn int
|
|
* @return int
|
|
*/
|
|
public static native int Hangup(int lana, int lsn);
|
|
|
|
/**
|
|
* Return the local computers NetBIOS name
|
|
*
|
|
* @return String
|
|
*/
|
|
public static native String GetLocalNetBIOSName();
|
|
|
|
/**
|
|
* Return the local domain name
|
|
*
|
|
* @return String
|
|
*/
|
|
public static native String GetLocalDomainName();
|
|
|
|
/**
|
|
* Return a comma delimeted list of WINS server TCP/IP addresses, or null if no WINS servers are
|
|
* configured.
|
|
*
|
|
* @return String
|
|
*/
|
|
public static native String getWINSServerList();
|
|
|
|
/**
|
|
* Find the TCP/IP address for a LANA
|
|
*
|
|
* @param lana int
|
|
* @return String
|
|
*/
|
|
public static final String getIPAddressForLANA(int lana)
|
|
{
|
|
|
|
// Get the local NetBIOS name
|
|
|
|
String localName = GetLocalNetBIOSName();
|
|
if (localName == null)
|
|
return null;
|
|
|
|
// Create a NetBIOS name for the local name
|
|
|
|
NetBIOSName nbName = new NetBIOSName(localName, NetBIOSName.WorkStation, false);
|
|
|
|
// Get the local NetBIOS name details
|
|
|
|
int sts = FindName(lana, nbName);
|
|
|
|
if (sts == -NetBIOS.NRC_EnvNotDef)
|
|
{
|
|
|
|
// Reset the LANA then try the name lookup again
|
|
|
|
Reset(lana);
|
|
sts = FindName(lana, nbName);
|
|
}
|
|
|
|
// Check if the name lookup was successful
|
|
|
|
String ipAddr = null;
|
|
|
|
if (sts >= 0)
|
|
{
|
|
|
|
// Get the first IP address from the list
|
|
|
|
ipAddr = nbName.getIPAddressString(0);
|
|
}
|
|
|
|
// Return the TCP/IP address for the LANA
|
|
|
|
return ipAddr;
|
|
}
|
|
|
|
/**
|
|
* Find the adapter name for a LANA
|
|
*
|
|
* @param lana int
|
|
* @return String
|
|
*/
|
|
public static final String getAdapterNameForLANA(int lana)
|
|
{
|
|
|
|
// Get the TCP/IP address for a LANA
|
|
|
|
String ipAddr = getIPAddressForLANA(lana);
|
|
if (ipAddr == null)
|
|
return null;
|
|
|
|
// Get the list of available network adapters
|
|
|
|
Hashtable<String, NetworkInterface> adapters = getNetworkAdapterList();
|
|
String adapterName = null;
|
|
|
|
if (adapters != null)
|
|
{
|
|
|
|
// Find the network adapter for the TCP/IP address
|
|
|
|
NetworkInterface ni = adapters.get(ipAddr);
|
|
if (ni != null)
|
|
adapterName = ni.getDisplayName();
|
|
}
|
|
|
|
// Return the adapter name for the LANA
|
|
|
|
return adapterName;
|
|
}
|
|
|
|
/**
|
|
* Find the LANA for a TCP/IP address
|
|
*
|
|
* @param addr String
|
|
* @return int
|
|
*/
|
|
public static final int getLANAForIPAddress(String addr)
|
|
{
|
|
|
|
// Check if the address is a numeric TCP/IP address
|
|
|
|
if (IPAddress.isNumericAddress(addr) == false)
|
|
return -1;
|
|
|
|
// Get a list of the available NetBIOS LANAs
|
|
|
|
int[] lanas = LanaEnum();
|
|
if (lanas == null || lanas.length == 0)
|
|
return -1;
|
|
|
|
// Search for the LANA with the matching TCP/IP address
|
|
|
|
for (int i = 0; i < lanas.length; i++)
|
|
{
|
|
|
|
// Get the current LANAs TCP/IP address
|
|
|
|
String curAddr = getIPAddressForLANA(lanas[i]);
|
|
if (curAddr != null && curAddr.equals(addr))
|
|
return lanas[i];
|
|
}
|
|
|
|
// Failed to find the LANA for the specified TCP/IP address
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Find the LANA for a network adapter
|
|
*
|
|
* @param name String
|
|
* @return int
|
|
*/
|
|
public static final int getLANAForAdapterName(String name)
|
|
{
|
|
|
|
// Get the list of available network adapters
|
|
|
|
Hashtable<String, NetworkInterface> niList = getNetworkAdapterList();
|
|
|
|
// Search for the address of the specified network adapter
|
|
|
|
Enumeration<String> niEnum = niList.keys();
|
|
|
|
while (niEnum.hasMoreElements())
|
|
{
|
|
|
|
// Get the current TCP/IP address
|
|
|
|
String ipAddr = niEnum.nextElement();
|
|
NetworkInterface ni = niList.get(ipAddr);
|
|
|
|
if (ni.getDisplayName().equalsIgnoreCase(name))
|
|
{
|
|
|
|
// Return the LANA for the network adapters TCP/IP address
|
|
|
|
return getLANAForIPAddress(ipAddr);
|
|
}
|
|
}
|
|
|
|
// Failed to find matching network adapter
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Return a hashtable of NetworkInterfaces indexed by TCP/IP address
|
|
*
|
|
* @return Hashtable<String,NetworkInterface>
|
|
*/
|
|
private static final Hashtable<String, NetworkInterface> getNetworkAdapterList()
|
|
{
|
|
|
|
// Get a list of the local network adapters
|
|
|
|
Hashtable<String, NetworkInterface> niList = new Hashtable<String, NetworkInterface>();
|
|
|
|
try
|
|
{
|
|
|
|
// Enumerate the available network adapters
|
|
|
|
Enumeration<NetworkInterface> niEnum = NetworkInterface.getNetworkInterfaces();
|
|
|
|
while (niEnum.hasMoreElements())
|
|
{
|
|
|
|
// Get the current network interface details
|
|
|
|
NetworkInterface ni = niEnum.nextElement();
|
|
Enumeration<InetAddress> addrEnum = ni.getInetAddresses();
|
|
|
|
while (addrEnum.hasMoreElements())
|
|
{
|
|
|
|
// Get the address and add the adapter to the list indexed via the numeric IP
|
|
// address string
|
|
|
|
InetAddress addr = addrEnum.nextElement();
|
|
niList.put(addr.getHostAddress(), ni);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
}
|
|
|
|
// Return the network adapter list
|
|
|
|
return niList;
|
|
}
|
|
|
|
//---------- Winsock based NetBIOS interface ----------//
|
|
|
|
/**
|
|
* Initialize the NetBIOS socket interface
|
|
*
|
|
* @exception WinsockNetBIOSException If a Winsock error occurs
|
|
*/
|
|
protected static native void InitializeSockets()
|
|
throws WinsockNetBIOSException;
|
|
|
|
/**
|
|
* Shutdown the NetBIOS socket interface
|
|
*/
|
|
protected static native void ShutdownSockets();
|
|
|
|
/**
|
|
* Create a NetBIOS socket
|
|
*
|
|
* @param lana int
|
|
* @return int
|
|
* @exception WinsockNetBIOSException If a Winsock error occurs
|
|
*/
|
|
protected static native int CreateSocket(int lana)
|
|
throws WinsockNetBIOSException;
|
|
|
|
/**
|
|
* Create a NetBIOS datagram socket
|
|
*
|
|
* @param lana int
|
|
* @return int
|
|
* @exception WinsockNetBIOSException If a Winsock error occurs
|
|
*/
|
|
protected static native int CreateDatagramSocket(int lana)
|
|
throws WinsockNetBIOSException;
|
|
|
|
/**
|
|
* Bind a NetBIOS socket to a name to listen for incoming sessions
|
|
*
|
|
* @param sockPtr int
|
|
* @param name byte[]
|
|
* @exception WinsockNetBIOSException If a Winsock error occurs
|
|
*/
|
|
protected static native int BindSocket(int sockPtr, byte[] name)
|
|
throws WinsockNetBIOSException;
|
|
|
|
/**
|
|
* Listen for an incoming connection
|
|
*
|
|
* @param sockPtr int
|
|
* @param callerName byte[]
|
|
* @return int
|
|
* @exception WinsockNetBIOSException If a Winsock error occurs
|
|
*/
|
|
protected static native int ListenSocket(int sockPtr, byte[] callerName)
|
|
throws WinsockNetBIOSException;
|
|
|
|
/**
|
|
* Close a NetBIOS socket
|
|
*
|
|
* @param sockPtr int
|
|
*/
|
|
protected static native void CloseSocket(int sockPtr);
|
|
|
|
/**
|
|
* Send data on a session socket
|
|
*
|
|
* @param sockPtr int
|
|
* @param buf byte[]
|
|
* @param off int
|
|
* @param len int
|
|
* @return int
|
|
* @exception WinsockNetBIOSException If a Winsock error occurs
|
|
*/
|
|
protected static native int SendSocket(int sockPtr, byte[] buf, int off, int len)
|
|
throws WinsockNetBIOSException;
|
|
|
|
/**
|
|
* Receive data on a session socket
|
|
*
|
|
* @param sockPtr int
|
|
* @param toName byte[]
|
|
* @param buf byte[]
|
|
* @param off int
|
|
* @param maxLen int
|
|
* @return int
|
|
* @exception WinsockNetBIOSException If a Winsock error occurs
|
|
*/
|
|
protected static native int ReceiveSocket(int sockPtr, byte[] buf, int off, int maxLen)
|
|
throws WinsockNetBIOSException;
|
|
|
|
/**
|
|
* Send data on a datagram socket
|
|
*
|
|
* @param sockPtr int
|
|
* @param toName byte[]
|
|
* @param buf byte[]
|
|
* @param off int
|
|
* @param len int
|
|
* @return int
|
|
* @exception WinsockNetBIOSException If a Winsock error occurs
|
|
*/
|
|
protected static native int SendSocketDatagram(int sockPtr, byte[] toName, byte[] buf, int off, int len)
|
|
throws WinsockNetBIOSException;
|
|
|
|
/**
|
|
* Wait for a network address change event, block until a change occurs or the Winsock NetBIOS
|
|
* interface is shut down
|
|
*/
|
|
public static native void waitForNetworkAddressChange();
|
|
|
|
/**
|
|
* Static initializer used to load the native code library
|
|
*/
|
|
static
|
|
{
|
|
// Check if we are running under 64 bit Windows
|
|
|
|
String dllName = "Win32NetBIOS";
|
|
|
|
if ( X64.isWindows64())
|
|
dllName = "Win32NetBIOSx64";
|
|
|
|
// Load the Win32 NetBIOS interface library
|
|
|
|
try
|
|
{
|
|
System.loadLibrary( dllName);
|
|
}
|
|
catch (Throwable ex)
|
|
{
|
|
ex.printStackTrace();
|
|
|
|
// Save the native code load exception
|
|
|
|
m_loadDLLException = ex;
|
|
}
|
|
}
|
|
}
|