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.
 
 
 
 
 
 

329 lines
9.3 KiB

#include <fusenetincludes.h>
#include <activator.h>
#include <versionmanagement.h>
#include "dbglog.h"
// debug msg stuff
void
Msg(LPCWSTR pwz)
{
MessageBox(NULL, pwz, L"ClickOnce", 0);
}
// ----------------------------------------------------------------------------
void
ShowError(LPCWSTR pwz)
{
MessageBox(NULL, pwz, L"ClickOnce Error", MB_ICONERROR);
}
// ----------------------------------------------------------------------------
void
ShowError(HRESULT hr, LPCWSTR pwz=NULL)
{
DWORD dwErrorCode = HRESULT_CODE(hr);
LPWSTR MessageBuffer = NULL;
DWORD dwBufferLength;
// ISSUE-2002/03/27-felixybc note: check for E_OUTOFMEMORY?
// Call FormatMessage() to allow for message
// text to be acquired from the system
if(dwBufferLength = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, // module to get message from (NULL == system)
dwErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(LPWSTR) &MessageBuffer,
0,
NULL))
{
// BUGBUG: Process any inserts in MessageBuffer
LPWSTR pwzMsg = MessageBuffer;
CString sMsg;
if (pwz != NULL)
{
if (SUCCEEDED(sMsg.Assign((LPWSTR)pwz)))
if (SUCCEEDED(sMsg.Append(L"\n\n")))
if (SUCCEEDED(sMsg.Append(MessageBuffer)))
pwzMsg = sMsg._pwz;
}
// Display the string
ShowError(pwzMsg);
// Free the buffer allocated by the system
LocalFree(MessageBuffer);
}
else
{
// ISSUE-2002/03/27-felixybc Error in this error handling code. Should print error code from format msg and orginal hr
// should at least print error code?
if (pwz != NULL)
ShowError((LPWSTR)pwz);
else
ShowError(L"Error occurred. Unable to retrieve associated error message from the system.");
}
}
/*void _stdcall
EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
hwnd - window handle that should be used as the owner window for
any windows your DLL creates
hinst - your DLL's instance handle
lpszCmdLine - ASCIIZ command line your DLL should parse
nCmdShow - describes how your DLL's windows should be displayed
*/
// ---------------------------------------------------------------------------
// DisableCurrentVersionW
// The rundll32 entry point for rollback to previous version
// The function should be named as 'DisableCurrentVersion' on rundll32's command line
// ---------------------------------------------------------------------------
void CALLBACK
DisableCurrentVersionW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
LPVERSION_MANAGEMENT pVerMan = NULL;
LPWSTR pwzDisplayNameMask = NULL;
IF_FAILED_EXIT(CoInitialize(NULL));
// parse commandline
// accepted formats: "displayNameMask"
if (*lpszCmdLine == L'\"')
{
LPWSTR pwz = NULL;
pwz = wcschr(lpszCmdLine+1, L'\"');
if (pwz != NULL)
{
*pwz = L'\0';
pwzDisplayNameMask = lpszCmdLine+1;
}
}
// exit if invalid arguments
IF_NULL_EXIT(pwzDisplayNameMask, E_INVALIDARG);
IF_FAILED_EXIT(CreateVersionManagement(&pVerMan, 0));
IF_FAILED_EXIT(pVerMan->Rollback(pwzDisplayNameMask));
if (hr == S_FALSE)
Msg(L"Application files cannot be found. Operation is aborted.");
exit:
SAFERELEASE(pVerMan);
if (FAILED(hr))
{
if (hr != E_ABORT)
ShowError(hr);
}
CoUninitialize();
return;
}
// ---------------------------------------------------------------------------
// UninstallW
// The rundll32 entry point for Control Panel's Add/Remove Program
// The function should be named as 'Uninstall' on rundll32's command line
// ---------------------------------------------------------------------------
void CALLBACK
UninstallW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
LPVERSION_MANAGEMENT pVerMan = NULL;
LPWSTR pwzDisplayNameMask = NULL;
LPWSTR pwzDesktopManifestPath = NULL;
HKEY hkey = NULL;
LONG lReturn = 0;
IF_FAILED_EXIT(CoInitialize(NULL));
// parse commandline
// accepted formats: "displayNameMask" "pathToDesktopManifest"
if (*lpszCmdLine == L'\"')
{
LPWSTR pwz = NULL;
pwz = wcschr(lpszCmdLine+1, L'\"');
if (pwz != NULL)
{
*pwz = L'\0';
pwzDisplayNameMask = lpszCmdLine+1;
pwz = wcschr(pwz+1, L'\"');
if (pwz != NULL)
{
pwzDesktopManifestPath = pwz+1;
pwz = wcschr(pwzDesktopManifestPath, L'\"');
if (pwz != NULL)
*pwz = L'\0';
else
pwzDesktopManifestPath = NULL;
}
}
}
// exit if invalid arguments
IF_FALSE_EXIT(pwzDisplayNameMask != NULL && pwzDesktopManifestPath != NULL, E_INVALIDARG);
IF_TRUE_EXIT(MessageBox(NULL, L"Do you want to remove this application and unregister its subscription?", L"ClickOnce",
MB_YESNO | MB_ICONQUESTION | MB_TASKMODAL) != IDYES, E_ABORT);
IF_FAILED_EXIT(CreateVersionManagement(&pVerMan, 0));
IF_FAILED_EXIT(pVerMan->Uninstall(pwzDisplayNameMask, pwzDesktopManifestPath));
if (hr == S_FALSE)
{
IF_TRUE_EXIT(MessageBox(NULL, L"The application can no longer be located on the system. Do you want to remove this entry?",
L"ClickOnce", MB_YESNO | MB_ICONQUESTION | MB_TASKMODAL) == IDNO, E_ABORT);
// delete registry uninstall info
extern const WCHAR* pwzUninstallSubKey; // defined in versionmanagement.cpp
// open uninstall key
lReturn = RegOpenKeyEx(HKEY_LOCAL_MACHINE, pwzUninstallSubKey, 0,
DELETE, &hkey);
IF_WIN32_FAILED_EXIT(lReturn);
lReturn = RegDeleteKey(hkey, pwzDisplayNameMask);
IF_WIN32_FAILED_EXIT(lReturn);
}
exit:
SAFERELEASE(pVerMan);
if (hkey)
{
lReturn = RegCloseKey(hkey);
if (SUCCEEDED(hr))
hr = (HRESULT_FROM_WIN32(lReturn));
}
if (FAILED(hr))
{
if (hr != E_ABORT)
ShowError(hr);
}
CoUninitialize();
return;
}
// ---------------------------------------------------------------------------
// StartW
// The single rundll32 entry point for both shell (file type host) and mimehandler/url
// The function should be named as 'Start' on rundll32's command line
// ---------------------------------------------------------------------------
void CALLBACK
StartW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
LPACTIVATOR pActivator = NULL;
LPWSTR pwzShortcutPath = NULL;
LPWSTR pwzShortcutUrl = NULL;
BOOL bIsFromWeb = FALSE;
CDebugLog * pDbgLog = NULL;
if (FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED)))
{
// ISSUE-2002/03/27-felixybc work around on longhorn builds, avalon bug 1493
if(hr == RPC_E_CHANGED_MODE)
hr = S_OK; // allow RPC_E_CHANGED_MODE error for now.
else
goto exit;
}
// parse commandline
// accepted formats: "Path" <OR> "Path" "URL"
if (*lpszCmdLine == L'\"')
{
LPWSTR pwz = NULL;
pwz = wcschr(lpszCmdLine+1, L'\"');
if (pwz != NULL)
{
*pwz = L'\0';
// case 1 desktop/local, path to shortcut only
pwzShortcutPath = lpszCmdLine+1;
pwz = wcschr(pwz+1, L'\"');
if (pwz != NULL)
{
pwzShortcutUrl = pwz+1;
pwz = wcschr(pwzShortcutUrl, L'\"');
if (pwz != NULL)
{
*pwz = L'\0';
// case 2 url/mimehandler, path to temp shortcut and source URL
bIsFromWeb = TRUE;
}
}
}
}
// exit if invalid arguments. ShortcutUrl is incomplete if bIsFromWeb is FALSE
IF_FALSE_EXIT(!(pwzShortcutPath == NULL || (pwzShortcutUrl != NULL && !bIsFromWeb)), E_INVALIDARG);
IF_FAILED_EXIT(CreateLogObject(&pDbgLog, NULL));
IF_FAILED_EXIT(CreateActivator(&pActivator, pDbgLog, 0));
IF_FAILED_EXIT(pActivator->Initialize(pwzShortcutPath, pwzShortcutUrl));
IF_FAILED_EXIT(pActivator->Process());
IF_FAILED_EXIT(pActivator->Execute());
exit:
if(pDbgLog)
{
DUMPDEBUGLOG(pDbgLog, -1, hr);
}
SAFERELEASE(pActivator);
if (FAILED(hr))
{
if (hr != E_ABORT)
ShowError(hr);
}
if (bIsFromWeb)
{
// delete the temp file from the mimehandler
// ignore return value
DeleteFile(pwzShortcutPath);
}
CoUninitialize();
SAFERELEASE(pDbgLog);
return;
}