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.
 
 
 
 
 
 

424 lines
12 KiB

#include "precomp.h"
#include <wininet.h>
#include <regstr.h>
// Private forward decalarations
static LPCTSTR mapSingleDw2Psz(PCMAPDW2PSZ pMap, UINT cEntries, DWORD dw, BOOL fFailNotFound = FALSE);
ULONG CoTaskMemSize(LPVOID pv)
{
IMalloc *p;
HRESULT hr;
if (pv == NULL)
return 0;
hr = CoGetMalloc(1, &p);
if (FAILED(hr))
return 0;
return (ULONG)p->GetSize(pv);
}
UINT CoStringFromGUID(REFGUID rguid, LPTSTR pszBuf, UINT cchBuf)
{
WCHAR wszGuid[128];
UINT nSize;
nSize = StringFromGUID2(rguid, wszGuid, countof(wszGuid));
W2Tbuf(wszGuid, pszBuf, cchBuf);
return nSize;
}
LPCTSTR GetHrSz(HRESULT hr)
{
static MAPDW2PSZ mapHr[] = {
// real HRESULTs
DW2PSZ_PAIR(S_OK),
DW2PSZ_PAIR(S_FALSE),
DW2PSZ_PAIR(E_UNEXPECTED),
DW2PSZ_PAIR(E_NOTIMPL),
DW2PSZ_PAIR(E_OUTOFMEMORY),
DW2PSZ_PAIR(E_INVALIDARG),
DW2PSZ_PAIR(E_NOINTERFACE),
DW2PSZ_PAIR(E_POINTER),
DW2PSZ_PAIR(E_HANDLE),
DW2PSZ_PAIR(E_ABORT),
DW2PSZ_PAIR(E_FAIL),
DW2PSZ_PAIR(E_ACCESSDENIED),
DW2PSZ_PAIR(CO_E_NOTINITIALIZED),
DW2PSZ_PAIR(CO_E_ALREADYINITIALIZED),
DW2PSZ_PAIR(CO_E_DLLNOTFOUND),
DW2PSZ_PAIR(CO_E_APPNOTFOUND),
DW2PSZ_PAIR(CO_E_ERRORINDLL),
DW2PSZ_PAIR(CO_E_APPDIDNTREG),
DW2PSZ_PAIR(RPC_E_CHANGED_MODE),
DW2PSZ_PAIR(REGDB_E_CLASSNOTREG),
DW2PSZ_PAIR(REGDB_E_READREGDB),
DW2PSZ_PAIR(REGDB_E_IIDNOTREG),
DW2PSZ_PAIR(CLASS_E_NOAGGREGATION),
DW2PSZ_PAIR(STG_E_FILENOTFOUND),
DW2PSZ_PAIR(STG_E_PATHNOTFOUND),
DW2PSZ_PAIR(TRUST_E_NOSIGNATURE),
DW2PSZ_PAIR(TRUST_E_FAIL),
DW2PSZ_PAIR(TRUST_E_SUBJECT_NOT_TRUSTED),
// win32 errors
DW2PSZ_PAIR(ERROR_FILE_NOT_FOUND),
DW2PSZ_PAIR(ERROR_PATH_NOT_FOUND),
// wininet errors
DW2PSZ_PAIR(ERROR_INTERNET_INTERNAL_ERROR)
};
LPCTSTR pszResult;
pszResult = mapSingleDw2Psz(mapHr, countof(mapHr), hr, TRUE);
if (pszResult != NULL)
return pszResult;
// error from HRESULT_FROM_WIN32
if (hr < 0 && (hr & (FACILITY_WIN32 << 16)) == (FACILITY_WIN32 << 16))
hr &= 0x0000FFFF; // only LOWORD matters
return mapSingleDw2Psz(mapHr, countof(mapHr), hr);
}
DWORD GetStringField(LPTSTR szStr, UINT uField, LPTSTR szBuf, UINT cchBufSize)
{
LPTSTR pszBegin = szStr;
LPTSTR pszEnd;
TCHAR cSeparator;
UINT i = 0;
DWORD dwToCopy;
if(cchBufSize == 0)
return 0;
szBuf[0] = TEXT('\0');
if(szStr == NULL)
return 0;
// figure out whether we're looking for commas or periods
if (StrChr(szStr, TEXT(',')))
cSeparator = TEXT(',');
else
{
if (StrChr(szStr, TEXT('.')))
cSeparator = TEXT('.');
else
return 0;
}
while(pszBegin && *pszBegin != TEXT('\0') && i < uField)
{
pszBegin = StrChr(pszBegin, cSeparator);
if(pszBegin && (*pszBegin != TEXT('\0')))
pszBegin++;
i++;
}
// we reached end of string, no field
if(!pszBegin || *pszBegin == TEXT('\0'))
{
return 0;
}
pszEnd = StrChr(pszBegin, cSeparator);
while(pszBegin <= pszEnd && *pszBegin == TEXT(' '))
pszBegin++;
while(pszEnd > pszBegin && *(pszEnd - 1) == TEXT(' '))
pszEnd--;
if(pszEnd > (pszBegin + 1) && *pszBegin == TEXT('"') && *(pszEnd-1) == TEXT('"'))
{
pszBegin++;
pszEnd--;
}
dwToCopy = (DWORD) (pszEnd - pszBegin + 1);
if(dwToCopy > cchBufSize)
dwToCopy = cchBufSize;
StrCpyN(szBuf, pszBegin, dwToCopy);
return dwToCopy - 1;
}
DWORD GetIntField(LPTSTR szStr, UINT uField, DWORD dwDefault)
{
TCHAR szNumBuf[16];
if (GetStringField(szStr, uField, szNumBuf, countof(szNumBuf)) == 0)
return dwDefault;
else
return StrToInt(szNumBuf);
}
void ConvertVersionStrToDwords(LPTSTR pszVer, LPDWORD pdwVer, LPDWORD pdwBuild)
{
DWORD dwTemp1,dwTemp2;
dwTemp1 = GetIntField(pszVer, 0, 0);
dwTemp2 = GetIntField(pszVer, 1, 0);
*pdwVer = (dwTemp1 << 16) + dwTemp2;
dwTemp1 = GetIntField(pszVer, 2, 0);
dwTemp2 = GetIntField(pszVer, 3, 0);
*pdwBuild = (dwTemp1 << 16) + dwTemp2;
}
void ConvertDwordsToVersionStr(LPTSTR pszVer, DWORD dwVer, DWORD dwBuild)
{
WORD w1, w2, w3, w4;
w1 = HIWORD(dwVer);
w2 = LOWORD(dwVer);
w3 = HIWORD(dwBuild);
w4 = LOWORD(dwBuild);
wnsprintf(pszVer, 32, TEXT("%d,%d,%d,%d"), w1, w2, w3, w4);
}
DWORD GetIEVersion()
{
TCHAR szValue[MAX_PATH];
DWORD dwInstalledVer, dwInstalledBuild, dwSize;
dwInstalledVer = dwInstalledBuild = (DWORD)-1;
szValue[0] = TEXT('\0');
dwSize = sizeof(szValue);
SHGetValue(HKEY_LOCAL_MACHINE, RK_IE, RV_VERSION, NULL, szValue, &dwSize);
if (szValue[0] != TEXT('\0')) {
ConvertVersionStrToDwords(szValue, &dwInstalledVer, &dwInstalledBuild);
return dwInstalledVer;
}
if (dwInstalledVer == (DWORD)-1) {
szValue[0] = TEXT('\0');
dwSize = sizeof(szValue);
SHGetValue(HKEY_LOCAL_MACHINE, REGSTR_PATH_APPPATHS TEXT("\\iexplore.exe"), NULL, NULL, szValue, &dwSize);
if (szValue[0] != TEXT('\0')) {
GetVersionFromFileWrap(szValue, &dwInstalledVer, &dwInstalledBuild, TRUE);
return dwInstalledVer;
}
}
return 0;
}
BOOL SetFlag(LPDWORD pdwFlags, DWORD dwMask, BOOL fSet /*= TRUE*/)
{
if (pdwFlags == NULL)
return FALSE;
if (fSet)
*pdwFlags |= dwMask;
else
*pdwFlags &= ~dwMask;
return TRUE;
}
// taken from IE setup code
BOOL IsNTAdmin()
{
typedef BOOL (WINAPI *LPCHECKTOKENMEMBERSHIP)(HANDLE, PSID, PBOOL);
static int s_fIsAdmin = 2;
HANDLE hAccessToken = NULL;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;
BOOL bRet = FALSE;
//
// If we have cached a value, return the cached value. Note I never
// set the cached value to false as I want to retry each time in
// case a previous failure was just a temp. problem (ie net access down)
//
bRet = FALSE;
if( s_fIsAdmin != 2 )
return (BOOL)s_fIsAdmin;
if (!IsOS(OS_NT))
{
s_fIsAdmin = TRUE; // If we are not running under NT return TRUE.
return (BOOL)s_fIsAdmin;
}
if(!IsOS(OS_NT5) &&
!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hAccessToken ) )
return FALSE;
if(AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup) )
{
// if we're running on W2K use the proper check (b388901 in W2K database) which
// will work for restricted tokens
if (IsOS(OS_NT5))
{
HINSTANCE hAdvapi32 = NULL;
LPCHECKTOKENMEMBERSHIP lpfnCheckTokenMembership = NULL;
hAdvapi32 = LoadLibrary(TEXT("advapi32.dll"));
if (hAdvapi32 != NULL)
{
lpfnCheckTokenMembership =
(LPCHECKTOKENMEMBERSHIP)GetProcAddress(hAdvapi32, "CheckTokenMembership");
if (lpfnCheckTokenMembership != NULL)
{
BOOL fMember = FALSE;
if (lpfnCheckTokenMembership(hAccessToken, AdministratorsGroup,
&fMember) && fMember)
{
s_fIsAdmin = TRUE;
bRet = TRUE;
}
}
FreeLibrary(hAdvapi32);
}
}
else
{
PTOKEN_GROUPS ptgGroups;
DWORD dwReqSize;
UINT i;
ptgGroups = NULL;
// See how big of a buffer we need for the token information
if(!GetTokenInformation( hAccessToken, TokenGroups, NULL, 0, &dwReqSize))
{
// GetTokenInfo should the buffer size we need - Alloc a buffer
if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
ptgGroups = (PTOKEN_GROUPS) CoTaskMemAlloc(dwReqSize);
}
// ptgGroups could be NULL for a coupla reasons here:
// 1. The alloc above failed
// 2. GetTokenInformation actually managed to succeed the first time (possible?)
// 3. GetTokenInfo failed for a reason other than insufficient buffer
// Any of these seem justification for bailing.
// So, make sure it isn't null, then get the token info
if((ptgGroups != NULL) &&
GetTokenInformation(hAccessToken, TokenGroups, ptgGroups, dwReqSize, &dwReqSize))
{
// Search thru all the groups this process belongs to looking for the
// Administrators Group.
for( i=0; i < ptgGroups->GroupCount; i++ )
{
if (EqualSid(ptgGroups->Groups[i].Sid, AdministratorsGroup))
{
// Yea! This guy looks like an admin
s_fIsAdmin = TRUE;
bRet = TRUE;
break;
}
}
}
if (ptgGroups != NULL)
CoTaskMemFree(ptgGroups);
}
FreeSid(AdministratorsGroup);
}
// BUGBUG: Close handle here? doc's aren't clear whether this is needed.
if (hAccessToken != NULL)
CloseHandle(hAccessToken);
return bRet;
}
HRESULT GetLcid(LCID *pLcid, LPCTSTR pcszLang, LPCTSTR pcszLocaleIni)
{
TCHAR szLookupEntries[1024];
TCHAR szLang[8];
LPTSTR pszIndex;
HRESULT hRetVal = E_FAIL;
if (pLcid == NULL || pcszLang == NULL || *pcszLang == TEXT('\0') || pcszLocaleIni == NULL ||
*pcszLocaleIni == TEXT('\0'))
return hRetVal;
if (GetPrivateProfileString(IS_ACTIVESETUP, NULL, TEXT(""), szLookupEntries, countof(szLookupEntries), pcszLocaleIni))
{
for (pszIndex = szLookupEntries; *pszIndex; pszIndex += StrLen(pszIndex)+1)
{
GetPrivateProfileString(IS_ACTIVESETUP, pszIndex, TEXT(""), szLang, countof(szLang), pcszLocaleIni);
if (StrCmpI(szLang, pcszLang) == 0)
{
TCHAR szHexLCID[16];
StrCpy(szHexLCID, TEXT("0x"));
StrCat(szHexLCID, pszIndex);
if (StrToIntEx(szHexLCID, STIF_SUPPORT_HEX, (int *)pLcid))
hRetVal = S_OK;
break;
}
}
}
return hRetVal;
}
UINT GetUnitsFromCb(UINT cbSrc, UINT cbUnit)
{
ASSERT(0 == cbSrc % cbUnit);
return (cbSrc / cbUnit);
}
/////////////////////////////////////////////////////////////////////////////
// Implementation helpers routines (private)
LPCTSTR mapSingleDw2Psz(PCMAPDW2PSZ pMap, UINT cEntries, DWORD dw, BOOL fFailNotFound /*= FALSE*/)
{
static TCHAR szUnknown[30];
ASSERT(pMap != NULL);
for (UINT i = 0; i < cEntries; i++)
if ((pMap + i)->dw == dw)
return (pMap + i)->psz;
if (fFailNotFound)
return NULL;
wnsprintf(szUnknown, countof(szUnknown), TEXT("(unknown) [0x%08lX]"), dw);
return szUnknown;
}