313 lines
6.9 KiB
C
313 lines
6.9 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) Microsoft Corporation. All Rights Reserved.
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
proxyinst.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Exception Pack installer helper DLL
|
||
|
Can be used as a co-installer, or called via setup app, or RunDll32 stub
|
||
|
|
||
|
This DLL is for internal distribution of exception packs to update
|
||
|
OS components.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Jamie Hunter (jamiehun) 2001-11-27
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
Jamie Hunter (jamiehun) 2001-11-27
|
||
|
|
||
|
Initial Version
|
||
|
|
||
|
--*/
|
||
|
#include "msoobcip.h"
|
||
|
|
||
|
typedef struct _PROXY_DATA {
|
||
|
TCHAR InfPath[MAX_PATH];
|
||
|
TCHAR Media[MAX_PATH];
|
||
|
TCHAR Store[MAX_PATH];
|
||
|
DWORD Flags;
|
||
|
HRESULT hrStatus;
|
||
|
} PROXY_DATA, * PPROXY_DATA;
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
ProxyInstallExceptionPackFromInf(
|
||
|
IN LPCTSTR InfPath,
|
||
|
IN LPCTSTR Media,
|
||
|
IN LPCTSTR Store,
|
||
|
IN DWORD Flags
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Kicks off another process, and calls RemoteInstallExceptionPackFromInf in
|
||
|
remote process.
|
||
|
(Bug workaround)
|
||
|
Otherwise as InstallExceptionPackFromInf
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
InfPath - name of Inf in Media location
|
||
|
Media - InfPath less InfName
|
||
|
Store - expack store
|
||
|
Flags - various flags
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
status as hresult
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
HANDLE hMapping = NULL;
|
||
|
DWORD Status;
|
||
|
HRESULT hrStatus;
|
||
|
PPROXY_DATA pData = NULL;
|
||
|
TCHAR ExecName[MAX_PATH];
|
||
|
TCHAR Buffer[MAX_PATH];
|
||
|
TCHAR CmdLine[MAX_PATH*3];
|
||
|
STARTUPINFO StartupInfo;
|
||
|
PROCESS_INFORMATION ProcessInfo;
|
||
|
SECURITY_ATTRIBUTES Security;
|
||
|
UINT uiRes;
|
||
|
//
|
||
|
// create a mapped region of shared data
|
||
|
//
|
||
|
|
||
|
ZeroMemory(&Security,sizeof(Security));
|
||
|
Security.nLength = sizeof(Security);
|
||
|
Security.lpSecurityDescriptor = NULL; // default
|
||
|
Security.bInheritHandle = TRUE;
|
||
|
|
||
|
hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
|
||
|
&Security,
|
||
|
PAGE_READWRITE|SEC_COMMIT,
|
||
|
0,
|
||
|
sizeof(PROXY_DATA),
|
||
|
NULL);
|
||
|
if(hMapping == NULL) {
|
||
|
Status = GetLastError();
|
||
|
return HRESULT_FROM_WIN32(Status);
|
||
|
}
|
||
|
|
||
|
pData = MapViewOfFile(
|
||
|
hMapping,
|
||
|
FILE_MAP_ALL_ACCESS,
|
||
|
0,
|
||
|
0,
|
||
|
sizeof(PROXY_DATA)
|
||
|
);
|
||
|
|
||
|
if(!pData) {
|
||
|
Status = GetLastError();
|
||
|
hrStatus = HRESULT_FROM_WIN32(Status);
|
||
|
goto final;
|
||
|
}
|
||
|
ZeroMemory(pData,sizeof(PROXY_DATA));
|
||
|
lstrcpyn(pData->InfPath,InfPath,MAX_PATH);
|
||
|
lstrcpyn(pData->Media,Media,MAX_PATH);
|
||
|
lstrcpyn(pData->Store,Store,MAX_PATH);
|
||
|
pData->Flags = Flags;
|
||
|
pData->hrStatus = E_UNEXPECTED;
|
||
|
|
||
|
//
|
||
|
// invoke the remote function
|
||
|
//
|
||
|
uiRes = GetSystemDirectory(ExecName,MAX_PATH);
|
||
|
if(uiRes>=MAX_PATH) {
|
||
|
hrStatus = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||
|
goto final;
|
||
|
}
|
||
|
ConcatPath(ExecName,MAX_PATH,TEXT("rundll32.exe"));
|
||
|
|
||
|
uiRes = GetModuleFileName(g_DllHandle,CmdLine,MAX_PATH);
|
||
|
if(uiRes>=MAX_PATH) {
|
||
|
hrStatus = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||
|
goto final;
|
||
|
}
|
||
|
//
|
||
|
// convert this to short name to ensure no spaces in path
|
||
|
// (hacky)
|
||
|
//
|
||
|
uiRes = GetShortPathName(CmdLine,Buffer,MAX_PATH);
|
||
|
if(uiRes>=MAX_PATH) {
|
||
|
hrStatus = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||
|
goto final;
|
||
|
}
|
||
|
//
|
||
|
// now build up command line
|
||
|
//
|
||
|
lstrcpy(CmdLine,ExecName);
|
||
|
lstrcat(CmdLine,TEXT(" "));
|
||
|
lstrcat(CmdLine,Buffer);
|
||
|
_stprintf(Buffer,TEXT(",ProxyRemoteInstall 0x%08x"),(ULONG_PTR)hMapping);
|
||
|
lstrcat(CmdLine,Buffer);
|
||
|
|
||
|
ZeroMemory(&StartupInfo,sizeof(StartupInfo));
|
||
|
StartupInfo.cb = sizeof(StartupInfo);
|
||
|
ZeroMemory(&ProcessInfo,sizeof(ProcessInfo));
|
||
|
|
||
|
//
|
||
|
// kick off rundll32 process to run our ProxyRemoteInstall entrypoint
|
||
|
//
|
||
|
if(!CreateProcess(ExecName,
|
||
|
CmdLine,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
TRUE, // inherit handles
|
||
|
CREATE_NO_WINDOW, // creation flags
|
||
|
NULL, // environment
|
||
|
NULL, // directory
|
||
|
&StartupInfo,
|
||
|
&ProcessInfo
|
||
|
)) {
|
||
|
Status = GetLastError();
|
||
|
hrStatus = HRESULT_FROM_WIN32(Status);
|
||
|
goto final;
|
||
|
}
|
||
|
if(WaitForSingleObject(ProcessInfo.hProcess,INFINITE) == WAIT_OBJECT_0) {
|
||
|
//
|
||
|
// process terminated 'fine', retrieve status from shared data
|
||
|
//
|
||
|
hrStatus = pData->hrStatus;
|
||
|
} else {
|
||
|
//
|
||
|
// failure
|
||
|
//
|
||
|
hrStatus = E_UNEXPECTED;
|
||
|
}
|
||
|
CloseHandle(ProcessInfo.hThread);
|
||
|
CloseHandle(ProcessInfo.hProcess);
|
||
|
|
||
|
final:
|
||
|
if(pData) {
|
||
|
UnmapViewOfFile(pData);
|
||
|
}
|
||
|
if(hMapping) {
|
||
|
CloseHandle(hMapping);
|
||
|
}
|
||
|
return hrStatus;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
ProxyRemoteInstallHandle(
|
||
|
IN HANDLE hShared
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Given a handle to a memory mapped file
|
||
|
marshell all the parameters to invoke InstallExceptionPackFromInf
|
||
|
and marshell result back
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
hShared - handle to memory mapped file
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
none, status returned via shared memory region
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
PPROXY_DATA pData = NULL;
|
||
|
|
||
|
try {
|
||
|
|
||
|
//
|
||
|
// Map the whole region
|
||
|
//
|
||
|
pData = MapViewOfFile(
|
||
|
hShared,
|
||
|
FILE_MAP_ALL_ACCESS,
|
||
|
0,
|
||
|
0,
|
||
|
sizeof(PROXY_DATA)
|
||
|
);
|
||
|
|
||
|
if(pData) {
|
||
|
pData->hrStatus = InstallExceptionPackFromInf(pData->InfPath,pData->Media,pData->Store,pData->Flags);
|
||
|
UnmapViewOfFile(pData);
|
||
|
}
|
||
|
|
||
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
||
|
if(pData) {
|
||
|
UnmapViewOfFile(pData);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
WINAPI
|
||
|
ProxyRemoteInstallW(
|
||
|
IN HWND Window,
|
||
|
IN HINSTANCE ModuleHandle,
|
||
|
IN PCWSTR CommandLine,
|
||
|
IN INT ShowCommand
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Remote side of the proxy install process
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Window - ignored
|
||
|
ModuleHandle - ignored
|
||
|
CommandLine - "0xXXXX" - shared handle
|
||
|
ShowCommand - ignored
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
none, status returned via shared memory region
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
ULONG_PTR val = wcstol(CommandLine,NULL,0);
|
||
|
ProxyRemoteInstallHandle((HANDLE)val);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
WINAPI
|
||
|
ProxyRemoteInstallA(
|
||
|
IN HWND Window,
|
||
|
IN HINSTANCE ModuleHandle,
|
||
|
IN PCSTR CommandLine,
|
||
|
IN INT ShowCommand
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Remote side of the proxy install process
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Window - ignored
|
||
|
ModuleHandle - ignored
|
||
|
CommandLine - "0xXXXX" - shared handle
|
||
|
ShowCommand - ignored
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
none, status returned via shared memory region
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
ULONG_PTR val = strtol(CommandLine,NULL,0);
|
||
|
ProxyRemoteInstallHandle((HANDLE)val);
|
||
|
}
|
||
|
|
||
|
|