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.
 
 
 
 
 
 

490 lines
11 KiB

#include "pch.hxx"
#include "strconst.h"
#include <mimeole.h>
#include <imnact.h>
#include "imsgcont.h"
#include <goptions.h>
#include <thormsgs.h>
#include "sigs.h"
#include <shlwapi.h>
#undef _INC_GOPTIONS_H
#define DEFINE_OPTION_STRUCTS
#include <goptions.h>
#include "demand.h"
#include "multiusr.h"
IOptionBucketEx *g_pOpt = NULL;
COptNotify *g_pOptNotify = NULL;
BOOL g_fBadShutdown = FALSE;
static OPTBCKTINIT g_init =
{
c_rgOptInfo,
ARRAYSIZE(c_rgOptInfo),
HKEY_CURRENT_USER,
c_szRegRoot,
c_rgszOptRegKey,
COPTREGKEY
};
BOOL InitGlobalOptions(HKEY hkey, LPCSTR szRegOptRoot)
{
OPTBCKTINIT init;
LPCOPTBCKTINIT pinit;
HRESULT hr;
Assert(NULL == g_pOpt);
Assert(NULL == g_pOptNotify);
g_init.hkey = MU_GetCurrentUserHKey();
IF_NULLEXIT(g_pOptNotify = new COptNotify);
IF_FAILEXIT(hr = CreateOptionBucketEx(&g_pOpt));
pinit = &g_init;
if (NULL != hkey)
{
Assert(NULL != szRegOptRoot);
init = g_init;
init.hkey = hkey;
init.pszRegKeyBase = szRegOptRoot;
pinit = &init;
}
IF_FAILEXIT(hr = g_pOpt->Initialize(pinit));
IF_FAILEXIT(hr = g_pOpt->SetNotification((IOptionBucketNotify *)g_pOptNotify));
// signature manager
IF_FAILEXIT(hr = InitSignatureManager(pinit->hkey, pinit->pszRegKeyBase));
// if the running regkey is still there, we shut down badly
g_fBadShutdown = DwGetOption(OPT_ATHENA_RUNNING);
SetDwOption(OPT_ATHENA_RUNNING, TRUE, NULL, 0);
exit:
return (S_OK == hr);
}
void DeInitGlobalOptions(void)
{
if (NULL != g_pOpt)
{
SetDwOption(OPT_ATHENA_RUNNING, FALSE, NULL, 0);
g_pOpt->Release();
g_pOpt = NULL;
}
if (NULL != g_pOptNotify)
{
g_pOptNotify->Release();
g_pOptNotify = NULL;
}
DeinitSignatureManager();
}
DWORD DwGetOption(PROPID id)
{
Assert(NULL != g_pOpt);
return(IDwGetOption(g_pOpt, id));
}
DWORD DwGetOptionDefault(PROPID id)
{
Assert(NULL != g_pOpt);
return(IDwGetOptionDefault(g_pOpt, id));
}
DWORD GetOption(PROPID id, void *pv, DWORD cb)
{
Assert(NULL != g_pOpt);
return(IGetOption(g_pOpt, id, pv, cb));
}
DWORD IDwGetOption(IOptionBucketEx *pOpt, PROPID id)
{
PROPVARIANT var;
HRESULT hr;
DWORD dw = 0;
Assert(NULL != pOpt);
// special case attachment checks to allow for ADM setting of group policy
if ((id == OPT_SECURITY_ATTACHMENT) || (id == OPT_SECURITY_ATTACHMENT_LOCKED))
{
HKEY hkey;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegFlat, 0, KEY_READ, &hkey))
{
DWORD dwVal, cb;
cb = sizeof(dwVal);
if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szBlockAttachments, 0, NULL, (LPBYTE)&dwVal, &cb))
{
// if set then unsafe attachments are both locked and also disallowed
if (dwVal == 1)
dw = 1;
}
RegCloseKey(hkey);
}
}
if (!dw)
{
IF_FAILEXIT(hr = pOpt->GetProperty(MAKEPROPSTRING(id), &var, 0));
Assert(VT_UI4 == var.vt);
dw = var.ulVal;
}
exit:
return(dw);
}
DWORD IDwGetOptionDefault(IOptionBucketEx *pOpt, PROPID id)
{
PROPVARIANT var;
HRESULT hr;
DWORD dw = 0;
Assert(pOpt != NULL);
IF_FAILEXIT(hr = pOpt->GetPropertyDefault(id, &var, 0));
Assert(var.vt == VT_UI4);
dw = var.ulVal;
exit:
return(dw);
}
DWORD IGetOption(IOptionBucketEx *pOpt, PROPID id, void *pv, DWORD cb)
{
PROPVARIANT var;
HRESULT hr = S_OK;
DWORD cbT = 0;
LPBYTE pByte = NULL;
Assert(NULL != pOpt);
IF_FAILEXIT(hr = pOpt->GetProperty(MAKEPROPSTRING(id), &var, 0));
switch (var.vt)
{
case VT_LPSTR:
pByte = (LPBYTE)var.pszVal;
cbT = lstrlen(var.pszVal) + 1;
break;
case VT_LPWSTR:
pByte = (LPBYTE)var.pwszVal;
cbT = (lstrlenW(var.pwszVal) + 1) * sizeof(WCHAR);
break;
case VT_BLOB:
pByte = (LPBYTE)var.blob.pBlobData;
cbT = var.blob.cbSize;
break;
default:
Assert(FALSE);
IF_FAILEXIT(hr = E_FAIL);
break;
}
if (cb >= cbT && pByte)
CopyMemory(pv, pByte, cbT);
else
IF_FAILEXIT(hr = E_FAIL);
exit:
MemFree(pByte);
return (SUCCEEDED(hr) ? cbT : 0);
}
BOOL SetDwOption(PROPID id, DWORD dw, HWND hwnd, DWORD dwFlags)
{
Assert(NULL != g_pOpt);
return(ISetOption(g_pOpt, id, &dw, sizeof(DWORD), hwnd, dwFlags));
}
BOOL SetOption(PROPID id, void *pv, DWORD cb, HWND hwnd, DWORD dwFlags)
{
Assert(NULL != g_pOpt);
return(ISetOption(g_pOpt, id, pv, cb, hwnd, dwFlags));
}
BOOL ISetDwOption(IOptionBucketEx *pOpt, PROPID id, DWORD dw, HWND hwnd, DWORD dwFlags)
{
Assert(NULL != pOpt);
return(ISetOption(pOpt, id, &dw, sizeof(DWORD), hwnd, dwFlags));
}
BOOL ISetOption(IOptionBucketEx *pOpt, PROPID id, void *pv, DWORD cb, HWND hwnd, DWORD dwFlags)
{
HRESULT hr;
PROPINFO info;
PROPVARIANT var;
Assert(NULL != pOpt);
Assert(NULL != pv);
info.cbSize = sizeof(info);
IF_FAILEXIT(hr = pOpt->GetPropertyInfo(id, &info, 0));
var.vt = info.vt;
switch(var.vt)
{
case VT_UI4:
var.ulVal = *((DWORD *)pv);
break;
case VT_LPSTR:
var.pszVal = (LPSTR)pv;
break;
case VT_LPWSTR:
var.pwszVal = (LPWSTR)pv;
break;
case VT_BLOB:
var.blob.cbSize = cb;
var.blob.pBlobData = (BYTE *)pv;
break;
default:
Assert(FALSE);
IF_FAILEXIT(hr = E_FAIL);
break;
}
IF_FAILEXIT(hr = pOpt->ISetProperty(hwnd, MAKEPROPSTRING(id), &var, dwFlags));
// TODO: notify option objects that option changed
exit:
return(SUCCEEDED(hr));
}
HRESULT OptionAdvise(HWND hwnd)
{
Assert(NULL != g_pOptNotify);
return(g_pOptNotify->Register(hwnd));
}
HRESULT OptionUnadvise(HWND hwnd)
{
Assert(NULL != g_pOptNotify);
return(g_pOptNotify->Unregister(hwnd));
}
COptNotify::COptNotify(void)
{
m_cRef = 1;
m_cHwnd = 0;
m_cHwndBuf = 0;
m_rgHwnd = NULL;
}
COptNotify::~COptNotify(void)
{
MemFree(m_rgHwnd);
}
STDMETHODIMP COptNotify::QueryInterface(REFIID riid, LPVOID *ppv)
{
if (NULL == ppv)
return(E_INVALIDARG);
if (IID_IUnknown == riid)
{
*ppv = (IUnknown *)this;
}
else if (IID_IOptionBucketNotify == riid)
{
*ppv = (IOptionBucketNotify *)this;
}
else
{
*ppv = NULL;
return(E_NOINTERFACE);
}
((IUnknown *)*ppv)->AddRef();
return(S_OK);
}
STDMETHODIMP_(ULONG) COptNotify::AddRef(void)
{
return((ULONG)InterlockedIncrement(&m_cRef));
}
STDMETHODIMP_(ULONG) COptNotify::Release(void)
{
LONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
delete this;
return((ULONG)cRef);
}
#define CADVISEOPT 32
HRESULT COptNotify::Register(HWND hwnd)
{
HRESULT hr = S_OK;
int cbuf;
if (m_cHwnd == m_cHwndBuf)
{
cbuf = m_cHwndBuf + CADVISEOPT;
IF_NULLEXIT(MemRealloc((void **)&m_rgHwnd, sizeof(HWND) * cbuf));
m_cHwndBuf = cbuf;
}
Assert(m_rgHwnd != NULL);
m_rgHwnd[m_cHwnd] = hwnd;
m_cHwnd++;
exit:
return hr;
}
HRESULT COptNotify::Unregister(HWND hwnd)
{
int index = 0;
while (index < m_cHwnd)
{
if (m_rgHwnd[index] == hwnd)
break;
index++;
}
if (index >= m_cHwnd)
return (E_FAIL);
if (m_cHwnd == 1)
{
MemFree(m_rgHwnd);
m_rgHwnd = NULL;
m_cHwndBuf = 0;
}
else
{
while (index < m_cHwnd)
{
m_rgHwnd[index] = m_rgHwnd[index+1];
index++;
}
}
m_cHwnd--;
return (S_OK);
}
STDMETHODIMP COptNotify::DoNotification(IOptionBucketEx *pBckt, HWND hwnd, PROPID id)
{
int i;
for (i = 0; i < m_cHwnd; i++)
{
if (hwnd != m_rgHwnd[i] && IsWindow(m_rgHwnd[i]))
PostMessage(m_rgHwnd[i], CM_OPTIONADVISE, id, 0);
}
return(S_OK);
}
void GetUserKeyPath(LPCSTR lpSubKey, LPSTR sz, int cch)
{
Assert(sz != NULL);
Assert(cch >= MAX_PATH);
LPCTSTR pszUserRoot = c_szRegRoot;
if (lpSubKey == NULL)
StrCpyN(sz, pszUserRoot, cch);
else
wnsprintf(sz, cch, c_szPathFileFmt, pszUserRoot, lpSubKey);
}
LONG AthUserCreateKey(LPCSTR lpSubKey, REGSAM samDesired, PHKEY phkResult, LPDWORD lpdwDisposition)
{
char sz[MAX_PATH];
GetUserKeyPath(lpSubKey, sz, ARRAYSIZE(sz));
return(RegCreateKeyEx(MU_GetCurrentUserHKey(), sz, 0, NULL, REG_OPTION_NON_VOLATILE,
samDesired, NULL, phkResult, lpdwDisposition));
}
LONG AthUserOpenKey(LPCSTR lpSubKey, REGSAM samDesired, PHKEY phkResult)
{
char sz[MAX_PATH];
GetUserKeyPath(lpSubKey, sz, ARRAYSIZE(sz));
return(RegOpenKeyEx(MU_GetCurrentUserHKey(), sz, 0, samDesired, phkResult));
}
LONG AthUserDeleteKey(LPCSTR lpSubKey)
{
char sz[MAX_PATH];
GetUserKeyPath(lpSubKey, sz, ARRAYSIZE(sz));
return(SHDeleteKey(MU_GetCurrentUserHKey(), sz));
}
LONG AthUserGetValue(LPCSTR lpSubKey, LPCSTR lpValueName, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
{
char sz[MAX_PATH];
GetUserKeyPath(lpSubKey, sz, ARRAYSIZE(sz));
return(SHGetValue(MU_GetCurrentUserHKey(), sz, lpValueName, lpType, lpData, lpcbData));
}
LONG AthUserSetValue(LPCSTR lpSubKey, LPCSTR lpValueName, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
{
char sz[MAX_PATH];
GetUserKeyPath(lpSubKey, sz, ARRAYSIZE(sz));
return(SHSetValue(MU_GetCurrentUserHKey(), sz, lpValueName, dwType, lpData, cbData));
}
LONG AthUserDeleteValue(LPCSTR lpSubKey, LPCSTR lpValueName)
{
char sz[MAX_PATH];
GetUserKeyPath(lpSubKey, sz, ARRAYSIZE(sz));
return(SHDeleteValue(MU_GetCurrentUserHKey(), sz, lpValueName));
}
HKEY AthUserGetKeyRoot(void)
{
return(MU_GetCurrentUserHKey());
}
void AthUserGetKeyPath(LPSTR szKey, int cch)
{
Assert(cch >= MAX_PATH);
LPCTSTR pszRegRoot = c_szRegRoot;
Assert(pszRegRoot);
StrCpyN(szKey, pszRegRoot, cch);
}