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.

275 lines
8.2 KiB

  1. /*
  2. Cache handling functions for use in kernel32.dll
  3. VadimB
  4. */
  5. #include "basedll.h"
  6. #include "ahcache.h"
  7. #pragma hdrstop
  8. BOOL
  9. NTAPI
  10. BaseCheckRunApp(
  11. IN HANDLE FileHandle,
  12. IN LPCWSTR pwszApplication,
  13. IN PVOID pEnvironment,
  14. IN USHORT uExeType,
  15. IN DWORD dwReason,
  16. OUT PVOID* ppData,
  17. OUT PDWORD pcbData,
  18. OUT PVOID* ppSxsData,
  19. OUT PDWORD pcbSxsData,
  20. OUT PDWORD pdwFusionFlags
  21. )
  22. {
  23. #if defined(BUILD_WOW6432)
  24. return NtWow64CsrBaseCheckRunApp(FileHandle,
  25. pwszApplication,
  26. pEnvironment,
  27. uExeType,
  28. dwReason,
  29. ppData,
  30. pcbData,
  31. ppSxsData,
  32. pcbSxsData,
  33. pdwFusionFlags);
  34. #else
  35. BASE_API_MSG m;
  36. PBASE_CHECK_APPLICATION_COMPATIBILITY_MSG pMsg = &m.u.CheckApplicationCompatibility;
  37. UNICODE_STRING EnvVar;
  38. UNICODE_STRING EnvVarValue;
  39. UNICODE_STRING ApplicationName;
  40. NTSTATUS Status;
  41. ULONG CaptureBufferSize;
  42. ULONG CaptureEnvSize;
  43. ULONG CountMessagePointers = 1; // at least the name of the app
  44. PWCHAR pEnv;
  45. PCSR_CAPTURE_HEADER CaptureBuffer = NULL;
  46. BOOL bRunApp = TRUE;
  47. INT i;
  48. struct _VarDefinitions {
  49. UNICODE_STRING Name;
  50. UNICODE_STRING Value;
  51. } rgImportantVariables[] = {
  52. { RTL_CONSTANT_STRING(L"SHIM_DEBUG_LEVEL") },
  53. { RTL_CONSTANT_STRING(L"SHIM_FILE_LOG") },
  54. { RTL_CONSTANT_STRING(L"__COMPAT_LAYER") },
  55. { RTL_CONSTANT_STRING(L"__PROCESS_HISTORY") }
  56. };
  57. pMsg->FileHandle = FileHandle;
  58. pMsg->CacheCookie = dwReason;
  59. pMsg->ExeType = uExeType;
  60. pMsg->pEnvironment = NULL;
  61. pMsg->pAppCompatData = NULL;
  62. pMsg->cbAppCompatData = 0;
  63. pMsg->pSxsData = NULL;
  64. pMsg->cbSxsData = 0;
  65. pMsg->bRunApp = TRUE; // optimistic please
  66. pMsg->FusionFlags = 0;
  67. RtlInitUnicodeString(&ApplicationName, pwszApplication);
  68. pMsg->FileName.MaximumLength = ApplicationName.Length + sizeof(UNICODE_NULL);
  69. CaptureBufferSize = 0;
  70. CaptureEnvSize = 0;
  71. for (i = 0; i < sizeof(rgImportantVariables)/sizeof(rgImportantVariables[0]); ++i) {
  72. EnvVar.Buffer = NULL;
  73. EnvVar.Length =
  74. EnvVar.MaximumLength = 0;
  75. Status = RtlQueryEnvironmentVariable_U(pEnvironment,
  76. (PUNICODE_STRING)(&rgImportantVariables[i].Name),
  77. &EnvVar);
  78. if (Status == STATUS_BUFFER_TOO_SMALL) {
  79. //
  80. // variable is present, account for the buffer size
  81. // length of the name string + length of the value string + '=' + null char
  82. //
  83. CaptureEnvSize += rgImportantVariables[i].Name.Length +
  84. EnvVar.Length + sizeof(WCHAR) +
  85. sizeof(UNICODE_NULL);
  86. rgImportantVariables[i].Value.MaximumLength = EnvVar.Length + sizeof(UNICODE_NULL);
  87. }
  88. }
  89. if (CaptureEnvSize != 0) {
  90. CaptureEnvSize += sizeof(UNICODE_NULL);
  91. ++CountMessagePointers;
  92. }
  93. CaptureBufferSize = CaptureEnvSize + pMsg->FileName.MaximumLength;
  94. //
  95. // at this point we either have one or two parameters to place into the buffer
  96. //
  97. CaptureBuffer = CsrAllocateCaptureBuffer(CountMessagePointers,
  98. CaptureBufferSize);
  99. if (CaptureBuffer == NULL) {
  100. DbgPrint("BaseCheckRunApp: Failed to allocate capture buffer size 0x%lx\n", CaptureBufferSize);
  101. goto Cleanup;
  102. }
  103. //
  104. // start allocating message data
  105. //
  106. CsrAllocateMessagePointer(CaptureBuffer,
  107. pMsg->FileName.MaximumLength,
  108. (PVOID)&pMsg->FileName.Buffer);
  109. RtlCopyUnicodeString(&pMsg->FileName, &ApplicationName);
  110. //
  111. // now let's do our "mini-environment block"
  112. //
  113. if (CaptureEnvSize) {
  114. CsrAllocateMessagePointer(CaptureBuffer,
  115. CaptureEnvSize,
  116. (PVOID)&pMsg->pEnvironment);
  117. //
  118. // loop through the vars and create mini-env
  119. //
  120. pEnv = pMsg->pEnvironment;
  121. pMsg->EnvironmentSize = CaptureEnvSize;
  122. for (i = 0; i < sizeof(rgImportantVariables)/sizeof(rgImportantVariables[0]); ++i) {
  123. if (rgImportantVariables[i].Value.MaximumLength == 0) {
  124. continue;
  125. }
  126. //
  127. // we incorporate this variable
  128. //
  129. EnvVar.Buffer = pEnv;
  130. EnvVar.Length = 0;
  131. EnvVar.MaximumLength = (USHORT)CaptureEnvSize;
  132. Status = RtlAppendUnicodeStringToString(&EnvVar, &rgImportantVariables[i].Name);
  133. if (!NT_SUCCESS(Status)) {
  134. //
  135. // skip this one
  136. //
  137. continue;
  138. }
  139. Status = RtlAppendUnicodeToString(&EnvVar, L"=");
  140. if (!NT_SUCCESS(Status)) {
  141. continue;
  142. }
  143. //
  144. // now query the variable
  145. //
  146. EnvVarValue.Buffer = pEnv + (EnvVar.Length / sizeof(WCHAR));
  147. EnvVarValue.MaximumLength = (USHORT)(CaptureEnvSize - EnvVar.Length);
  148. Status = RtlQueryEnvironmentVariable_U(pEnvironment,
  149. (PUNICODE_STRING)&rgImportantVariables[i].Name,
  150. &EnvVarValue);
  151. if (!NT_SUCCESS(Status)) {
  152. continue;
  153. }
  154. //
  155. // make sure we're zero-terminated, adjust the size
  156. //
  157. CaptureEnvSize -= (EnvVar.Length + EnvVarValue.Length);
  158. //
  159. // zero-terminate, it may not be after an rt function call
  160. //
  161. if (CaptureEnvSize < sizeof(UNICODE_NULL) * 2) {
  162. //
  163. // can't zero-terminate
  164. //
  165. continue;
  166. }
  167. *(pEnv + (EnvVar.Length + EnvVarValue.Length) / sizeof(WCHAR)) = L'\0';
  168. CaptureEnvSize -= sizeof(UNICODE_NULL);
  169. pEnv += (EnvVar.Length + EnvVarValue.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
  170. }
  171. //
  172. // we always slap another zero at the end please
  173. //
  174. if (CaptureEnvSize < sizeof(UNICODE_NULL)) {
  175. //
  176. // we cannot double-null terminate, forget the call then, we have failed to transport environment
  177. // this situation however is impossible -- we will always have at least that much space left
  178. //
  179. goto Cleanup;
  180. }
  181. //
  182. // this ensures our simple validation mechanism in server works
  183. //
  184. RtlZeroMemory(pEnv, CaptureEnvSize);
  185. }
  186. //
  187. // we are ready to commence a csr call
  188. //
  189. Status = CsrClientCallServer((PCSR_API_MSG)&m,
  190. CaptureBuffer,
  191. CSR_MAKE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepCheckApplicationCompatibility),
  192. sizeof(*pMsg));
  193. if (NT_SUCCESS(Status)) {
  194. bRunApp = pMsg->bRunApp;
  195. //
  196. // pointers to the appcompat data
  197. //
  198. *ppData = pMsg->pAppCompatData;
  199. *pcbData = pMsg->cbAppCompatData;
  200. *ppSxsData = pMsg->pSxsData;
  201. *pcbSxsData = pMsg->cbSxsData;
  202. *pdwFusionFlags = pMsg->FusionFlags;
  203. } else {
  204. //
  205. // dbg print here to indicate a failed csr call
  206. //
  207. DbgPrint("BaseCheckRunApp: failed to call csrss 0x%lx\n", Status);
  208. }
  209. Cleanup:
  210. if (CaptureBuffer != NULL) {
  211. CsrFreeCaptureBuffer(CaptureBuffer);
  212. }
  213. return bRunApp;
  214. #endif
  215. }