Source code of Windows XP (NT5)
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.

312 lines
6.9 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All Rights Reserved.
  3. Module Name:
  4. proxyinst.c
  5. Abstract:
  6. Exception Pack installer helper DLL
  7. Can be used as a co-installer, or called via setup app, or RunDll32 stub
  8. This DLL is for internal distribution of exception packs to update
  9. OS components.
  10. Author:
  11. Jamie Hunter (jamiehun) 2001-11-27
  12. Revision History:
  13. Jamie Hunter (jamiehun) 2001-11-27
  14. Initial Version
  15. --*/
  16. #include "msoobcip.h"
  17. typedef struct _PROXY_DATA {
  18. TCHAR InfPath[MAX_PATH];
  19. TCHAR Media[MAX_PATH];
  20. TCHAR Store[MAX_PATH];
  21. DWORD Flags;
  22. HRESULT hrStatus;
  23. } PROXY_DATA, * PPROXY_DATA;
  24. HRESULT
  25. ProxyInstallExceptionPackFromInf(
  26. IN LPCTSTR InfPath,
  27. IN LPCTSTR Media,
  28. IN LPCTSTR Store,
  29. IN DWORD Flags
  30. )
  31. /*++
  32. Routine Description:
  33. Kicks off another process, and calls RemoteInstallExceptionPackFromInf in
  34. remote process.
  35. (Bug workaround)
  36. Otherwise as InstallExceptionPackFromInf
  37. Arguments:
  38. InfPath - name of Inf in Media location
  39. Media - InfPath less InfName
  40. Store - expack store
  41. Flags - various flags
  42. Return Value:
  43. status as hresult
  44. --*/
  45. {
  46. HANDLE hMapping = NULL;
  47. DWORD Status;
  48. HRESULT hrStatus;
  49. PPROXY_DATA pData = NULL;
  50. TCHAR ExecName[MAX_PATH];
  51. TCHAR Buffer[MAX_PATH];
  52. TCHAR CmdLine[MAX_PATH*3];
  53. STARTUPINFO StartupInfo;
  54. PROCESS_INFORMATION ProcessInfo;
  55. SECURITY_ATTRIBUTES Security;
  56. UINT uiRes;
  57. //
  58. // create a mapped region of shared data
  59. //
  60. ZeroMemory(&Security,sizeof(Security));
  61. Security.nLength = sizeof(Security);
  62. Security.lpSecurityDescriptor = NULL; // default
  63. Security.bInheritHandle = TRUE;
  64. hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
  65. &Security,
  66. PAGE_READWRITE|SEC_COMMIT,
  67. 0,
  68. sizeof(PROXY_DATA),
  69. NULL);
  70. if(hMapping == NULL) {
  71. Status = GetLastError();
  72. return HRESULT_FROM_WIN32(Status);
  73. }
  74. pData = MapViewOfFile(
  75. hMapping,
  76. FILE_MAP_ALL_ACCESS,
  77. 0,
  78. 0,
  79. sizeof(PROXY_DATA)
  80. );
  81. if(!pData) {
  82. Status = GetLastError();
  83. hrStatus = HRESULT_FROM_WIN32(Status);
  84. goto final;
  85. }
  86. ZeroMemory(pData,sizeof(PROXY_DATA));
  87. lstrcpyn(pData->InfPath,InfPath,MAX_PATH);
  88. lstrcpyn(pData->Media,Media,MAX_PATH);
  89. lstrcpyn(pData->Store,Store,MAX_PATH);
  90. pData->Flags = Flags;
  91. pData->hrStatus = E_UNEXPECTED;
  92. //
  93. // invoke the remote function
  94. //
  95. uiRes = GetSystemDirectory(ExecName,MAX_PATH);
  96. if(uiRes>=MAX_PATH) {
  97. hrStatus = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  98. goto final;
  99. }
  100. ConcatPath(ExecName,MAX_PATH,TEXT("rundll32.exe"));
  101. uiRes = GetModuleFileName(g_DllHandle,CmdLine,MAX_PATH);
  102. if(uiRes>=MAX_PATH) {
  103. hrStatus = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  104. goto final;
  105. }
  106. //
  107. // convert this to short name to ensure no spaces in path
  108. // (hacky)
  109. //
  110. uiRes = GetShortPathName(CmdLine,Buffer,MAX_PATH);
  111. if(uiRes>=MAX_PATH) {
  112. hrStatus = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  113. goto final;
  114. }
  115. //
  116. // now build up command line
  117. //
  118. lstrcpy(CmdLine,ExecName);
  119. lstrcat(CmdLine,TEXT(" "));
  120. lstrcat(CmdLine,Buffer);
  121. _stprintf(Buffer,TEXT(",ProxyRemoteInstall 0x%08x"),(ULONG_PTR)hMapping);
  122. lstrcat(CmdLine,Buffer);
  123. ZeroMemory(&StartupInfo,sizeof(StartupInfo));
  124. StartupInfo.cb = sizeof(StartupInfo);
  125. ZeroMemory(&ProcessInfo,sizeof(ProcessInfo));
  126. //
  127. // kick off rundll32 process to run our ProxyRemoteInstall entrypoint
  128. //
  129. if(!CreateProcess(ExecName,
  130. CmdLine,
  131. NULL,
  132. NULL,
  133. TRUE, // inherit handles
  134. CREATE_NO_WINDOW, // creation flags
  135. NULL, // environment
  136. NULL, // directory
  137. &StartupInfo,
  138. &ProcessInfo
  139. )) {
  140. Status = GetLastError();
  141. hrStatus = HRESULT_FROM_WIN32(Status);
  142. goto final;
  143. }
  144. if(WaitForSingleObject(ProcessInfo.hProcess,INFINITE) == WAIT_OBJECT_0) {
  145. //
  146. // process terminated 'fine', retrieve status from shared data
  147. //
  148. hrStatus = pData->hrStatus;
  149. } else {
  150. //
  151. // failure
  152. //
  153. hrStatus = E_UNEXPECTED;
  154. }
  155. CloseHandle(ProcessInfo.hThread);
  156. CloseHandle(ProcessInfo.hProcess);
  157. final:
  158. if(pData) {
  159. UnmapViewOfFile(pData);
  160. }
  161. if(hMapping) {
  162. CloseHandle(hMapping);
  163. }
  164. return hrStatus;
  165. }
  166. VOID
  167. ProxyRemoteInstallHandle(
  168. IN HANDLE hShared
  169. )
  170. /*++
  171. Routine Description:
  172. Given a handle to a memory mapped file
  173. marshell all the parameters to invoke InstallExceptionPackFromInf
  174. and marshell result back
  175. Arguments:
  176. hShared - handle to memory mapped file
  177. Return Value:
  178. none, status returned via shared memory region
  179. --*/
  180. {
  181. PPROXY_DATA pData = NULL;
  182. try {
  183. //
  184. // Map the whole region
  185. //
  186. pData = MapViewOfFile(
  187. hShared,
  188. FILE_MAP_ALL_ACCESS,
  189. 0,
  190. 0,
  191. sizeof(PROXY_DATA)
  192. );
  193. if(pData) {
  194. pData->hrStatus = InstallExceptionPackFromInf(pData->InfPath,pData->Media,pData->Store,pData->Flags);
  195. UnmapViewOfFile(pData);
  196. }
  197. } except(EXCEPTION_EXECUTE_HANDLER) {
  198. if(pData) {
  199. UnmapViewOfFile(pData);
  200. }
  201. }
  202. }
  203. VOID
  204. WINAPI
  205. ProxyRemoteInstallW(
  206. IN HWND Window,
  207. IN HINSTANCE ModuleHandle,
  208. IN PCWSTR CommandLine,
  209. IN INT ShowCommand
  210. )
  211. /*++
  212. Routine Description:
  213. Remote side of the proxy install process
  214. Arguments:
  215. Window - ignored
  216. ModuleHandle - ignored
  217. CommandLine - "0xXXXX" - shared handle
  218. ShowCommand - ignored
  219. Return Value:
  220. none, status returned via shared memory region
  221. --*/
  222. {
  223. ULONG_PTR val = wcstol(CommandLine,NULL,0);
  224. ProxyRemoteInstallHandle((HANDLE)val);
  225. }
  226. VOID
  227. WINAPI
  228. ProxyRemoteInstallA(
  229. IN HWND Window,
  230. IN HINSTANCE ModuleHandle,
  231. IN PCSTR CommandLine,
  232. IN INT ShowCommand
  233. )
  234. /*++
  235. Routine Description:
  236. Remote side of the proxy install process
  237. Arguments:
  238. Window - ignored
  239. ModuleHandle - ignored
  240. CommandLine - "0xXXXX" - shared handle
  241. ShowCommand - ignored
  242. Return Value:
  243. none, status returned via shared memory region
  244. --*/
  245. {
  246. ULONG_PTR val = strtol(CommandLine,NULL,0);
  247. ProxyRemoteInstallHandle((HANDLE)val);
  248. }