📄 cardif_windows_wireless.c
字号:
**/
void cardif_windows_wireless_parse_ies(context *ctx, uint8_t *iedata, int ielen)
{
int i = 0;
int wpalen = 0;
uint8_t wpaie[255];
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return;
if (!xsup_assert((iedata != NULL), "iedata != NULL", FALSE))
return;
if (!xsup_assert((ielen > 0), "ielen > 0", FALSE))
return;
if (cardif_windows_wireless_find_wpa_ie(ctx, iedata, ielen, wpaie, &wpalen) == XENONE)
{
// We have a valid IE, save it.
config_ssid_update_abilities(ctx->intTypeData, WPA_IE);
config_ssid_add_wpa_ie(ctx->intTypeData, wpaie, wpalen);
}
if (cardif_windows_wireless_find_wpa2_ie(ctx, iedata, ielen, wpaie, &wpalen) == XENONE)
{
// We have a valid IE, save it.
config_ssid_update_abilities(ctx->intTypeData, RSN_IE);
config_ssid_add_rsn_ie(ctx->intTypeData, wpaie, wpalen);
}
}
/**
* \brief Enumerate the IOCTLs that this interface can use.
*
* @param[in] ctx The context that contains the information that we need to use
* to enumerate the IOCTLs, and make a decision.
*
* \retval 0 if we can't determine which wireless calls to use.
* \retval 1 if we should use the XP calls
* \retval 2 if we should use the Vista calls
**/
int cardif_windows_use_new_ioctls(context *ctx)
{
DWORD BytesReturned = 0;
DWORD result = 0;
UCHAR QueryBuffer[4096];
PNDISPROT_QUERY_OID pQueryOid = NULL;
struct win_sock_data *sockData = NULL;
LPVOID lpMsgBuf = NULL;
DWORD *vals = NULL;
int count = 0, i = 0, x = 0;
int retval = 0;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return 0;
sockData = (struct win_sock_data *)ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE))
return 0;
pQueryOid = (PNDISPROT_QUERY_OID)&QueryBuffer[0];
pQueryOid->Oid = OID_GEN_SUPPORTED_LIST;
result = devioctl(sockData->devHandle, IOCTL_NDISPROT_QUERY_OID_VALUE,
(LPVOID)&QueryBuffer[0], sizeof(QueryBuffer),
(LPVOID)&QueryBuffer[0], sizeof(QueryBuffer), &BytesReturned);
if ((result != WAIT_OBJECT_0) && (result != WAIT_IO_COMPLETION))
{
if (result == 0xffffffff)
{
debug_printf(DEBUG_NORMAL, "IOCTL returned that it doesn't know how to enumerate OIDs!\n");
return 0;
}
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_GETTING_BSSID, ctx->desc);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Enum IOCTLs IOCTL failed on interface '%s'. Error was : %s\n",
ctx->desc, lpMsgBuf);
LocalFree(lpMsgBuf);
return 0;
}
vals = pQueryOid->Data;
count = ((BytesReturned - sizeof(NDIS_OID)) / sizeof(DWORD));
debug_printf(DEBUG_INT, "Found %d OIDs in the table.\n", count);
x = -1;
retval = 2; // Assume we can handle the needed IOCTLs, until we decide otherwise.
debug_printf(DEBUG_INT, "\n------- Checking for Current Gen IOCTLs -------\n");
while (((++x) >= 0) && (newoidsneeded[x].oid != 0) && (retval == 2))
{
i = 0;
while (((++i) <= count) && (newoidsneeded[x].oid != vals[i]));
if (i <= count)
{
debug_printf(DEBUG_INT, "Found IOCTL for %s.\n", newoidsneeded[x].oidname);
}
else
{
retval = 0;
}
}
if (retval == 2) goto done;
x = -1;
retval = 1; // Assume we can handle the needed IOCTLs, until we decide otherwise.
debug_printf(DEBUG_INT, "\n------- Checking for Last Gen IOCTLs -------\n");
while (((++x) >= 0) && (oldoidsneeded[x].oid != 0) && (retval == 1))
{
i = 0;
while (((++i) <= count) && (oldoidsneeded[x].oid != vals[i]));
if (i <= count)
{
debug_printf(DEBUG_INT, "Found IOCTL for %s.\n", oldoidsneeded[x].oidname);
}
else
{
retval = 0;
}
}
done:
return retval;
}
/**
* \brief Check to see if the context supports the authmode requested. If it does,
* it will return true, if not it will throw an error to the UI.
*
* @param[in] ctx The context for the interface that we think the authmode is invalid for.
* @param[in] authmode The authmode as defined by the Windows headers.
*
* \retval TRUE if the authmode is supported.
* \retval FALSE if the authmode isn't supported (this function will also send out a UI error message)
**/
int cardif_windows_authmode_supported_in_ctx(context *ctx, DWORD authmode)
{
int retval = TRUE;
wireless_ctx *wctx = NULL;
if (ctx->intType != ETH_802_11_INT) return retval;
wctx = ctx->intTypeData;
if (wctx == NULL) return retval;
switch (authmode)
{
case Ndis802_11AuthModeWPA:
if (!TEST_FLAG(wctx->enc_capa, DOES_WPA))
{
debug_printf(DEBUG_NORMAL, "Attempted to set the authentication mode to WPA when the card doesn't appear to support it.\n");
ipc_events_error(ctx, IPC_EVENT_ERROR_NOT_SUPPORTED, "WPA");
retval = FALSE;
}
break;
case Ndis802_11AuthModeWPA2:
if (!TEST_FLAG(wctx->enc_capa, DOES_WPA2))
{
debug_printf(DEBUG_NORMAL, "Attempted to set the authentication mode to WPA2 when the card doesn't appear to support it.\n");
ipc_events_error(ctx, IPC_EVENT_ERROR_NOT_SUPPORTED, "WPA2");
retval = FALSE;
}
break;
}
return retval;
}
/**
* Set the authentication (as in 802.11, not 802.1X) mode that we will be using to
* create an association with the AP.
**/
int cardif_windows_set_auth_mode(context *ctx, DWORD authmode, int throwError)
{
DWORD Bytes = 0;
UCHAR Buffer[sizeof(NDIS_OID)+sizeof(DWORD)];
PNDISPROT_SET_OID pSetOid = NULL;
struct win_sock_data *sockData = NULL;
DWORD *mode = NULL;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return -1;
sockData = ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE)) return -1;
pSetOid = (PNDISPROT_SET_OID)&Buffer[0];
pSetOid->Oid = OID_802_11_AUTHENTICATION_MODE;
mode = (DWORD *)&pSetOid->Data[0];
(*mode) = authmode;
SetLastError(0);
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE,
(LPVOID)&Buffer[0], sizeof(Buffer), NULL, 0, &Bytes) == FALSE)
{
// Only scream if we believe this should have worked.
if (GetLastError() != ERROR_NOT_READY)
{
if (throwError == TRUE)
{
// If the auth mode isn't supported the call below will throw the error to the UI.
if (cardif_windows_authmode_supported_in_ctx(ctx, authmode) == TRUE)
{
debug_printf(DEBUG_NORMAL, "Attempt to set authentication mode for interface '%s' failed!\n",
ctx->desc);
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_802_11_AUTH_MODE, ctx->desc);
}
}
}
else
{
debug_printf(DEBUG_NORMAL, "'%s' indicated it wasn't ready yet. We will try again later.\n", ctx->desc);
}
return -1;
}
return XENONE;
}
/**
* \brief Check to see if an encryption mode is included in what the context discovered about
* the interface.
*
* @param[in] ctx The context for the interface that we want to check.
* @param[in] encmode The encryption mode that we attempted to enable.
*
* \retval TRUE if the encryption mode is supported
* \retval FALSE if it is not (this function will send a message to the UI)
**/
int cardif_windows_enc_supported_in_ctx(context *ctx, DWORD encmode)
{
int retval = TRUE;
wireless_ctx *wctx = NULL;
if (ctx->intType != ETH_802_11_INT) return retval;
wctx = ctx->intTypeData;
if (wctx == NULL) return retval;
switch (encmode)
{
case Ndis802_11Encryption1Enabled:
if (!TEST_FLAG(wctx->flags, DOES_WEP104))
{
debug_printf(DEBUG_NORMAL, "Attempted to enable WEP encryption, but the interface doesn't seem to support it.\n");
ipc_events_error(ctx, IPC_EVENT_ERROR_NOT_SUPPORTED, "WEP encryption");
retval = FALSE;
}
break;
case Ndis802_11Encryption2Enabled:
if (!TEST_FLAG(wctx->flags, DOES_TKIP))
{
debug_printf(DEBUG_NORMAL, "Attempted to enable TKIP encryption, but the interface doesn't seem to support it.\n");
ipc_events_error(ctx, IPC_EVENT_ERROR_NOT_SUPPORTED, "TKIP encryption");
retval = FALSE;
}
break;
case Ndis802_11Encryption3Enabled:
if (!TEST_FLAG(wctx->flags, DOES_CCMP))
{
debug_printf(DEBUG_NORMAL, "Attempted to enable CCMP encryption, but the interface doesn't seem to support it.\n");
ipc_events_error(ctx, IPC_EVENT_ERROR_NOT_SUPPORTED, "CCMP encryption");
retval = FALSE;
}
break;
}
return retval;
}
/**
* Set the encryption mode. On Windows, this sets which encryption methods are allowed.
*
* From the Windows DDK documentation :
*
* Encryption modes define the set of cipher suites that can be enabled on the 802.11 device:
*
* Encryption1
* WEP encryption is supported and enabled on the device. The device either does not support TKIP and AES or these cipher suites are disabled.
* The WEP cipher suite as defined through this OID uses either 40 bit or 104 bit key lengths. Other extended key lengths are not supported for the WEP cipher suite.
*
* Encryption2
* WEP and TKIP encryption are supported and enabled on the device. The device either does not support AES or this cipher suite is disabled.
*
* Encryption3
* WEP, TKIP, and AES encryption are supported and enabled on the device.
* The AES cipher suite as defined through this OID is AES-CCMP. If the device supports other variants of the AES cipher suite, it cannot advertise support for the Encryption3 encryption mode unless the device also supports AES-CCMP.
**/
int cardif_windows_set_enc_mode(context *ctx, DWORD encmode, int throwError)
{
DWORD BytesReturned = 0;
UCHAR Buffer[sizeof(NDIS_OID)+sizeof(DWORD)];
PNDISPROT_SET_OID pSetOid = NULL;
struct win_sock_data *sockData = NULL;
DWORD *mode = NULL;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return -1;
sockData = ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE)) return -1;
pSetOid = (PNDISPROT_SET_OID)&Buffer[0];
pSetOid->Oid = OID_802_11_ENCRYPTION_STATUS;
mode = (DWORD *)&pSetOid->Data[0];
(*mode) = encmode;
SetLastError(0);
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE,
(LPVOID)&Buffer[0], sizeof(Buffer), NULL, 0, &BytesReturned) == FALSE)
{
// Only scream if we believe this should have worked.
if (GetLastError() != ERROR_NOT_READY)
{
if (throwError == TRUE)
{
if (cardif_windows_enc_supported_in_ctx(ctx, encmode) == TRUE)
{
debug_printf(DEBUG_NORMAL, "Attempt to set encryption mode for interface '%s' failed!\n",
ctx->desc);
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_802_11_ENC_MODE, ctx->desc);
}
}
}
else
{
debug_printf(DEBUG_NORMAL, "'%s' indicated it wasn't ready yet. We will try again later.\n", ctx->desc);
}
return -1;
}
return XENONE;
}
/**
* Set the card in to infrastructure mode. This will case all keys to be deleted.
**/
int cardif_windows_set_infra_mode(context *ctx)
{
DWORD BytesReturned = 0;
UCHAR Buffer[sizeof(NDIS_OID)+sizeof(DWORD)];
PNDISPROT_SET_OID pSetOid = NULL;
struct win_sock_data *sockData = NULL;
DWORD *mode = NULL;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return -1;
sockData = ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE)) return -1;
pSetOid = (PNDISPROT_SET_OID)&Buffer[0];
pSetOid->Oid = OID_802_11_INFRASTRUCTURE_MODE;
mode = (DWORD *)&pSetOid->Data[0];
(*mode) = Ndis802_11Infrastructure;
SetLastError(0);
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE,
(LPVOID)&Buffer[0], sizeof(Buffer), NULL, 0, &BytesReturned) == FALSE)
{
if (GetLastError() == ERROR_NOT_READY) // The interface wasn't ready yet.
{
debug_printf(DEBUG_NORMAL, "Attempt to set infrastructure mode for interface '%s' failed. The interface reported it isn't ready yet.\n");
}
else
{
debug_printf(DEBUG_NORMAL, "Attempt to set infrastructure mode for interface '%s' failed! (Error : %d)\n",
ctx->desc, GetLastError());
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_802_11_INFRA_MODE, ctx->desc);
}
return -1;
}
return XENONE;
}
#if 0
void cardif_windows_get_events(void *pValue)
{
unsigned char Buffer[2048];
PNDISPROT_INDICATE_STATUS pData = NULL;
context *ctx = NULL;
DWORD BytesReturned;
struct win_sock_data *sockData = NULL;
ctx = (context *)pValue;
sockData = ctx->sockData;
pData = (NDISPROT_INDICATE_STATUS *)&Buffer;
printf("Set up event listener for %d\n", sockData->devHandle);
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_INDICATE_STATUS,
pData, sizeof(Buffer), (LPVOID)pData, sizeof(Buffer), &BytesReturned) == FALSE)
{
debug_printf(DEBUG_NORMAL, "No event!\n");
printf("No event!\n");
//ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_802_11_INFRA_MODE, ctx->desc);
return;
}
printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Got an event. id %d\n", pData->IndicatedStatus);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -