RAS API. sizeof (RASDIALPARAMS) неверно. Ошибка 632

Я работаю с RAS API под Windows 7 x32. Следующая функция возвращает ошибку 632 (ERROR_INVALID_SIZE):

int32_t set_username_passwd(wchar_t *entry_title)
{
RASDIALPARAMS ras_param;
ZeroMemory(&ras_param, sizeof(RASDIALPARAMS));
ras_param.dwSize = sizeof(RASDIALPARAMS);
memcpy(ras_param.szEntryName, entry_title, wcslen(entry_title));
memcpy(ras_param.szUserName, L"username", wcslen(L"username"));
memcpy(ras_param.szPassword, L"password", wcslen(L"password"));
return RasSetEntryDialParams(0, &ras_param, 0);
}

sizeof(RASDIALPARAMS) возвращает неправильный размер? Как это могло произойти?

Или что мне не хватает?

0

Решение

RASDIALPARAMS За последние годы в него были добавлены новые поля:

#define RASDIALPARAMSW struct tagRASDIALPARAMSW
RASDIALPARAMSW
{
DWORD dwSize;
WCHAR szEntryName[ RAS_MaxEntryName + 1 ];
WCHAR szPhoneNumber[ RAS_MaxPhoneNumber + 1 ];
WCHAR szCallbackNumber[ RAS_MaxCallbackNumber + 1 ];
WCHAR szUserName[ UNLEN + 1 ];
WCHAR szPassword[ PWLEN + 1 ];
WCHAR szDomain[ DNLEN + 1 ];
#if (WINVER >= 0x401) // 95/NT4 and later
DWORD dwSubEntry;
ULONG_PTR dwCallbackId;
#endif
#if (WINVER >= 0x601) // Windows 7 and later
DWORD dwIfIndex;
#endif
};

Таким образом, размер RASDIALPARAMS тот RasSetEntryDialParams() Ожидается, зависит от конкретной версии Windows. Но фактический размер RASDIALPARAMS внутри вашего приложения зависит от WINVER определить во время компиляции, как показано выше.

Таким образом, при ориентации на Windows 7, WINVER должно быть установлено значение, по крайней мере, 0x601 (Windows 7 v6.1). Если вы компилируете с более низким WINVER значение, то размер RASDIALPARAMS будет слишком маленьким для Windows 7, чтобы принять.

Если вы установите WINVER для более высокого значения, чем версия Windows, на которую вы нацелены, вы можете определить версию ОС во время выполнения и установить ras_param.dwSize до соответствующего размера с sizeof(RASDIALPARAMS) будет больше, чем что RasSetEntryDialParams() ожидает. Например:

int32_t set_username_passwd(wchar_t *entry_title)
{
RASDIALPARAMSW ras_param;
ZeroMemory(&ras_param, sizeof(ras_param));

OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(osvi));

GetVersionEx(&osvi);

#if (WINVER >= 0x401)
if ((osvi.dwMajorVersion < 4) ||
((osvi.dwMajorVersion == 4) && (osvi.dwMinVersion < 1)) )
{
ras_param.dwSize = offsetof(RASDIALPARAMSW, dwSubEntry);
}
else
#endif
#if (WINVER >= 0x601)
if ((osvi.dwMajorVersion < 6) ||
((osvi.dwMajorVersion == 6) && (osvi.dwMinVersion < 1)) )
{
ras_param.dwSize = offsetof(RASDIALPARAMSW, dwIfIndex);
}
else
#endif
{
ras_param.dwSize = sizeof(ras_param);
}

wcsncpy(ras_param.szEntryName, entry_title, RAS_MaxEntryName);
wcsncpy(ras_param.szUserName, L"username", UNLEN);
wcsncpy(ras_param.szPassword, L"password", PWLEN);

return RasSetEntryDialParamsW(0, &ras_param, 0);
}

Кроме того, вы можете пропустить проверку ОС и просто обработать ERROR_INVALID_SIZE ошибка вместо:

int32_t set_username_passwd(wchar_t *entry_title)
{
RASDIALPARAMSW ras_param;
ZeroMemory(&ras_param, sizeof(ras_param));

ras_param.dwSize = sizeof(ras_param);
wcsncpy(ras_param.szEntryName, entry_title, RAS_MaxEntryName);
wcsncpy(ras_param.szUserName, L"username", UNLEN);
wcsncpy(ras_param.szPassword, L"password", PWLEN);

DWORD dwRet = RasSetEntryDialParamsW(0, &ras_param, 0);
#if (WINVER >= 0x601)
if (dwRet == ERROR_INVALID_SIZE)
{
ras_param.dwSize = offsetof(RASDIALPARAMSW, dwIfIndex);
dwRet = RasSetEntryDialParamsW(0, &ras_param, 0);
}
#elif (WINVER >= 0x401)
if (dwRet == ERROR_INVALID_SIZE)
{
ras_param.dwSize = offsetof(RASDIALPARAMSW, dwSubEntry);
dwRet = RasSetEntryDialParamsW(0, &ras_param, 0);
}
#endif

return dwRet;
}
4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]