Я пытаюсь переписать программу, работающую с файловым сервером Novell NetWare 5.1 с языка C++ на C#.
.NET библиотеку Novell, похоже, писать не собирается, поэтому я вынужден использовать PlatformInvoke.
Инициализация у меня проходит без ошибок, затем подключение — NWDSLogin (и NWDSLoginEx) возвращают успешный код, но поработать с установленным соединением не получается — функции
NWDSAuthenticateConn,
NWDSAuthenticateConnEx,
NWGetFileServerInformation,
NWFreeConnectionSlot
возвращают один и тот же код: 0x8801 (INVALID_CONNECTION: Request attempted with invalid or nonattached connection handle).
Все декларации функцмй из Win32 библиотек Novell я предворяю следующим атрибутом:
[DllImport("NAME.dll", CharSet = CharSet.Ansi)]
Почему соединение оказывается недействительным?
Здравствуйте, adontz, Вы писали:
A>Думаю, виноваты ... и отсутствие Си++ и С# объявлений, которые можно было бы сравнить.
Привожу исходнники тестовых программ, готовые к компиляции:
1) На языке C++ всё работает прекрасно
#include <stdio.h>
#include <conio.h>
#include <nwnet.h>
#include <nwcalls.h>
#include <nwlocale.h>
void main(int argc, char* argv[])
{
nint32 rcode;
nuint32 context;
unsigned int conn;
char Tree[50] = "zebra_tree";
char ServerName[50] = "zebra";
char UsrContext[50] = "org";
char UsrName[50] = "admin";
char UsrPwd[50] = "adminpwd";
rcode = NWCallsInit(0, 0);
if (rcode != 0)
printf("NWCallsInit returned %x", rcode);
LCONV lConvInfo, *plConvInfo;
plConvInfo = NWLlocaleconv(&lConvInfo);
lConvInfo = *plConvInfo;
rcode = NWInitUnicodeTables(lConvInfo.country_id, lConvInfo.code_page);
if (rcode != 0)
printf("NWInitUnicodeTables returned %x", rcode);
rcode = NWDSCreateContextHandle(&context);
if (rcode != 0)
printf("NWDSCreateContextHandle returned %x", rcode);
rcode = NWDSSetContext(context,
11, // DCK_TREE_NAME
Tree);
if (rcode != 0)
printf("NWDSSetContext returned %x", rcode);
rcode = NWDSSetContext(context,
3, // DCK_NAME_CONTEXT
UsrContext);
if (rcode != 0)
printf("NWDSSetContext returned %x", rcode);
rcode = NWDSLogin(context, 0, UsrName, UsrPwd, 0);
if (rcode != 0)
printf("NWDSLogin returned %x", rcode);
rcode = NWDSOpenConnToNDSServer(context, ServerName, &conn);
if (rcode != 0)
printf("NWDSOpenConnToNDSServer returned %x", rcode);
rcode = NWDSAuthenticateConn(context, conn);
if (rcode != 0)
printf("NWDSAuthenticateConn returned %x", rcode);
printf("Finish");
getch();
NWDSLogout(context);
NWDSFreeContext(context);
NWFreeUnicodeTables();
}
2) А вот при перехоле на C# возникает ошибка 0x8801 (в примере — у функции NWDSAuthenticateConn)
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace LoginTest
{
class Program
{
[DllImport("calwin32.dll", CharSet = CharSet.Ansi)]
public static extern int NWCallsInit(int _in, int _out);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class LCONV
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] decimal_point;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] thousands_sep;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] grouping;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public char[] int_curr_symbol;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] currency_symbol;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] mon_decimal_point;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] mon_thousands_sep;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public char[] mon_grouping;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] positive_sign;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] negative_sign;
public char int_frac_digits;
public char frac_digits;
public char p_cs_precedes;
public char p_sep_by_space;
public char n_cs_precedes;
public char n_sep_by_space;
public char p_sign_posn;
public char n_sign_posn;
public Int16 code_page;
public Int16 country_id;
public char data_list_separator;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] date_separator;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] time_separator;
public char time_format;
public Int16 date_format;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public char[] am;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public char[] pm;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public char[] reserved;
}
[DllImport("locwin32.dll", CharSet = CharSet.Ansi)]
public static extern LCONV NWLlocaleconv(LCONV lconvPtr);
[DllImport("locwin32.dll", CharSet = CharSet.Ansi)]
public static extern int NWInitUnicodeTables(Int16 countryCode, Int16 codePage);
[DllImport("locwin32.dll", CharSet = CharSet.Ansi)]
public static extern int NWFreeUnicodeTables();
[DllImport("netwin32.dll", CharSet = CharSet.Ansi)]
public static extern int NWDSCreateContextHandle(out UInt32 newHandle);
[DllImport("netwin32.dll", CharSet = CharSet.Ansi)]
public static extern int NWDSFreeContext(UInt32 context);
[DllImport("netwin32.dll", CharSet = CharSet.Ansi)]
public static extern int NWDSLogin(UInt32 context, UInt32 optionsFlag, string objectName, string password, UInt32 validityPeriod);
[DllImport("netwin32.dll", CharSet = CharSet.Ansi)]
public static extern Int16 NWDSAuthenticateConn(UInt32 context, UInt16 connHandle);
[DllImport("netwin32.dll", CharSet = CharSet.Ansi)]
public static extern int NWDSLogout(UInt32 context);
[DllImport("netwin32.dll", CharSet = CharSet.Ansi)]
public static extern int NWDSSetContext(UInt32 context, Int16 key, string value);
[DllImport("netwin32.dll", CharSet = CharSet.Ansi)]
public static extern Int16 NWDSOpenConnToNDSServer(UInt32 context, string serverName, out UInt16 connHandle);
static void Main(string[] args)
{
int rcode;
UInt32 context;
UInt16 conn;
string Tree = "zebra_tree";
string ServerName = "zebra";
string UsrContext = "org";
string UsrName = "admin";
string UsrPwd = "adminpwd";
try
{
rcode = NWCallsInit(0, 0);
if (rcode != 0)
Console.WriteLine("NWCallsInit returned {0:X}", rcode);
LCONV lConvInfo = new LCONV();
lConvInfo = NWLlocaleconv(lConvInfo);
rcode = NWInitUnicodeTables(lConvInfo.country_id, lConvInfo.code_page);
if (rcode != 0)
Console.WriteLine("NWInitUnicodeTables returned {0:X}", rcode);
rcode = NWDSCreateContextHandle(out context);
if (rcode != 0)
Console.WriteLine("NWDSCreateContextHandle returned {0:X}", rcode);
rcode = NWDSSetContext(context,
11, // DCK_TREE_NAME
Tree);
if (rcode != 0)
Console.WriteLine("NWDSSetContext1 returned {0:X}", rcode);
rcode = NWDSSetContext(context,
3, // DCK_NAME_CONTEXT
UsrContext);
if (rcode != 0)
Console.WriteLine("NWDSSetContext2 returned {0:X}", rcode);
rcode = NWDSLogin(context, 0, UsrName, UsrPwd, 0);
if (rcode != 0)
Console.WriteLine("NWDSLogin returned {0:X}", rcode);
rcode = NWDSOpenConnToNDSServer(context, ServerName, out conn);
if (rcode != 0)
Console.WriteLine("NWDSOpenConnToNDSServer returned {0:X}", rcode);
rcode = NWDSAuthenticateConn(context, conn);
if (rcode != 0)
Console.WriteLine("NWDSAuthenticateConn returned {0:X}", rcode);
Console.WriteLine("Finish");
Console.ReadKey();
NWDSLogout(context);
NWDSFreeContext(context);
NWFreeUnicodeTables();
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}", e.Message);
Console.ReadKey();
NWFreeUnicodeTables();
}
}
}
}
Результат повторяется на серверах NetWare 5.1 и 6.5.
Так почему же в приложении на языке C# соединение оказывается недействительным?
Здравствуйте, Roman_Zarubin, Вы писали:
R_Z>Программу на C++ я компилировал в Visual Studio 6.0 а там тип int 16битный.
Что ещё я упустил в своей жизни? char в VC6 занимает 8 байт?
Здравствуйте, adontz, Вы писали:
A>Что ещё я упустил в своей жизни? char в VC6 занимает 8 байт?
Да. char в VS6 занимает 8 бит.
Здравствуйте, adontz, Вы писали:
A>А чего это conn из 32битного стал 16битным?
Это ключ к решению проблемы...
Sorry, int в VC6 32битный
Теперь всё работает нормально.