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.
 
 
 
 
 
 

612 lines
16 KiB

#include <fusenetincludes.h>
#include <version.h>
#include "cstrings.h"
HRESULT ConvertVersionStrToULL(LPCWSTR pwzVerStr, ULONGLONG *pullVersion)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
LPCWSTR pwz = NULL;
WORD wVer[4] = {0,0,0,0};
ULONGLONG ullVer = 0;
INT i= 0, iVersion = 0;
BOOL fDot = TRUE;
IF_NULL_EXIT(pwzVerStr, E_INVALIDARG);
IF_NULL_EXIT(pullVersion, E_INVALIDARG);
// Parse the version to ulonglong
pwz = pwzVerStr;
while (*pwz)
{
if (fDot)
{
iVersion=StrToInt(pwz);
wVer[i++] = (WORD) iVersion;
fDot = FALSE;
}
if (*pwz == L'.')
fDot = TRUE;
pwz++;
if (i > 3)
break;
}
for (i = 0; i < 4; i++)
ullVer |= ((ULONGLONG) wVer[i]) << (sizeof(WORD) * 8 * (3-i));
*pullVersion = ullVer;
exit:
return hr;
}
HRESULT FusionCompareString(LPCWSTR pwz1, LPWSTR pwz2, DWORD dwFlags)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
DWORD iCompare = CompareString(LOCALE_USER_DEFAULT, dwFlags,
pwz1, -1, pwz2, -1);
IF_WIN32_FALSE_EXIT(iCompare);
hr = (iCompare == CSTR_EQUAL) ? S_OK : S_FALSE;
exit:
return hr;
}
VOID MakeRandomString(LPWSTR wzRandom, DWORD cc)
{
static DWORD g_dwCounter;
LPWSTR pwzRandom = wzRandom;
for (DWORD i = 0; i < cc; i++)
{
DWORD dwChar;
DWORD dwRandom;
dwRandom = (GetTickCount() * rand()) + g_dwCounter++;
dwChar = dwRandom % 36; // 10 digits + 26 letters
*pwzRandom++ = (dwChar < 10 ) ?
(WCHAR)(L'0' + dwChar) : (WCHAR)(L'A' + (dwChar - 10));
}
}
HRESULT CreateRandomDir(LPWSTR pwzRootPath, LPWSTR pwzRandomDir, DWORD cchDirLen)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
DWORD dwLastError = 0;
CString sTempDirPath;
BOOL bDone = FALSE;
DWORD dwCount=0;
IF_FAILED_EXIT(::CreateDirectoryHierarchy(NULL, pwzRootPath));
do
{
::MakeRandomString(pwzRandomDir, cchDirLen);
IF_FAILED_EXIT(sTempDirPath.Assign(pwzRootPath));
IF_FAILED_EXIT(sTempDirPath.Append(pwzRandomDir));
::SetLastError(0);
::CreateDirectory(sTempDirPath._pwz, NULL);
dwLastError = ::GetLastError();
switch(dwLastError)
{
case NO_ERROR:
bDone = TRUE;
case ERROR_ALREADY_EXISTS :
break;
default :
_hr = HRESULT_FROM_WIN32(dwLastError);
goto exit;
}
if(bDone)
break;
if(dwCount > 1000)
{
// we tried enough ??
hr = E_FAIL;
goto exit;
}
else
{
dwCount++;
}
} while (1);
exit :
return hr;
}
HRESULT CheckFileExistence(LPCWSTR pwzFile, BOOL *pbExists)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
DWORD dw;
ASSERT(pwzFile && pbExists);
dw = GetFileAttributes(pwzFile);
if (dw == INVALID_FILE_ATTRIBUTES) {
hr = FusionpHresultFromLastError();
if ( (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) ||
(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) )
{
*pbExists = FALSE;
hr = S_OK;
}
goto exit;
}
*pbExists = TRUE;
exit:
return hr;
}
/////////////////////////////////////////////////////////////////////////
// CreateDirectoryHierarchy
/////////////////////////////////////////////////////////////////////////
HRESULT CreateDirectoryHierarchy(LPWSTR pwzRootDir, LPWSTR pwzFilePath)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
LPWSTR pwzPath, pwzEnd;
CString sCombinedPath;
IF_FALSE_EXIT(pwzRootDir || pwzFilePath, E_INVALIDARG);
if (pwzRootDir)
IF_FAILED_EXIT(sCombinedPath.Assign(pwzRootDir));
if (pwzFilePath)
IF_FAILED_EXIT(sCombinedPath.Append(pwzFilePath));
pwzPath = sCombinedPath._pwz;
pwzEnd = pwzPath + sizeof("C:\\");
while (pwzEnd = StrChr(pwzEnd, L'\\'))
{
BOOL bExists;
*pwzEnd = L'\0';
IF_FAILED_EXIT(CheckFileExistence(pwzPath, &bExists));
if (!bExists)
{
if(!CreateDirectory(pwzPath, NULL))
{
hr = FusionpHresultFromLastError();
goto exit;
}
}
*(pwzEnd++) = L'\\';
}
exit:
return hr;
}
HRESULT RemoveDirectoryAndChildren(LPWSTR szDir)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
HANDLE hf = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA fd;
CString sBuf;
DWORD dwError = 0;
IF_NULL_EXIT(szDir && lstrlenW(szDir), E_INVALIDARG);
IF_FAILED_EXIT(sBuf.Assign(szDir));
// Cannot delete root. Path must have greater length than "x:\"
if (lstrlenW(sBuf._pwz) < 4) {
// ASSERT(0);
hr = HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
goto exit;
}
if (RemoveDirectory(sBuf._pwz)) {
goto exit;
}
// ha! we have a case where the directory is probbaly not empty
IF_FAILED_EXIT(sBuf.Append(TEXT("\\*")));
if ((hf = FindFirstFile(sBuf._pwz, &fd)) == INVALID_HANDLE_VALUE) {
dwError = GetLastError();
if(dwError == ERROR_PATH_NOT_FOUND)
hr = S_FALSE;
else
hr = HRESULT_FROM_WIN32(dwError);
goto exit;
}
do {
IF_FAILED_EXIT(FusionCompareString(fd.cFileName, TEXT("."), 0));
if(hr == S_OK)
continue;
IF_FAILED_EXIT(FusionCompareString(fd.cFileName, TEXT(".."), 0));
if(hr == S_OK)
continue;
IF_FAILED_EXIT(sBuf.Assign(szDir));
IF_FAILED_EXIT(sBuf.Append(TEXT("\\")));
IF_FAILED_EXIT(sBuf.Append(fd.cFileName));
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
SetFileAttributes(sBuf._pwz,
FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_NORMAL);
IF_FAILED_EXIT(RemoveDirectoryAndChildren(sBuf._pwz));
} else {
SetFileAttributes(sBuf._pwz, FILE_ATTRIBUTE_NORMAL);
IF_WIN32_FALSE_EXIT(DeleteFile(sBuf._pwz));
}
} while (FindNextFile(hf, &fd));
dwError = GetLastError();
if (dwError != ERROR_NO_MORE_FILES) {
hr = HRESULT_FROM_WIN32(dwError);
goto exit;
}
if (hf != INVALID_HANDLE_VALUE) {
FindClose(hf);
hf = INVALID_HANDLE_VALUE;
}
// here if all subdirs/children removed
/// re-attempt to remove the main dir
if (!RemoveDirectory(szDir)) {
dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
goto exit;
}
exit:
if (hf != INVALID_HANDLE_VALUE)
FindClose(hf);
return hr;
}
HRESULT FusionpHresultFromLastError()
{
HRESULT hr = S_OK;
DWORD dwLastError = GetLastError();
if (dwLastError != NO_ERROR)
{
hr = HRESULT_FROM_WIN32(dwLastError);
}
else
{
hr = E_FAIL;
}
return hr;
}
// ---------------------------------------------------------------------------
// IsKnownAssembly
// ---------------------------------------------------------------------------
HRESULT IsKnownAssembly(IAssemblyIdentity *pId, DWORD dwFlags)
{
HRESULT hr = S_FALSE;
MAKE_ERROR_MACROS_STATIC(hr);
LPWSTR pwz = NULL;
DWORD cc = 0;
CString sPublicKeyToken;
// URT system assemblies; these are not downloaded or installed.
LPWSTR wzSystemTokens[] = { L"b03f5f7f11d50a3a", L"b77a5c561934e089" };
// Avalon assemblies - can be installed to gac.
LPWSTR wzAvalonTokens[] = { L"a29c01bbd4e39ac5" };
// Get the public key token in string form.
if (pId->GetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PUBLIC_KEY_TOKEN, &pwz, &cc) != S_OK)
goto exit;
sPublicKeyToken.TakeOwnership(pwz);
// Check for system assembly.
if (dwFlags == KNOWN_SYSTEM_ASSEMBLY)
{
for (int i = 0; i < 2; i++)
{
IF_FAILED_EXIT(FusionCompareString(wzSystemTokens[i], sPublicKeyToken._pwz, NORM_IGNORECASE));
if(hr == S_OK)
break;
}
}
// check for Avalon assembly.
else if (dwFlags == KNOWN_TRUSTED_ASSEMBLY)
{
IF_FAILED_EXIT(FusionCompareString(wzAvalonTokens[0], sPublicKeyToken._pwz, NORM_IGNORECASE));
}
exit:
return hr;
}
BOOL DoHeapValidate()
{
HANDLE h = GetProcessHeap();
return HeapValidate(h, 0, NULL);
}
//=--------------------------------------------------------------------------=
// EnsureDebuggerPresent
//=--------------------------------------------------------------------------=
// Ensures that a debugger is present. If one isn't present, this will attempt
// to attach one. If no debugger is installed on the machine, this will
// display a message and return FALSE.
//
BOOL EnsureDebuggerPresent()
{
BOOL fRet = TRUE;
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
HKEY hKey = NULL;
typedef BOOL (WINAPI* ISDEBUGGERPRESENT)();
static BOOL _fStartedDebugger = FALSE;
static ISDEBUGGERPRESENT _IsDebuggerPresent = NULL;
// If we've already done the work to start the debugger, we're fine
//
if (_fStartedDebugger)
{
fRet = TRUE;
goto exit;
}
// First, if we don't have an IsDebuggerPresent API, look for one.
//
if (!_IsDebuggerPresent)
{
HMODULE hKernel = NULL;
hKernel = GetModuleHandle (L"Kernel32.dll");
if (!hKernel)
{
MessageBox(NULL, L"Unable to attach to debugger because we could not find Kernel32.dll", L"VsAssert", MB_OK | MB_ICONSTOP);
fRet = FALSE;
goto exit;
}
_IsDebuggerPresent = (ISDEBUGGERPRESENT)GetProcAddress(hKernel, "IsDebuggerPresent");
if (!_IsDebuggerPresent)
{
MessageBox(NULL, L"Unable to attach to debugger because we could not find a suitable IsDebuggerPresent API", L"VsAssert", MB_OK | MB_ICONSTOP);
fRet = FALSE;
goto exit;
}
}
// Now find out if the debugger is indeed present.
//
if (_IsDebuggerPresent())
{
_fStartedDebugger = TRUE;
}
else
{
// The debugger has not been started yet. Do this here.
//
BOOL fJIT = FALSE;
//
// Magic! Location of the JIT debugger info...
//
WCHAR *wzRegKey = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug";
LONG lRetVal;
lRetVal = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
wzRegKey,
0,
KEY_READ,
&hKey);
CString sCommandLine;
DWORD dwSize = MAX_PATH;
BOOL fResult;
PROCESS_INFORMATION pi;
IF_FAILED_EXIT(sCommandLine.ResizeBuffer(dwSize+1));
if (lRetVal == ERROR_SUCCESS)
{
DWORD dwType;
lRetVal = RegQueryValueEx(
hKey,
L"Debugger",
0,
&dwType,
(BYTE *)sCommandLine._pwz,
&dwSize);
RegCloseKey(hKey);
hKey = NULL; // reset the value after closing....
if (lRetVal == ERROR_SUCCESS)
{
fJIT = TRUE;
}
}
else
{
//
// Try WIN.INI
GetProfileString(L"AeDebug", L"Debugger", L"", sCommandLine._pwz,
dwSize);
if (lstrlen(sCommandLine._pwz) != 0)
{
fJIT = TRUE;
}
}
if (!fJIT)
{
MessageBox(NULL, L"Unable to attach to debugger because we could not find a debugger on this machine.", L"VsAssert", MB_OK | MB_ICONSTOP);
fRet = FALSE;
goto exit;
}
HANDLE hEvent;
//
// Now that we have the JIT debugger, try to start it.
// The JIT needs a process ID (ours), and an event.
//
SECURITY_ATTRIBUTES sa;
memset(&sa, 0 , sizeof(sa));
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
hEvent = CreateEvent(&sa, TRUE, FALSE, NULL);
if (hEvent != NULL)
{
CString sCommand;
DWORD ccSize = 2 * MAX_PATH + 1 ;
BOOL fResult;
PROCESS_INFORMATION pi;
IF_FAILED_EXIT(sCommand.ResizeBuffer(ccSize));
wnsprintf(sCommand._pwz, ccSize-1, sCommandLine._pwz, GetCurrentProcessId(), hEvent);
sCommand._pwz[ccSize-1] = L'\0';
__try
{
STARTUPINFO si;
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
fResult = CreateProcess(
NULL,
sCommand._pwz,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&si,
&pi);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
fResult = FALSE;
}
if (fResult)
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
_fStartedDebugger = TRUE;
WaitForSingleObject(hEvent, INFINITE);
CloseHandle(hEvent);
}
else
{
CString sPoof;
DWORD ccSize = 2 * MAX_PATH + 100 ;
IF_FAILED_EXIT(sPoof.ResizeBuffer(ccSize));
wnsprintf(sPoof._pwz, sPoof._cc, L"Unable to invoke the debugger. The invocation command we used was:\r\n\r\n%s", sCommand._pwz);
sPoof._pwz[ccSize-1] = L'\0';
MessageBox(NULL, sPoof._pwz, L"VsAssert", MB_OK | MB_ICONSTOP);
fRet = FALSE;
goto exit;
}
}
}
exit :
if(hKey)
RegCloseKey(hKey);
return fRet;
}
// shlwapi either path- or url-combine
HRESULT DoPathCombine(CString& sDest, LPWSTR pwzSource)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
LPWSTR pwzDir = NULL, pwzTemp = NULL;
DWORD ccSource = 0, ccCombined = 0, dwFlags = 0;
ccSource = lstrlen(pwzSource) + 1;
ccCombined = sDest._cc + ccSource;
IF_FAILED_EXIT(sDest.ResizeBuffer(ccCombined));
pwzDir = WSTRDupDynamic(sDest._pwz);
pwzTemp = ::PathCombine(sDest._pwz, pwzDir, pwzSource);
IF_NULL_EXIT(pwzTemp, E_FAIL);
sDest._cc = lstrlen(sDest._pwz) + 1;
exit:
SAFEDELETEARRAY(pwzDir);
return S_OK;
}