Commit 506c5ec7 authored by Sam Hocevar's avatar Sam Hocevar

  * Win32 compilation fixes, esp. the MAC retrieval.
parent 5b5ae2eb
......@@ -141,7 +141,7 @@ INCLUDE += -Iinclude -Iextras -I/usr/local/include
LIB += @LIB@ -L/usr/local/lib
ifneq (,$(findstring mingw32,$(SYS)))
LIB += -lws2_32
LIB += -lws2_32 -lnetapi32
endif
#
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -149,9 +149,11 @@ dnl
case x$host_os in
xmingw32msvc)
MMX_PLUGINS="idctmmx motionmmx"
MMXEXT_PLUGINS="idctmmxext motionmmxext imdct3dn"
;;
*)
MMX_PLUGINS="yuvmmx idctmmx motionmmx"
MMXEXT_PLUGINS="idctmmxext motionmmxext imdct3dn imdctsse downmix3dn downmixsse"
;;
esac
......@@ -162,7 +164,7 @@ AC_TRY_COMPILE([void quux(){void *p;asm("packuswb %%mm1,%%mm2"::"r"(p));}],,
AC_MSG_CHECKING([if \$CC groks MMX EXT or SSE inline assembly])
AC_TRY_COMPILE([void quux(){void *p;asm("maskmovq %%mm1,%%mm2"::"r"(p));}],,
ACCEL_PLUGINS="${ACCEL_PLUGINS} idctmmxext motionmmxext imdct3dn imdctsse downmix3dn downmixsse"
ACCEL_PLUGINS="${ACCEL_PLUGINS} ${MMXEXT_PLUGINS}"
AC_MSG_RESULT(yes), AC_MSG_RESULT(no))
dnl
......
......@@ -4,7 +4,7 @@
* modules.
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: netutils.h,v 1.12 2001/05/06 04:32:02 sam Exp $
* $Id: netutils.h,v 1.13 2001/05/28 02:38:48 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Henri Fallon <henri@videolan.org>
......@@ -32,5 +32,5 @@
*****************************************************************************/
int network_BuildLocalAddr ( struct sockaddr_in *, int, char * );
int network_BuildRemoteAddr( struct sockaddr_in *, char * );
int network_ChannelJoin ( int i_channel_id );
int network_ChannelJoin ( int );
int network_ChannelCreate ( void );
......@@ -2,7 +2,7 @@
* ac3_imdct_3dn.c: accelerated 3D Now! ac3 DCT
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_imdct_3dn.c,v 1.1 2001/05/16 14:51:29 reno Exp $
* $Id: ac3_imdct_3dn.c,v 1.2 2001/05/28 02:38:48 sam Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
*
......@@ -41,6 +41,10 @@
#include "ac3_imdct_common.h"
#include "ac3_retables.h"
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
void _M( fft_64p ) ( complex_t *x );
void _M( fft_128p ) ( complex_t *a );
......
......@@ -2,7 +2,7 @@
* ac3_imdct_sse.c: accelerated SSE ac3 DCT
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_imdct_sse.c,v 1.2 2001/05/16 14:51:29 reno Exp $
* $Id: ac3_imdct_sse.c,v 1.3 2001/05/28 02:38:48 sam Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
......@@ -42,6 +42,10 @@
#include "ac3_imdct_common.h"
#include "ac3_retables.h"
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
void _M( fft_64p ) ( complex_t *x );
void _M( fft_128p ) ( complex_t *a );
......
......@@ -2,7 +2,7 @@
* imdct3dn.c : accelerated 3D Now! IMDCT module
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: imdct3dn.c,v 1.1 2001/05/16 14:51:29 reno Exp $
* $Id: imdct3dn.c,v 1.2 2001/05/28 02:38:48 sam Exp $
*
* Authors: Gaël Hendryckx <jimmy@via.ecp.fr>
*
......@@ -67,7 +67,7 @@ MODULE_CONFIG_END
MODULE_INIT
{
p_module->psz_name = MODULE_STRING;
p_module->psz_longname = "AC3 IMDCT module";
p_module->psz_longname = "3D Now! AC3 IMDCT module";
p_module->psz_version = VERSION;
p_module->i_capabilities = MODULE_CAPABILITY_NULL
......
......@@ -2,7 +2,7 @@
* imdctsse.c : accelerated SSE IMDCT module
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: imdctsse.c,v 1.1 2001/05/15 16:19:42 sam Exp $
* $Id: imdctsse.c,v 1.2 2001/05/28 02:38:48 sam Exp $
*
* Authors: Gaël Hendryckx <jimmy@via.ecp.fr>
*
......@@ -67,7 +67,7 @@ MODULE_CONFIG_END
MODULE_INIT
{
p_module->psz_name = MODULE_STRING;
p_module->psz_longname = "AC3 IMDCT module";
p_module->psz_longname = "SSE AC3 IMDCT module";
p_module->psz_version = VERSION;
p_module->i_capabilities = MODULE_CAPABILITY_NULL
......
......@@ -2,7 +2,7 @@
* netutils.c: various network functions
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: netutils.c,v 1.30 2001/05/18 09:49:16 xav Exp $
* $Id: netutils.c,v 1.31 2001/05/28 02:38:48 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Benoit Steiner <benny@via.ecp.fr>
......@@ -31,7 +31,7 @@
#include <stdlib.h> /* free(), realloc(), atoi() */
#include <errno.h> /* errno() */
#include <string.h> /* bzero(), bcopy() */
#include <string.h> /* memset() */
#include <unistd.h> /* gethostname() */
#include <sys/time.h> /* gettimeofday */
......@@ -52,9 +52,6 @@
#ifdef WIN32 /* tools to get the MAC adress from */
#include <windows.h> /* the interface under Windows */
#include <stdio.h>
#include <iostream>
#include <strstream>
#include <string>
#endif
#ifdef HAVE_NET_IF_H
......@@ -75,7 +72,6 @@
#include "netutils.h"
/*****************************************************************************
* input_channel_t: channel library data
*****************************************************************************
......@@ -86,131 +82,16 @@
*****************************************************************************/
typedef struct input_channel_s
{
int i_channel_id; /* current channel number */
int i_channel; /* current channel number */
mtime_t last_change; /* last change date */
} input_channel_t;
#ifdef WIN32
/*****************************************************************************
* GetAdapterInfo : gets some informations about the interface using NETBIOS *
* Local prototypes
*****************************************************************************/
using namespace std ;
bool GetAdapterInfo ( int nAdapterNum, string & sMAC )
{
/* Reset the LAN adapter so that we can begin querying it */
NCB Ncb ;
memset ( &Ncb, 0, sizeof ( Ncb ) ) ;
Ncb.ncb_command = NCBRESET ;
Ncb.ncb_lana_num = nAdapterNum ;
if ( Netbios ( &Ncb ) != NRC_GOODRET )
{
char acTemp [ 80 ] ;
ostrstream outs ( acTemp, sizeof ( acTemp ) ) ;
/* FIXME This should use vlc's standard handling error functions */
outs << "error " << Ncb.ncb_retcode << " on reset" << ends ;
sMAC = acTemp ;
return false ;
}
/* Prepare to get the adapter status block */
memset ( &Ncb, 0, sizeof ( Ncb ) ) ; /* Initialization */
Ncb.ncb_command = NCBASTAT ;
Ncb.ncb_lana_num = nAdapterNum ;
strcpy ( ( char * ) Ncb.ncb_callname, "*" ) ;
struct ASTAT {
ADAPTER_STATUS adapt ;
NAME_BUFFER NameBuff[30] ;
} Adapter ;
memset ( &Adapter, 0, sizeof ( Adapter ) ) ;
Ncb.ncb_buffer = ( unsigned char * ) &Adapter ;
Ncb.ncb_length = sizeof ( Adapter ) ;
/* Get the adapter's info and, if this works, return it in standard,
colon-delimited form. */
if ( Netbios( &Ncb ) == 0 )
{
char acMAC [ 18 ] ;
sprintf ( acMAC, "%02X:%02X:%02X:%02X:%02X:%02X",
int ( Adapter.adapt.adapter_address[0] ),
int ( Adapter.adapt.adapter_address[1] ),
int ( Adapter.adapt.adapter_address[2] ),
int ( Adapter.adapt.adapter_address[3] ),
int ( Adapter.adapt.adapter_address[4] ),
int ( Adapter.adapt.adapter_address[5] ) );
sMAC = acMAC;
return true;
}
else
{
char acTemp[80] ;
ostrstream outs ( acTemp, sizeof ( acTemp ) ) ;
/* FIXME Same thing as up there */
outs << "error " << Ncb.ncb_retcode << " on ASTAT" << ends;
sMAC = acTemp;
return false;
}
}
/*****************************************************************************
* GetMacAddress : Extracts the MAC Address from the informations collected in
* GetAdapterInfo
****************************************************************************/
string GetMacAddress()
{
/* Get adapter list - support for more than one adapter */
LANA_ENUM AdapterList ;
NCB Ncb ;
memset ( &Ncb, 0, sizeof ( NCB ) ) ;
Ncb.ncb_command = NCBENUM ;
Ncb.ncb_buffer = ( unsigned char * ) &AdapterList ;
Ncb.ncb_length = sizeof ( AdapterList ) ;
Netbios ( &Ncb ) ;
/* Get all of the local ethernet addresses */
string sMAC;
for ( int i = 0; i < AdapterList.length ; ++i )
{
if ( GetAdapterInfo ( AdapterList.lana [ i ] , sMAC ) )
{
cout << "Adapter " << int ( AdapterList. lana [ i ] ) <<
"'s MAC is " << sMAC << endl ;
}
else
{
/* FIXME those bloody error messages */
cerr << "Failed to get MAC address! Do you" << endl;
cerr << "have the NetBIOS protocol installed?" << endl;
break;
}
}
return sMac;
}
static int GetMacAddress ( int i_socket, char *psz_mac );
#ifdef WIN32
static int GetAdapterInfo ( int i_adapter, char *psz_string );
#endif
/*****************************************************************************
......@@ -324,19 +205,19 @@ int network_ChannelCreate( void )
p_main->p_channel = malloc( sizeof( input_channel_t ) );
if( p_main->p_channel == NULL )
{
intf_ErrMsg("error: %s\n", strerror(ENOMEM));
intf_ErrMsg( "network error: could not create channel bank" );
return( -1 );
}
/* Initialize structure */
p_main->p_channel->i_channel_id = 0;
p_main->p_channel->i_channel = 0;
p_main->p_channel->last_change = 0;
intf_Msg("Channels initialized\n");
intf_Msg( "network: channels initialized" );
return( 0 );
#else
intf_ErrMsg( "error : channel changing only works with linux yest" );
intf_ErrMsg( "network error : channels not supported" );
return( 1 );
#endif
......@@ -353,191 +234,292 @@ int network_ChannelCreate( void )
* should be unlocked using input_ChannelLeave().
* Non 0 will be returned in case of error.
*****************************************************************************/
int network_ChannelJoin( int i_channel_id )
int network_ChannelJoin( int i_channel )
{
/* I still prefer to put BeOS a bit apart */
#if defined( SYS_BEOS )
intf_ErrMsg( "Channels are not yet supported under BeOS" );
intf_ErrMsg( "network error: channels are not yet supported under BeOS" );
return( -1 );
#elif defined( SYS_LINUX )
int i_socket_cl;
#elif defined( WIN32 ) || defined( SYS_LINUX )
int i_socket;
int i_fromlen;
struct ifreq s_interface;
struct sockaddr_in sa_server;
struct sockaddr_in sa_client;
unsigned int i_version = 12;
char psz_mess[80];
char psz_mess[ 80 ];
char psz_mac[ 40 ];
char i_mess_length = 80;
struct timeval * p_date_cl;
struct timeval s_time;
long unsigned int i_date;
unsigned long int i_date;
struct timeval answer_delay;
int i_nbanswer;
char i_answer;
fd_set s_rfds;
fd_set fd;
unsigned int i_rc;
if( ! p_main->b_channels )
{
intf_ErrMsg( "Channels disabled. To enable them, use the --channels"
" option" );
intf_ErrMsg( "network: channels disabled, to enable them, use the"
"--channels option" );
return( -1 );
}
/* debug */
intf_DbgMsg( "ChannelJoin : %d", i_channel_id );
intf_DbgMsg( "network: ChannelJoin : %d", i_channel );
/* If last change is too recent, wait a while */
if( mdate() - p_main->p_channel->last_change < INPUT_CHANNEL_CHANGE_DELAY )
{
intf_Msg( "Waiting before changing channel...\n" );
intf_Msg( "network: waiting before changing channel" );
mwait( p_main->p_channel->last_change + INPUT_CHANNEL_CHANGE_DELAY );
}
p_main->p_channel->last_change = mdate();
p_main->p_channel->i_channel_id = i_channel_id;
intf_Msg( "Joining channel %d\n", i_channel_id );
/*
* Looking for information about the eth0 interface
*/
s_interface.ifr_addr.sa_family = AF_INET;
strcpy( s_interface.ifr_name, INPUT_IFACE_DEFAULT );
p_main->p_channel->last_change = mdate();
p_main->p_channel->i_channel = i_channel;
intf_Msg( "network: joining channel %d", i_channel );
/*
* Initialysing the socket
* Initializing the socket
*/
i_socket_cl=socket( AF_INET, SOCK_DGRAM, 0 );
i_socket = socket( AF_INET, SOCK_DGRAM, 0 );
/*
* Getting the server's information
*/
bzero( &sa_server, sizeof(struct sockaddr_in) );
memset( &sa_server, 0x00, sizeof(struct sockaddr_in) );
sa_server.sin_family = AF_INET;
sa_server.sin_port = htons( INPUT_CHANNEL_PORT_DEFAULT );
inet_aton( INPUT_CHANNEL_SERVER_DEFAULT, &(sa_server.sin_addr) );
#ifdef HAVE_ARPA_INET_H
if( !inet_aton( psz_server, &p_socket->sin_addr) )
#else
if( (sa_server.sin_addr.s_addr = inet_addr( INPUT_CHANNEL_SERVER_DEFAULT )) == -1 )
#endif
/*
* Looking for the interface MAC address
*/
ioctl( i_socket_cl, SIOCGIFHWADDR, &s_interface );
intf_DbgMsg(
"CHANNELSERVER: macaddr == %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
s_interface.ifr_hwaddr.sa_data[0] & 0xff,
s_interface.ifr_hwaddr.sa_data[1] & 0xff,
s_interface.ifr_hwaddr.sa_data[2] & 0xff,
s_interface.ifr_hwaddr.sa_data[3] & 0xff,
s_interface.ifr_hwaddr.sa_data[4] & 0xff,
s_interface.ifr_hwaddr.sa_data[5] & 0xff );
/*
* Getting date of the client
*/
p_date_cl=malloc( sizeof(struct timeval) );
if( p_date_cl == NULL )
{
intf_ErrMsg( "CHANNELSERVER: unable to allocate memory\n" );
/* return VS_R_MEMORY;*/
return( -1);
}
if ( gettimeofday( p_date_cl, 0 ) == -1 )
if( GetMacAddress( i_socket, psz_mac ) )
{
return( -1);
intf_ErrMsg( "network error: failed getting MAC address" );
return( -1 );
}
i_date = p_date_cl->tv_sec;
free( p_date_cl );
intf_DbgMsg( "CHANNELSERVER: date %lu\n", i_date );
/*
* Getting date of the client in seconds
*/
i_date = mdate() / 1000000;
intf_DbgMsg( "vlcs: date %lu", i_date );
/*
* Build of the message
*/
sprintf( psz_mess, "%d %u %lu %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n",
i_channel_id, i_version, i_date,
s_interface.ifr_hwaddr.sa_data[0] & 0xff,
s_interface.ifr_hwaddr.sa_data[1] & 0xff,
s_interface.ifr_hwaddr.sa_data[2] & 0xff,
s_interface.ifr_hwaddr.sa_data[3] & 0xff,
s_interface.ifr_hwaddr.sa_data[4] & 0xff,
s_interface.ifr_hwaddr.sa_data[5] & 0xff );
sprintf( psz_mess, "%d %u %lu %s \n",
i_channel, i_version, i_date, psz_mac );
intf_DbgMsg( "CHANNELSERVER: The message is %s\n", psz_mess );
intf_DbgMsg( "vlcs: The message is %s", psz_mess );
/*
* Open the socket 2
*/
bzero( &sa_client, sizeof(struct sockaddr_in) );
memset( &sa_client, 0x00, sizeof(struct sockaddr_in) );
sa_client.sin_family = AF_INET;
sa_client.sin_port = htons(4312);
sa_client.sin_addr.s_addr = INADDR_ANY;
i_fromlen = sizeof( struct sockaddr );
i_rc = bind( i_socket_cl, (struct sockaddr *)(&sa_client),\
i_rc = bind( i_socket, (struct sockaddr *)(&sa_client),\
sizeof(struct sockaddr) );
if ( i_rc )
{
intf_ErrMsg( "CHANNELSERVER: Unable to bind socket:%u\n", i_rc );
intf_ErrMsg( "vlcs: Unable to bind socket:%u ", i_rc );
/* TODO put CS_R_BIND in types.h*/
/* return CS_R_SOCKET;*/
return -1;
}
/*
* Send the message
*/
sendto( i_socket_cl, psz_mess, i_mess_length, 0, \
sendto( i_socket, psz_mess, i_mess_length, 0, \
(struct sockaddr *)(&sa_server), \
sizeof(struct sockaddr) );
/*
* Waiting 5 sec for one answer from the server
*/
s_time.tv_sec = 5;
s_time.tv_usec = 0;
FD_ZERO( &s_rfds );
FD_SET( i_socket_cl, &s_rfds );
i_nbanswer = select( i_socket_cl+1, &s_rfds, NULL, NULL, &s_time );
if( i_nbanswer == 0 )
{
intf_DbgMsg( "CHANNELSERVER: no answer\n" );
}
else if( i_nbanswer == -1 )
{
intf_DbgMsg( "CHANNELSERVER: Unable to receive the answer\n ");
}
else
answer_delay.tv_sec = 5;
answer_delay.tv_usec = 0;
FD_ZERO( &fd );
FD_SET( i_socket, &fd );
i_nbanswer = select( i_socket + 1, &fd, NULL, NULL, &answer_delay );
switch( i_nbanswer )
{
recvfrom( i_socket_cl, &i_answer, sizeof(char), 0,\
case 0:
intf_DbgMsg( "vlcs: no answer" );
break;
case -1:
intf_DbgMsg( "vlcs: unable to receive the answer ");
break;
default:
recvfrom( i_socket, &i_answer, sizeof(char), 0,\
(struct sockaddr *)(&sa_client), &i_fromlen);
intf_DbgMsg( "CHANNELSERVER: the answer : %hhd\n", i_answer );
if( i_answer == -1 )
{
intf_DbgMsg(
"CHANNELSERVER: The server failed to create the thread\n" );
}
else if( i_answer == 0 )
{
intf_DbgMsg(
"CHANNELSERVER: The server tries to change the channel\n" );
}
else
intf_DbgMsg( "vlcs: the answer : %i", i_answer );
switch( i_answer )
{
intf_DbgMsg( "CHANNELSERVER: Unknown answer !\n" );
case -1:
intf_DbgMsg( "vlcs: the server failed to create the thread" );
break;
case 0:
intf_DbgMsg( "vlcs: the server tries to change the channel" );
break;
default:
intf_DbgMsg( "vlcs: unknown answer !" );
break;
}
break;
}
/*
* Close the socket
*/
close( i_socket_cl );
close( i_socket );
return( 0 );
#else
intf_ErrMsg( "Channels only work under linux yet" );
intf_ErrMsg( "network error: channels not supported" );
return( -1 );
#endif
}
/* Following functions are local */
/*****************************************************************************
* GetMacAddress: extract the MAC Address
*****************************************************************************/
static int GetMacAddress( int i_socket, char *psz_mac )
{
#if defined( SYS_LINUX )
struct ifreq interface;
int i_ret;
/*
* Looking for information about the eth0 interface
*/
interface.ifr_addr.sa_family = AF_INET;
strcpy( interface.ifr_name, INPUT_IFACE_DEFAULT );
i_ret = ioctl( i_socket, SIOCGIFHWADDR, &interface );
if( i_ret )
{
intf_ErrMsg( "network error: ioctl SIOCGIFHWADDR failed" );
return( i_ret );
}
sprintf( psz_mac, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
interface.ifr_hwaddr.sa_data[0] & 0xff,
interface.ifr_hwaddr.sa_data[1] & 0xff,
interface.ifr_hwaddr.sa_data[2] & 0xff,
interface.ifr_hwaddr.sa_data[3] & 0xff,
interface.ifr_hwaddr.sa_data[4] & 0xff,
interface.ifr_hwaddr.sa_data[5] & 0xff );
return( 0 );
#elif defined( WIN32 )
int i, i_ret = -1;
/* Get adapter list - support for more than one adapter */
LANA_ENUM AdapterList;
NCB Ncb;
intf_WarnMsg( 2, "network: looking for MAC address" );
memset( &Ncb, 0, sizeof( NCB ) );
Ncb.ncb_command = NCBENUM;
Ncb.ncb_buffer = (unsigned char *)&AdapterList;
Ncb.ncb_length = sizeof( AdapterList );
Netbios( &Ncb );
/* Get all of the local ethernet addresses */
for ( i = 0; i < AdapterList.length ; ++i )
{
if ( GetAdapterInfo ( AdapterList.lana[ i ], psz_mac ) == 0 )
{
i_ret = 0;
}
}
return( i_ret );
#elif
return( -1);
#endif
}
#ifdef WIN32
/*****************************************************************************
* GetAdapterInfo : gets some informations about the interface using NETBIOS
*****************************************************************************/
static int GetAdapterInfo( int i_adapter, char *psz_string )
{
struct ASTAT
{
ADAPTER_STATUS adapt;
NAME_BUFFER psz_name[30];
} Adapter;
/* Reset the LAN adapter so that we can begin querying it */
NCB Ncb;
memset( &Ncb, 0, sizeof ( Ncb ) );
Ncb.ncb_command = NCBRESET;
Ncb.ncb_lana_num = i_adapter;
if( Netbios( &Ncb ) != NRC_GOODRET )
{
intf_ErrMsg( "network error: reset returned %i", Ncb.ncb_retcode );
return -1;
}
/* Prepare to get the adapter status block */
memset( &Ncb, 0, sizeof( Ncb ) ) ; /* Initialization */
Ncb.ncb_command = NCBASTAT;
Ncb.ncb_lana_num = i_adapter;
strcpy( (char *)Ncb.ncb_callname, "*" );
memset( &Adapter, 0, sizeof ( Adapter ) );
Ncb.ncb_buffer = ( unsigned char * ) &Adapter;
Ncb.ncb_length = sizeof ( Adapter );
/* Get the adapter's info and, if this works, return it in standard,
* colon-delimited form. */
if ( Netbios( &Ncb ) == 0 )
{
sprintf ( psz_string, "%02X:%02X:%02X:%02X:%02X:%02X",
(int) ( Adapter.adapt.adapter_address[0] ),
(int) ( Adapter.adapt.adapter_address[1] ),
(int) ( Adapter.adapt.adapter_address[2] ),
(int) ( Adapter.adapt.adapter_address[3] ),
(int) ( Adapter.adapt.adapter_address[4] ),
(int) ( Adapter.adapt.adapter_address[5] ) );
intf_WarnMsg( 2, "network: found MAC address %s", psz_string );
return 0;
}
else
{
intf_ErrMsg( "network error: ASTAT returned %i", Ncb.ncb_retcode );
return -1;
}
}
#endif /* WIN32 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment