Арифметическая операция привела к переполнению C#

Я получаю следующую ошибку при разблокировке файла

Арифметическая операция привела к переполнению

System.IntPtr.ToInt32

Я подозреваю, что это следующая строка pBuffer.ToInt32():

IntPtr iPtr = new IntPtr(pBuffer.ToInt32() + (i * Marshal.SizeOf(fi3)));

Я не могу воспроизвести ошибку самостоятельно, и ошибка не отображает правильный номер строки. Я ищу способ воспроизвести эту или любую обратную связь о возможной причине. Спасибо

public void Close()
{
        const int MAX_PREFERRED_LENGTH = -1;
        int readEntries;
        int totalEntries;
        IntPtr pBuffer = IntPtr.Zero;
        FILE_INFO_3 fi3 = new FILE_INFO_3();
        int iStatus = NetFileEnum(this.HostName, this.HostPathToShare + this.FileNameFromShare, null, 3, ref pBuffer, MAX_PREFERRED_LENGTH, out readEntries, out totalEntries, pBuffer);
        if (iStatus == 0)
        {
            for (int i = 0; i < readEntries; i++)
            {
                IntPtr iPtr = new IntPtr(pBuffer.ToInt32() + (i * Marshal.SizeOf(fi3)));
                fi3 = (FILE_INFO_3)Marshal.PtrToStructure(iPtr, typeof(FILE_INFO_3));
                NetFileClose(this.HostName, fi3.fi3_id);
            }
        }
        NetApiBufferFree(pBuffer);
}

[DllImport("netapi32.dll", SetLastError=true, CharSet = CharSet.Unicode)]
static extern int NetFileClose(
    string servername,
    int id);

[DllImport("Netapi32.dll", SetLastError=true)]
static extern int NetApiBufferFree(IntPtr Buffer);

[DllImport("netapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
static extern int NetFileEnum(
     string servername,
     string basepath,
     string username,
     int level,
     ref IntPtr bufptr,
     int prefmaxlen,
     out int entriesread,
     out int totalentries,
     IntPtr resume_handle
);

Обновить

Я добавил Win32 API-код.

Приведенные ниже ответы выглядят правильно и машина 64-битная. Но я не могу воспроизвести его на сервере dev, несмотря на то, что среда разработки 64-битная. Есть идеи по воспроизведению ошибки?

2 ответа

Решение

Ошибка вызвана тем, что ваш код работает в 64-битном контексте и возвращает адрес указателя, который находится за пределами диапазона, адресуемого 32-битным, поэтому .ToInt32() броски.

Вызовите Environment.Is64BitProcess, чтобы определить, работает ли ваш процесс в 32- или 64-разрядном режиме, и соответствующим образом преобразовать адрес:

long pointerAddress;

if (Environment.Is64BitProcess)
{
    pointerAddress = pBuffer.ToInt64(); 
}
else
{
    pointerAddress = pBuffer.ToInt32(); 
}

var fileInfoPointer = new IntPtr(pointerAddress + (i * Marshal.SizeOf(fi3)));

Я сразу вижу две ошибки в коде:

  1. Вы установили свой pBuffer до 0, и никогда не выделять его. Должно появиться сообщение об ошибке при передаче NetFileEnum, хотя это функция Win32 API, поэтому она может не заметить.

  2. Вы конвертируете pBuffer .ToInt32(), который должен работать, когда он специально скомпилирован для x86, но если в качестве целевой платформы у вас есть Any CPU или x64, это тоже будет проблемой.

Другие вопросы по тегам