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.
 
 
 
 
 
 

355 lines
8.7 KiB

/*
* persist.cpp - IPersist, IPersistFile implementations for
* CFusionShortcut class.
*/
/* Headers
**********/
#include "project.hpp" // for GetLastWin32Error
/* Global Constants
*******************/
const WCHAR g_cwzDefaultFileNamePrompt[] = L"*.manifest";
// ----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CFusionShortcut::GetCurFile(LPWSTR pwzFile,
UINT ucbLen)
{
HRESULT hr=S_OK;
if (m_pwzShortcutFile)
{
wcsncpy(pwzFile, m_pwzShortcutFile, ucbLen-1);
pwzFile[ucbLen-1] = L'\0';
}
else
hr = S_FALSE;
ASSERT(hr == S_OK ||
hr == S_FALSE);
return(hr);
}
HRESULT STDMETHODCALLTYPE CFusionShortcut::Dirty(BOOL bDirty)
{
HRESULT hr=S_OK;
if (bDirty)
{
SET_FLAG(m_dwFlags, FUSSHCUT_FL_DIRTY);
//m_dwFlags = FUSSHCUT_FL_DIRTY;
}
else
{
CLEAR_FLAG(m_dwFlags, FUSSHCUT_FL_DIRTY);
//m_dwFlags = FUSSHCUT_FL_NOTDIRTY;
}
return(hr);
}
HRESULT STDMETHODCALLTYPE CFusionShortcut::GetClassID(CLSID* pclsid)
{
HRESULT hr=S_OK;
if (pclsid == NULL)
hr = E_INVALIDARG;
else
*pclsid = CLSID_FusionShortcut;
return(hr);
}
HRESULT STDMETHODCALLTYPE CFusionShortcut::IsDirty(void)
{
HRESULT hr;
if (IS_FLAG_SET(m_dwFlags, FUSSHCUT_FL_DIRTY))
//if (m_dwFlags == FUSSHCUT_FL_DIRTY)
// modified
hr = S_OK;
else
// not modified
hr = S_FALSE;
return(hr);
}
HRESULT STDMETHODCALLTYPE CFusionShortcut::Save(LPCOLESTR pcwszFile,
BOOL bRemember)
{
// BUGBUG: no save for now!
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CFusionShortcut::SaveCompleted(LPCOLESTR pcwszFile)
{
// BUGBUG: no save for now!
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CFusionShortcut::Load(LPCOLESTR pcwszFile,
DWORD dwMode)
{
HRESULT hr = S_OK;
LPWSTR pwzWorkingDir = NULL;
LPWSTR pwzValue = NULL;
DWORD dwCC = 0, dwCB = 0, dwFlag = 0;
LPASSEMBLY_MANIFEST_IMPORT pManImport = NULL;
LPASSEMBLY_CACHE_IMPORT pCacheImport = NULL;
IManifestInfo *pAppInfo = NULL;
IManifestInfo *pDependAsmInfo = NULL;
// FEATURE: Validate dwMode here.
// FEAUTRE: Implement dwMode flag support.
if (!pcwszFile)
{
hr = E_INVALIDARG;
goto exit;
}
// a hack check
// BUGBUG?: this shouldn't be called more than once?
// BUT: the rest of this code works even if called multiple times
if (m_pwzWorkingDirectory)
{
hr = E_FAIL;
goto exit;
}
// store the shortcut file name
if (m_pwzShortcutFile)
delete [] m_pwzShortcutFile;
// (+ 1) for null terminator.
m_pwzShortcutFile = new(WCHAR[wcslen(pcwszFile) + 1]);
if (m_pwzShortcutFile)
{
wcscpy(m_pwzShortcutFile, pcwszFile);
}
else
{
hr = E_OUTOFMEMORY;
goto exit;
}
if (FAILED(hr = CreateAssemblyManifestImport(&pManImport, m_pwzShortcutFile, NULL, 0)))
goto exit;
// check this 1st for pref...
if (FAILED(hr=pManImport->GetManifestApplicationInfo(&pAppInfo)))
goto exit;
// can't continue without this...
if (hr==S_FALSE)
{
hr = E_FAIL;
goto exit;
}
if (m_pIdentity)
m_pIdentity->Release();
if (FAILED(hr = pManImport->GetAssemblyIdentity(&m_pIdentity)))
goto exit;
// can't continue without a cache dir, 'cos otherwise unknown behavior
// BUGBUG: should check/code to ensure some continue to work
// even without the complete name, eg. shell icon path, part of infotip
if (FAILED(hr = CreateAssemblyCacheImport(&pCacheImport, m_pIdentity, CACHEIMP_CREATE_RESOLVE_REF_EX)))
goto exit;
pCacheImport->GetManifestFileDir(&pwzWorkingDir, &dwCC);
if (dwCC < 2)
{
// this should never happen
hr = E_UNEXPECTED;
goto exit;
}
// remove last L'\\'
*(pwzWorkingDir+dwCC-2) = L'\0';
if (FAILED(hr=SetWorkingDirectory(pwzWorkingDir)))
goto exit;
// ignore failure
pAppInfo->Get(MAN_INFO_APPLICATION_SHOWCOMMAND, (LPVOID *)&pwzValue, &dwCB, &dwFlag);
if (pwzValue != NULL)
{
// default is normal
int nShowCmd = SW_SHOWNORMAL;
if (!_wcsicmp(pwzValue, L"maximized"))
{
nShowCmd = SW_SHOWMAXIMIZED;
}
else if (!_wcsicmp(pwzValue, L"minimized"))
{
nShowCmd = SW_SHOWMINIMIZED;
}
if (FAILED(hr=SetShowCmd(nShowCmd)))
goto exit;
delete [] pwzValue;
}
// ignore failure
pAppInfo->Get(MAN_INFO_APPLICATION_ENTRYPOINT, (LPVOID *)&pwzValue, &dwCB, &dwFlag);
if (pwzValue != NULL)
{
size_t ccWorkingDir = wcslen(pwzWorkingDir)+1;
size_t ccEntryPoint = wcslen(pwzValue)+1;
LPWSTR pwzTemp = new WCHAR[ccWorkingDir+ccEntryPoint]; // 2 strings + '\\' + '\0'
// like .lnk or .url, entry point is under wzWorkingDir
// 'path' is the target file of the shortcut, ie. the entry point of the app in this case
if (pwzTemp == NULL)
{
hr = E_OUTOFMEMORY;
goto exit;
}
memcpy(pwzTemp, pwzWorkingDir, ccWorkingDir * sizeof(WCHAR));
if (!PathAppend(pwzTemp, pwzValue))
hr = E_FAIL;
else
hr=SetPath(pwzTemp);
delete [] pwzTemp;
if (FAILED(hr))
goto exit;
delete [] pwzValue;
}
//else
// ... if no entry point leave it blank so that the default icon will be used
// ignore failure
pAppInfo->Get(MAN_INFO_APPLICATION_FRIENDLYNAME, (LPVOID *)&pwzValue, &dwCB, &dwFlag);
if (pwzValue != NULL)
{
if (FAILED(hr=SetDescription(pwzValue)))
goto exit;
delete [] pwzValue;
}
// ignore failure
pAppInfo->Get(MAN_INFO_APPLICATION_ICONFILE, (LPVOID *)&pwzValue, &dwCB, &dwFlag);
if (pwzValue != NULL)
{
LPWSTR pwzValue2 = NULL;
pAppInfo->Get(MAN_INFO_APPLICATION_ICONINDEX, (LPVOID *)&pwzValue2, &dwCB, &dwFlag);
if (pwzValue2 != NULL)
{
LPWSTR pwzStopString = NULL;
hr=SetIconLocation(pwzValue, (int) wcstol(pwzValue2, &pwzStopString, 10));
delete [] pwzValue2;
if (FAILED(hr))
goto exit;
}
delete [] pwzValue;
}
// ignore failure
pAppInfo->Get(MAN_INFO_APPLICATION_HOTKEY, (LPVOID *)&pwzValue, &dwCB, &dwFlag);
if (pwzValue != NULL)
{
LPWSTR pwzStopString = NULL;
if (FAILED(hr=SetHotkey((WORD) wcstol(pwzValue, &pwzStopString, 10))))
goto exit;
delete [] pwzValue;
}
// note: this method of getting the codebase is only valid for desktop (and subscription) manifests
// thus the hardcoded index '0'
// ignore failure
pManImport->GetNextAssembly(0, &pDependAsmInfo);
if (pDependAsmInfo != NULL)
{
pDependAsmInfo->Get(MAN_INFO_DEPENDENT_ASM_CODEBASE, (LPVOID *)&pwzValue, &dwCB, &dwFlag);
if (pwzValue != NULL)
{
if (FAILED(hr=SetCodebase(pwzValue)))
goto exit;
delete [] pwzValue;
}
}
pwzValue = NULL;
exit:
if (pwzValue != NULL)
delete [] pwzValue;
if (pwzWorkingDir != NULL)
delete [] pwzWorkingDir;
if (pDependAsmInfo != NULL)
pDependAsmInfo->Release();
if (pAppInfo != NULL)
pAppInfo->Release();
if (pCacheImport != NULL)
pCacheImport->Release();
if (pManImport != NULL)
pManImport->Release();
return(hr);
}
HRESULT STDMETHODCALLTYPE CFusionShortcut::GetCurFile(LPOLESTR *ppwszFile)
{
HRESULT hr = S_OK;
LPOLESTR pwszTempFile;
if (ppwszFile == NULL)
{
hr = E_INVALIDARG;
goto exit;
}
// BUGBUG?: ensure *ppwszFile NULL?
if (m_pwzShortcutFile)
{
pwszTempFile = m_pwzShortcutFile;
}
else
{
pwszTempFile = (LPWSTR) g_cwzDefaultFileNamePrompt;
hr = S_FALSE;
}
*ppwszFile = (LPOLESTR) CoTaskMemAlloc((wcslen(pwszTempFile) + 1) * sizeof(*pwszTempFile));
if (*ppwszFile)
wcscpy(*ppwszFile, pwszTempFile);
else
hr = E_OUTOFMEMORY;
exit:
return(hr);
}