windows-nt/Source/XPSP1/NT/base/ntsetup/msoobci/proxyinst.c
2020-09-26 16:20:57 +08:00

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);
}