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.

295 lines
10 KiB

  1. // --------------------------------------------------------------------------
  2. // Module Name: FUSAPI.cpp
  3. //
  4. // Copyright (c) 2000, Microsoft Corporation
  5. //
  6. // Class to manage communication with the BAM server for shims.
  7. //
  8. // History: 11/03/2000 vtan created
  9. // 11/29/2000 a-larrsh Ported to Multi-Shim Format
  10. // --------------------------------------------------------------------------
  11. #include "precomp.h"
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <lpcfus.h>
  17. #include "FUSAPI.h"
  18. #ifndef ARRAYSIZE
  19. #define ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0]))
  20. #endif
  21. #define TBOOL(x) (BOOL)(x)
  22. #define TSTATUS(x) (NTSTATUS)(x)
  23. // --------------------------------------------------------------------------
  24. // CFUSAPI::CFUSAPI
  25. //
  26. // Arguments: pszImageName = Image name of the desired process.
  27. //
  28. // Returns: <none>
  29. //
  30. // Purpose: Constructor for CFUSAPI. Establishes a connection with the
  31. // BAM server. Saves off the image name given or the image name
  32. // of the current process if not specified.
  33. //
  34. // History: 2000-11-03 vtan created
  35. // --------------------------------------------------------------------------
  36. CFUSAPI::CFUSAPI (const WCHAR *pszImageName) :
  37. _hPort(NULL),
  38. _pszImageName(NULL)
  39. {
  40. ULONG ulConnectionInfoLength;
  41. UNICODE_STRING portName, *pImageName;
  42. SECURITY_QUALITY_OF_SERVICE sqos;
  43. WCHAR szConnectionInfo[32];
  44. RtlInitUnicodeString(&portName, FUS_PORT_NAME);
  45. sqos.Length = sizeof(sqos);
  46. sqos.ImpersonationLevel = SecurityImpersonation;
  47. sqos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
  48. sqos.EffectiveOnly = TRUE;
  49. lstrcpyW(szConnectionInfo, FUS_CONNECTION_REQUEST);
  50. ulConnectionInfoLength = sizeof(szConnectionInfo);
  51. TSTATUS(NtConnectPort(&_hPort,
  52. &portName,
  53. &sqos,
  54. NULL,
  55. NULL,
  56. NULL,
  57. szConnectionInfo,
  58. &ulConnectionInfoLength));
  59. if (pszImageName != NULL)
  60. {
  61. _pszImageName = static_cast<WCHAR*>(LocalAlloc(LMEM_FIXED, (lstrlen(pszImageName) + sizeof('\0')) * sizeof(WCHAR)));
  62. if (_pszImageName != NULL)
  63. {
  64. (TCHAR*)lstrcpy(_pszImageName, pszImageName);
  65. }
  66. }
  67. else
  68. {
  69. pImageName = &NtCurrentPeb()->ProcessParameters->ImagePathName;
  70. _pszImageName = static_cast<WCHAR*>(LocalAlloc(LMEM_FIXED, pImageName->Length + sizeof(WCHAR)));
  71. if (_pszImageName != NULL)
  72. {
  73. CopyMemory(_pszImageName, pImageName->Buffer, pImageName->Length);
  74. _pszImageName[pImageName->Length / sizeof(WCHAR)] = L'\0';
  75. }
  76. }
  77. }
  78. // --------------------------------------------------------------------------
  79. // CFUSAPI::~CFUSAPI
  80. //
  81. // Arguments: <none>
  82. //
  83. // Returns: <none>
  84. //
  85. // Purpose: Destructor for CFUSAPI. Releases resources used by the class.
  86. //
  87. // History: 2000-11-03 vtan created
  88. // --------------------------------------------------------------------------
  89. CFUSAPI::~CFUSAPI (void)
  90. {
  91. if (_pszImageName != NULL)
  92. {
  93. (HLOCAL)LocalFree(_pszImageName);
  94. _pszImageName = NULL;
  95. }
  96. if (_hPort != NULL)
  97. {
  98. TBOOL(CloseHandle(_hPort));
  99. _hPort = NULL;
  100. }
  101. }
  102. // --------------------------------------------------------------------------
  103. // CFUSAPI::IsRunning
  104. //
  105. // Arguments: <none>
  106. //
  107. // Returns: bool
  108. //
  109. // Purpose: Asks the BAM server is the image name running?
  110. //
  111. // History: 2000-11-03 vtan created
  112. // --------------------------------------------------------------------------
  113. bool CFUSAPI::IsRunning (void)
  114. {
  115. bool fResult;
  116. fResult = false;
  117. if ((_hPort != NULL) && (_pszImageName != NULL))
  118. {
  119. FUSAPI_PORT_MESSAGE portMessageIn, portMessageOut;
  120. ZeroMemory(&portMessageIn, sizeof(portMessageIn));
  121. ZeroMemory(&portMessageOut, sizeof(portMessageOut));
  122. portMessageIn.apiBAM.apiGeneric.ulAPINumber = API_BAM_QUERYRUNNING;
  123. portMessageIn.apiBAM.apiSpecific.apiQueryRunning.in.pszImageName = _pszImageName;
  124. portMessageIn.apiBAM.apiSpecific.apiQueryRunning.in.cchImageName = lstrlenW(_pszImageName) + sizeof('\0');
  125. portMessageIn.portMessage.u1.s1.DataLength = sizeof(API_BAM);
  126. portMessageIn.portMessage.u1.s1.TotalLength = static_cast<CSHORT>(sizeof(FUSAPI_PORT_MESSAGE));
  127. if (NT_SUCCESS(NtRequestWaitReplyPort(_hPort, &portMessageIn.portMessage, &portMessageOut.portMessage)) &&
  128. NT_SUCCESS(portMessageOut.apiBAM.apiGeneric.status))
  129. {
  130. fResult = portMessageOut.apiBAM.apiSpecific.apiQueryRunning.out.fResult;
  131. }
  132. }
  133. return(fResult);
  134. }
  135. // --------------------------------------------------------------------------
  136. // CFUSAPI::TerminatedFirstInstance
  137. //
  138. // Arguments: <none>
  139. //
  140. // Returns: bool
  141. //
  142. // Purpose: Starts a child process to bring up UI for the current process.
  143. // The current process is shim'd typically as a BAM type 1
  144. // process. The child process makes the decision and presents
  145. // appropriate UI and returns the result to this process in the
  146. // exit code. This process then makes a decision on what to do.
  147. // The process is halted waiting for the child process (with the
  148. // loader lock held).
  149. //
  150. // History: 2000-11-03 vtan created
  151. // --------------------------------------------------------------------------
  152. bool CFUSAPI::TerminatedFirstInstance (void)
  153. {
  154. bool fResult;
  155. HANDLE hProcess;
  156. STARTUPINFO startupInfo;
  157. PROCESS_INFORMATION processInformation;
  158. WCHAR szCommandLine[MAX_PATH];
  159. fResult = false;
  160. (DWORD)ExpandEnvironmentStringsW(L"%systemroot%\\system32\\rundll32.exe %systemroot%\\system32\\shsvcs.dll,FUSCompatibilityEntry prompt", szCommandLine, ARRAYSIZE(szCommandLine));
  161. if (DuplicateHandle(GetCurrentProcess(),
  162. GetCurrentProcess(),
  163. GetCurrentProcess(),
  164. &hProcess,
  165. PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
  166. TRUE,
  167. 0) != FALSE)
  168. {
  169. WCHAR szProcessHandle[16];
  170. DWORDToString(HandleToULong(hProcess), szProcessHandle);
  171. (WCHAR*)lstrcatW(szCommandLine, L" ");
  172. (WCHAR*)lstrcatW(szCommandLine, szProcessHandle);
  173. }
  174. else
  175. {
  176. hProcess = NULL;
  177. }
  178. ZeroMemory(&startupInfo, sizeof(startupInfo));
  179. ZeroMemory(&processInformation, sizeof(processInformation));
  180. startupInfo.cb = sizeof(startupInfo);
  181. if (CreateProcessW(NULL,
  182. szCommandLine,
  183. NULL,
  184. NULL,
  185. TRUE,
  186. 0,
  187. NULL,
  188. NULL,
  189. &startupInfo,
  190. &processInformation) != FALSE)
  191. {
  192. DWORD dwExitCode;
  193. TBOOL(CloseHandle(processInformation.hThread));
  194. (DWORD)WaitForSingleObject(processInformation.hProcess, INFINITE);
  195. dwExitCode = 0;
  196. TBOOL(GetExitCodeProcess(processInformation.hProcess, &dwExitCode));
  197. fResult = (dwExitCode != 0);
  198. TBOOL(CloseHandle(processInformation.hProcess));
  199. }
  200. if (hProcess != NULL)
  201. {
  202. TBOOL(CloseHandle(hProcess));
  203. }
  204. return(fResult);
  205. }
  206. // --------------------------------------------------------------------------
  207. // CFUSAPI::RegisterBadApplication
  208. //
  209. // Arguments: bamType = BAM type of the current process.
  210. //
  211. // Returns: <none>
  212. //
  213. // Purpose: Registers with the BAM server this process (image name) as a
  214. // bad application of type whatever is passed in. The different
  215. // BAM shims pass in different parameters.
  216. //
  217. // History: 2000-11-03 vtan created
  218. // --------------------------------------------------------------------------
  219. void CFUSAPI::RegisterBadApplication (BAM_TYPE bamType)
  220. {
  221. if ((_hPort != NULL) && (_pszImageName != NULL))
  222. {
  223. FUSAPI_PORT_MESSAGE portMessageIn, portMessageOut;
  224. ZeroMemory(&portMessageIn, sizeof(portMessageIn));
  225. ZeroMemory(&portMessageOut, sizeof(portMessageOut));
  226. portMessageIn.apiBAM.apiGeneric.ulAPINumber = API_BAM_REGISTERRUNNING;
  227. portMessageIn.apiBAM.apiSpecific.apiRegisterRunning.in.pszImageName = _pszImageName;
  228. portMessageIn.apiBAM.apiSpecific.apiRegisterRunning.in.cchImageName = lstrlen(_pszImageName) + sizeof('\0');
  229. portMessageIn.apiBAM.apiSpecific.apiRegisterRunning.in.dwProcessID = GetCurrentProcessId();
  230. portMessageIn.apiBAM.apiSpecific.apiRegisterRunning.in.bamType = bamType;
  231. portMessageIn.portMessage.u1.s1.DataLength = sizeof(API_BAM);
  232. portMessageIn.portMessage.u1.s1.TotalLength = static_cast<CSHORT>(sizeof(FUSAPI_PORT_MESSAGE));
  233. TSTATUS(NtRequestWaitReplyPort(_hPort, &portMessageIn.portMessage, &portMessageOut.portMessage));
  234. }
  235. }
  236. // --------------------------------------------------------------------------
  237. // CFUSAPI::DWORDToString
  238. //
  239. // Arguments: dwNumber = DWORD to convert to a string.
  240. // pszString = Buffer that gets the result.
  241. //
  242. // Returns: <none>
  243. //
  244. // Purpose: Implements wsprintf(pszString, TEXT("%ld"), dwNumber) because
  245. // this code CANNOT use user32 imports.
  246. //
  247. // History: 2000-11-08 vtan created
  248. // --------------------------------------------------------------------------
  249. void CFUSAPI::DWORDToString (DWORD dwNumber, WCHAR *pszString)
  250. {
  251. int i;
  252. WCHAR szTemp[16];
  253. i = 0;
  254. do
  255. {
  256. szTemp[i++] = L'0' + static_cast<WCHAR>(dwNumber % 10);
  257. dwNumber /= 10;
  258. } while (dwNumber != 0);
  259. do
  260. {
  261. --i;
  262. *pszString++ = szTemp[i];
  263. } while (i != 0);
  264. *pszString = L'\0';
  265. }