Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

483 lines
14 KiB

#include <precomp.h>
#include "ErrCtrl.h"
#include "Utils.h"
#include "ArgParse.h"
//----------------------------------------------------
// Utility function for parsing an UINT type of argument;
DWORD
FnPaUint(LPWSTR *pwszArg, WCHAR wchTerm, UINT *pnValue)
{
DWORD dwErr = ERROR_SUCCESS;
UINT nValue = 0;
LPWSTR wszArg = (*pwszArg);
if (*wszArg == L'\0' || *wszArg == wchTerm)
dwErr = ERROR_BAD_FORMAT;
else
{
for (nValue = 0; *wszArg != L'\0' && iswdigit(*wszArg); wszArg++)
{
if (*wszArg == wchTerm)
break;
nValue = nValue * 10 + ((*wszArg) - L'0');
}
if (*wszArg != wchTerm)
dwErr = ERROR_BAD_FORMAT;
else if (pnValue != NULL)
*pnValue = nValue;
}
*pwszArg = wszArg;
SetLastError(dwErr);
return dwErr;
}
//----------------------------------------------------
// Utility function for parsing two hexa digits (one byte)
DWORD
FnPaByte(LPWSTR *pwszArg, BYTE *pbtValue)
{
DWORD dwErr = ERROR_SUCCESS;
BYTE btValue = 0;
LPWSTR wszArg = (*pwszArg);
if (iswxdigit(*wszArg))
{
btValue = HEX(*wszArg);
wszArg++;
}
else
dwErr = ERROR_BAD_FORMAT;
if (dwErr == ERROR_SUCCESS && iswxdigit(*wszArg))
{
btValue <<= 4;
btValue |= HEX(*wszArg);
wszArg++;
}
else
dwErr = ERROR_BAD_FORMAT;
if (dwErr == ERROR_SUCCESS && pbtValue != NULL)
*pbtValue = btValue;
*pwszArg = wszArg;
SetLastError(dwErr);
return dwErr;
}
//----------------------------------------------------
// Utility function for common postprocessing of argument parsing routines
DWORD
FnPaPostProcess(DWORD dwErr, PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry)
{
if (dwErr == ERROR_SUCCESS)
{
// it is guaranteed that when parsing the argument of a parameter
// the parameter itself is encountered for the first time. Consequently
// there is no need for checking whether this argumented param ever occured before.
pPDData->dwArgumentedParams |= pPDEntry->nParamID;
}
SetLastError(dwErr);
return dwErr;
}
//----------------------------------------------------
// Parser for the Guid type of argument
DWORD
FnPaGuid(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
{
DWORD dwErr = ERROR_SUCCESS;
LPWSTR wszGuid = NULL;
UINT nGuidLen = wcslen(wszParamArg);
if (nGuidLen < 1)
dwErr = ERROR_BAD_FORMAT;
if (dwErr == ERROR_SUCCESS)
{
// create a buffer for the GUID
wszGuid = MemCAlloc((nGuidLen + 1) * sizeof(WCHAR));
if (wszGuid == NULL)
dwErr = GetLastError();
}
if (dwErr == ERROR_SUCCESS)
{
wcscpy(wszGuid, wszParamArg);
MemFree(pPDData->wzcIntfEntry.wszGuid);
// copy the GUID into the param descriptors data
pPDData->wzcIntfEntry.wszGuid = wszGuid;
}
return FnPaPostProcess(dwErr, pPDData, pPDEntry);
}
//----------------------------------------------------
// Parser for the argument of the "mask" parameter
DWORD
FnPaMask(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
{
DWORD dwErr = ERROR_SUCCESS;
NDIS_802_11_NETWORK_INFRASTRUCTURE ndIm;
dwErr = FnPaUint(&wszParamArg, L'\0', (UINT *)&ndIm);
if (dwErr == ERROR_SUCCESS)
{
if (ndIm > Ndis802_11AutoUnknown)
dwErr = ERROR_INVALID_DATA;
else
{
pPDData->wzcIntfEntry.dwCtlFlags &= ~INTFCTL_CM_MASK;
pPDData->wzcIntfEntry.dwCtlFlags |= ndIm;
}
}
return FnPaPostProcess(dwErr, pPDData, pPDEntry);
}
//----------------------------------------------------
// Parser for the argument of the "enabled" parameter
DWORD
FnPaEnabled(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
{
DWORD dwErr = ERROR_SUCCESS;
BOOL bEnabled;
dwErr = FnPaUint(&wszParamArg, L'\0', (UINT *)&bEnabled);
if (dwErr == ERROR_SUCCESS)
{
if (bEnabled > 1)
dwErr = ERROR_INVALID_DATA;
else if (bEnabled)
pPDData->wzcIntfEntry.dwCtlFlags |= INTFCTL_ENABLED;
else
pPDData->wzcIntfEntry.dwCtlFlags &= ~INTFCTL_ENABLED;
}
return FnPaPostProcess(dwErr, pPDData, pPDEntry);
}
//----------------------------------------------------
// Parser for the argument of the "ssid" parameter
DWORD
FnPaSsid(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
{
DWORD dwErr = ERROR_SUCCESS;
UINT nSsidWLen = wcslen(wszParamArg);
UINT nSsidALen;
LPBYTE pbtSsid = NULL;
// ssid is hardcoded to 32 bytes in ntddndis.h
pbtSsid = MemCAlloc(33);
if (pbtSsid == NULL)
dwErr = GetLastError();
// trim out the '"' if any
if (dwErr == ERROR_SUCCESS &&
nSsidWLen > 2 && wszParamArg[0] == L'"' && wszParamArg[nSsidWLen-1] == '"')
{
wszParamArg++; nSsidWLen-=2;
wszParamArg[nSsidWLen+1] = L'\0';
}
if (dwErr == ERROR_SUCCESS)
{
nSsidALen = WideCharToMultiByte(
CP_ACP,
0,
wszParamArg,
wcslen(wszParamArg)+1,
pbtSsid,
33,
NULL,
NULL);
// the call above includes the '\0' in the count of
// characters converted. Normalize the length then,
// (failure => all "f"s which is higher than 32 hence error)
nSsidALen--;
// a valid SSID should contain at least 1 char, and no more than 32
if (nSsidALen < 1 || nSsidALen > 32)
dwErr = ERROR_INVALID_DATA;
}
if (dwErr == ERROR_SUCCESS)
{
pPDData->wzcIntfEntry.rdSSID.dwDataLen = nSsidALen;
pPDData->wzcIntfEntry.rdSSID.pData = pbtSsid;
}
else
MemFree(pbtSsid);
return FnPaPostProcess(dwErr, pPDData, pPDEntry);
}
//----------------------------------------------------
// Parser for the argument of the "bssid" parameter
DWORD
FnPaBssid(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
{
DWORD dwErr = ERROR_SUCCESS;
PNDIS_802_11_MAC_ADDRESS pndMac = NULL;
UINT i;
// allocate space for the mac address
pndMac = MemCAlloc(sizeof(NDIS_802_11_MAC_ADDRESS));
if (pndMac == NULL)
dwErr = GetLastError();
for (i = 0; dwErr == ERROR_SUCCESS && i < sizeof(NDIS_802_11_MAC_ADDRESS); i++)
{
dwErr = FnPaByte(&wszParamArg, &((*pndMac)[i]));
if (dwErr == ERROR_SUCCESS)
{
if (i != sizeof(NDIS_802_11_MAC_ADDRESS)-1 && *wszParamArg == L':')
wszParamArg++;
else if (i != sizeof(NDIS_802_11_MAC_ADDRESS)-1 || *wszParamArg != L'\0')
dwErr = ERROR_BAD_FORMAT;
}
}
if (dwErr == ERROR_SUCCESS)
{
pPDData->wzcIntfEntry.rdBSSID.dwDataLen = sizeof(NDIS_802_11_MAC_ADDRESS);
pPDData->wzcIntfEntry.rdBSSID.pData = (LPBYTE)pndMac;
}
else
{
MemFree(pndMac);
}
return FnPaPostProcess(dwErr, pPDData, pPDEntry);
}
//----------------------------------------------------
// Parser for the argument of the "im" parameter
DWORD
FnPaIm(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
{
DWORD dwErr = ERROR_SUCCESS;
NDIS_802_11_NETWORK_INFRASTRUCTURE ndIm;
dwErr = FnPaUint(&wszParamArg, L'\0', (UINT *)&ndIm);
if (dwErr == ERROR_SUCCESS)
{
if (ndIm > Ndis802_11Infrastructure)
dwErr = ERROR_INVALID_DATA;
else
pPDData->wzcIntfEntry.nInfraMode = ndIm;
}
return FnPaPostProcess(dwErr, pPDData, pPDEntry);
}
//----------------------------------------------------
// Parser for the argument of the "am" parameter
DWORD
FnPaAm(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
{
DWORD dwErr = ERROR_SUCCESS;
NDIS_802_11_AUTHENTICATION_MODE ndAm;
dwErr = FnPaUint(&wszParamArg, L'\0', (UINT *)&ndAm);
if (dwErr == ERROR_SUCCESS)
{
if (ndAm > Ndis802_11AuthModeShared)
dwErr = ERROR_INVALID_DATA;
else
pPDData->wzcIntfEntry.nAuthMode = ndAm;
}
return FnPaPostProcess(dwErr, pPDData, pPDEntry);
}
//----------------------------------------------------
// Parser for the argument of the "priv" parameter
DWORD
FnPaPriv(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
{
DWORD dwErr = ERROR_SUCCESS;
NDIS_802_11_WEP_STATUS ndEncr;
dwErr = FnPaUint(&wszParamArg, L'\0', (UINT *)&ndEncr);
if (dwErr == ERROR_SUCCESS)
{
if (ndEncr != Ndis802_11WEPDisabled &&
ndEncr != Ndis802_11WEPEnabled)
dwErr = ERROR_INVALID_DATA;
else
{
// change the semantic of nWepStatus according to XP SP (which expects a boolean!)
pPDData->wzcIntfEntry.nWepStatus = ndEncr == Ndis802_11WEPDisabled ? 0 : 1;
}
}
return FnPaPostProcess(dwErr, pPDData, pPDEntry);
}
//----------------------------------------------------
// Parser for the argument of the "key" parameter
DWORD
FnPaKey(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
{
DWORD dwErr = ERROR_SUCCESS;
UINT nKIdx, nKLen;
BOOL bIsHex;
PNDIS_802_11_WEP pndKey = NULL;
// get the key index
dwErr = FnPaUint(&wszParamArg, L':', &nKIdx);
// check whether the key index is within permitted values
if (dwErr == ERROR_SUCCESS && (nKIdx < 1 || nKIdx > 4))
dwErr = ERROR_INVALID_DATA;
// check the key material length
if (dwErr == ERROR_SUCCESS)
{
wszParamArg++;
nKLen = wcslen(wszParamArg);
// trim out the '"' if any
if (nKLen > 2 && wszParamArg[0] == L'"' && wszParamArg[nKLen-1] == '"')
{
wszParamArg++; nKLen-=2;
}
switch (nKLen)
{
case 10: // 5 bytes = 40 bits
case 26: // 13 bytes = 104 bits
case 32: // 16 bytes = 128 bits
nKLen >>= 1;
bIsHex = TRUE;
break;
case 5: // 5 bytes = 40 bits
case 13: // 13 bytes = 104 bits
case 16: // 16 bytes = 128 bits
bIsHex = FALSE;
break;
default:
dwErr = ERROR_BAD_LENGTH;
break;
}
}
// allocate space for the key material
if (dwErr == ERROR_SUCCESS)
{
pndKey = MemCAlloc(FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial) + nKLen);
if (pndKey == NULL)
dwErr = GetLastError();
else
{
pndKey->Length = FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial) + nKLen;
pndKey->KeyIndex = nKIdx-1;
pndKey->KeyLength = nKLen;
}
}
// parse the key material and fill it in the allocated space
if (dwErr == ERROR_SUCCESS)
{
if (bIsHex)
{
UINT i;
for (i = 0; dwErr == ERROR_SUCCESS && i < pndKey->KeyLength; i++)
dwErr = FnPaByte(&wszParamArg, &(pndKey->KeyMaterial[i]));
}
else
{
UINT nAnsi;
nAnsi = WideCharToMultiByte(
CP_ACP,
0,
wszParamArg,
nKLen,
pndKey->KeyMaterial,
pndKey->KeyLength,
NULL,
NULL);
if (nAnsi != pndKey->KeyLength)
dwErr = ERROR_BAD_FORMAT;
else
wszParamArg += pndKey->KeyLength;
}
}
// if the key material proved to be correct, then pass the data in the pPDData
if (dwErr == ERROR_SUCCESS)
{
_Asrt(*wszParamArg == L'\0' ||
*wszParamArg == L'"',
L"Code bug - key length incorrectly inferred.\n");
pPDData->wzcIntfEntry.rdCtrlData.dwDataLen = pndKey->Length;
pPDData->wzcIntfEntry.rdCtrlData.pData = (LPBYTE)pndKey;
}
else
{
MemFree(pndKey);
}
return FnPaPostProcess(dwErr, pPDData, pPDEntry);;
}
//----------------------------------------------------
// Parser for the boolean argument for the "onex" parameter
DWORD
FnPaOneX(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
{
DWORD dwErr = ERROR_SUCCESS;
BOOL bOneX;
dwErr = FnPaUint(&wszParamArg, L'\0', (UINT *)&bOneX);
if (dwErr == ERROR_SUCCESS)
{
if (bOneX != TRUE && bOneX != FALSE)
dwErr = ERROR_INVALID_DATA;
else
{
// save the parameter's argument
pPDData->bOneX = bOneX;
}
}
return FnPaPostProcess(dwErr, pPDData, pPDEntry);
}
//----------------------------------------------------
// Parser for the "outfile" file name parameter
FnPaOutFile(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
{
FILE *pfOut;
DWORD dwErr = ERROR_SUCCESS;
pfOut = _wfopen(wszParamArg, L"a+");
if (pfOut == NULL)
dwErr = GetLastError();
if (dwErr == ERROR_SUCCESS)
{
CHAR szCrtDate[32];
CHAR szCrtTime[32];
pPDData->pfOut = pfOut;
fprintf(pPDData->pfOut,"\n\n[%s - %s]\n",
_strdate(szCrtDate), _strtime(szCrtTime));
}
return FnPaPostProcess(dwErr, pPDData, pPDEntry);
}