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.

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