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.

671 lines
13 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. wow64ipc.c
  5. Abstract:
  6. This module will do the communication machanism among different processes that need
  7. to interact with the wow64 services, like winlogon will notify wow64svc.
  8. Author:
  9. ATM Shafiqul Khalid (askhalid) 22-Mar-2000
  10. Revision History:
  11. --*/
  12. #include <windows.h>
  13. #include <memory.h>
  14. #include <wow64reg.h>
  15. #include <stdio.h>
  16. #include "reflectr.h"
  17. #define SHMEMSIZE 4096
  18. LPVOID lpvMem = NULL; // pointer to shared memory
  19. HANDLE hMapObject = NULL;
  20. HANDLE hWow64Event = NULL;
  21. HANDLE hWow64Mutex = NULL;
  22. LIST_OBJECT *pList = NULL;
  23. //SECURITY_DESCRIPTOR sdWow64SharedMemory;
  24. //SECURITY_ATTRIBUTES saWow64SharedMemory;
  25. BOOL
  26. Wow64CreateLock (
  27. DWORD dwOption
  28. )
  29. /*++
  30. Routine Description:
  31. Create or open Event wow64 service need to check.
  32. Arguments:
  33. dwOption -
  34. OPEN_EXISTING_SHARED_MEMORY -- shouldn't be the first process to create this.
  35. Return Value:
  36. TRUE if the function has successfully created/opened the memory.
  37. FALSE otherwise.
  38. --*/
  39. {
  40. hWow64Mutex = CreateMutex(
  41. NULL, // SD
  42. FALSE,// initial owner
  43. WOW64_SVC_REFLECTOR_MUTEX_NAME // object name
  44. );
  45. if ( hWow64Mutex == NULL )
  46. return FALSE;
  47. if ( GetLastError() != ERROR_ALREADY_EXISTS && dwOption == OPEN_EXISTING_SHARED_RESOURCES) {
  48. Wow64CloseLock ();
  49. return FALSE;
  50. }
  51. return TRUE;
  52. }
  53. VOID
  54. Wow64CloseLock ()
  55. /*++
  56. Routine Description:
  57. Close wow64 service event.
  58. Arguments:
  59. None.
  60. Return Value:
  61. None.
  62. --*/
  63. {
  64. if ( NULL != hWow64Mutex )
  65. CloseHandle ( hWow64Mutex );
  66. hWow64Mutex = NULL;
  67. }
  68. Wow64CreateEvent (
  69. DWORD dwOption,
  70. HANDLE *hEvent
  71. )
  72. /*++
  73. Routine Description:
  74. Create or open Event wow64 service need to check.
  75. Arguments:
  76. dwOption -
  77. OPEN_EXISTING_SHARED_MEMORY -- shouldn't be the first process to create this.
  78. Return Value:
  79. TRUE if the function has successfully created/opened the memory.
  80. FALSE otherwise.
  81. --*/
  82. {
  83. *hEvent = NULL;
  84. hWow64Event = CreateEvent(
  85. NULL, // SD
  86. TRUE, // reset type
  87. FALSE,// initial state
  88. WOW64_SVC_REFLECTOR_EVENT_NAME // object name
  89. );
  90. if ( hWow64Event == NULL )
  91. return FALSE;
  92. if ( GetLastError() != ERROR_ALREADY_EXISTS && dwOption == OPEN_EXISTING_SHARED_RESOURCES) {
  93. Wow64CloseEvent ();
  94. return FALSE;
  95. }
  96. *hEvent = hWow64Event;
  97. return TRUE;
  98. }
  99. VOID
  100. Wow64CloseEvent ()
  101. /*++
  102. Routine Description:
  103. Close wow64 service event.
  104. Arguments:
  105. None.
  106. Return Value:
  107. None.
  108. --*/
  109. {
  110. if ( NULL != hWow64Event )
  111. CloseHandle ( hWow64Event );
  112. hWow64Event = NULL;
  113. }
  114. BOOL
  115. LockSharedMemory ()
  116. {
  117. DWORD Ret;
  118. Ret = WaitForSingleObject( hWow64Mutex, 1000*5*60); // 5 min is good enough
  119. //
  120. // now you can access shared memory
  121. //
  122. //Log information if error occur
  123. if ( Ret == WAIT_OBJECT_0 || Ret == WAIT_ABANDONED )
  124. return TRUE;
  125. //
  126. // check for abandaned case
  127. //
  128. return FALSE;
  129. }
  130. BOOL
  131. UnLockSharedMemory ()
  132. {
  133. if ( ReleaseMutex ( hWow64Mutex ) )
  134. return TRUE;
  135. return FALSE;
  136. }
  137. BOOL
  138. CreateSharedMemory (
  139. DWORD dwOption
  140. )
  141. /*++
  142. Routine Description:
  143. Create or open shared memory, used by different process.
  144. Arguments:
  145. dwOption -
  146. OPEN_EXISTING_SHARED_MEMORY -- shouldn't be the first process to create this.
  147. Return Value:
  148. TRUE if the function has successfully created/opened the memory.
  149. FALSE otherwise.
  150. --*/
  151. {
  152. BOOL fInit;
  153. //if (!InitializeSecurityDescriptor( &sdWow64SharedMemory, SECURITY_DESCRIPTOR_REVISION ))
  154. // return FALSE;
  155. // saWow64SharedMemory.nLength = sizeof ( SECURITY_ATTRIBUTES );
  156. // saWow64SharedMemory.bInheritHandle = TRUE;
  157. // saWow64SharedMemory.lpSecurityDescriptor = &sdWow64SharedMemory;
  158. // Create a named file mapping object.
  159. hMapObject = CreateFileMapping(
  160. INVALID_HANDLE_VALUE, // use paging file
  161. NULL, //&saWow64SharedMemory, // no security attributes
  162. PAGE_READWRITE, // read/write access
  163. 0, // size: high 32-bits
  164. SHMEMSIZE, // size: low 32-bits
  165. SHRED_MEMORY_NAME ); // name of map object
  166. if (hMapObject == NULL)
  167. return FALSE;
  168. // The first process to attach initializes memory.
  169. fInit = (GetLastError() != ERROR_ALREADY_EXISTS);
  170. if (fInit && dwOption == OPEN_EXISTING_SHARED_RESOURCES ) {
  171. CloseSharedMemory ();
  172. return FALSE; // no shared memory exist
  173. }
  174. // Get a pointer to the file-mapped shared memory.
  175. pList = (LIST_OBJECT *) MapViewOfFile(
  176. hMapObject, // object to map view of
  177. FILE_MAP_WRITE, // read/write access
  178. 0, // high offset: map from
  179. 0, // low offset: beginning
  180. 0); // default: map entire file
  181. if (pList == NULL)
  182. return FALSE;
  183. // Initialize memory if this is the first process.
  184. if (fInit) {
  185. memset( ( PBYTE )pList, '\0', SHMEMSIZE);
  186. pList->MaxCount = ( SHMEMSIZE - sizeof ( LIST_OBJECT ) ) / (LIST_NAME_LEN*sizeof (WCHAR));
  187. }
  188. //
  189. // Also initialize all the locking and synchronization object
  190. //
  191. if ( !Wow64CreateLock ( dwOption ) ) {
  192. CloseSharedMemory ();
  193. return FALSE;
  194. }
  195. return TRUE;
  196. }
  197. VOID
  198. CloseSharedMemory ()
  199. {
  200. if (pList != NULL )
  201. UnmapViewOfFile(pList);
  202. pList = NULL;
  203. // Close the process's handle to the file-mapping object.
  204. if ( hMapObject!= NULL )
  205. CloseHandle(hMapObject);
  206. hMapObject = NULL;
  207. Wow64CloseLock ();
  208. }
  209. // initially try to transfer only one object
  210. BOOL
  211. EnQueueObject (
  212. PWCHAR pObjName,
  213. WCHAR Type
  214. )
  215. /*++
  216. Routine Description:
  217. Put an object name in the queue.
  218. Arguments:
  219. pObjName - Name of the object to put in the quque.
  220. Type - L: Loading hive
  221. U: Unloading Hive
  222. Return Value:
  223. TRUE if the function has successfully created/opened the memory.
  224. FALSE otherwise.
  225. --*/
  226. {
  227. // lpvMem check if this value is NULL
  228. // wait to get the lock on shared memory
  229. DWORD Len;
  230. DWORD i;
  231. if ( pList == NULL )
  232. return FALSE;
  233. Len = wcslen (pObjName);
  234. if (Len == 0 || Len > 256 )
  235. return FALSE;
  236. if (!LockSharedMemory ())
  237. return FALSE;
  238. if ( pList->Count == pList->MaxCount ) {
  239. UnLockSharedMemory ();
  240. return FALSE;
  241. }
  242. for ( i=0; i<pList->MaxCount; i++) {
  243. if (pList->Name[i][0] == UNICODE_NULL ) break;
  244. }
  245. if ( i == pList->MaxCount ) {
  246. UnLockSharedMemory ();
  247. return FALSE;
  248. }
  249. wcscpy ( pList->Name[i], pObjName);
  250. pList->Count++;
  251. pList->Name[i][LIST_NAME_LEN-1] = Type;
  252. UnLockSharedMemory ();
  253. SignalWow64Svc ();
  254. // write data
  255. // release data
  256. return TRUE;
  257. }
  258. BOOL
  259. DeQueueObject (
  260. PWCHAR pObjName,
  261. PWCHAR Type
  262. )
  263. /*++
  264. Routine Description:
  265. Get a name of object from the queue.
  266. Arguments:
  267. pObjName - Name of the object that receive the name.
  268. Type - L: Loading hive
  269. U: Unloading Hive
  270. Return Value:
  271. TRUE if the function has successfully created/opened the memory.
  272. FALSE otherwise.
  273. --*/
  274. {
  275. // lpvMem check if this value is NULL
  276. // wait to get the lock on shared memory
  277. DWORD Len;
  278. DWORD i;
  279. if ( pList == NULL )
  280. return FALSE;
  281. if (!LockSharedMemory ())
  282. return FALSE;
  283. if ( pList->Count == 0 ) {
  284. UnLockSharedMemory ();
  285. return FALSE;
  286. }
  287. for ( i=0; i < pList->MaxCount; i++) {
  288. if (pList->Name[i][0] != UNICODE_NULL ) break;
  289. }
  290. if ( i == pList->MaxCount ) {
  291. UnLockSharedMemory ();
  292. return FALSE;
  293. }
  294. wcscpy ( pObjName, pList->Name[i]);
  295. pList->Name[i][0] = UNICODE_NULL;
  296. pList->Count--;
  297. *Type = pList->Name[i][LIST_NAME_LEN-1];
  298. UnLockSharedMemory ();
  299. //SignalWow64Svc ();
  300. // write data
  301. // release data
  302. return TRUE;
  303. }
  304. //signal wowservice to receive the data.
  305. BOOL
  306. SignalWow64Svc ()
  307. {
  308. //this might be a simple event trigger or set event
  309. if ( SetEvent ( hWow64Event ) )
  310. return TRUE;
  311. return FALSE;
  312. }
  313. BOOL
  314. CheckAdminPriviledge ()
  315. /*++
  316. Routine Description:
  317. Check if the running thread has admin priviledge.
  318. Arguments:
  319. None.
  320. Return Value:
  321. TRUE if the calling thread has admin proviledge.
  322. FALSE otherwise.
  323. --*/
  324. {
  325. BOOL bRetCode = FALSE;
  326. /*
  327. HANDLE TokenHandle;
  328. BOOL b;
  329. DWORD ReturnLength;
  330. PTOKEN_USER TokenInfo;
  331. //
  332. // If we're impersonating, use the thread token, otherwise
  333. // use the process token.
  334. //
  335. PTOKEN_USER Result = NULL;
  336. b = OpenThreadToken(
  337. GetCurrentThread(),
  338. TOKEN_QUERY,
  339. FALSE,
  340. &TokenHandle
  341. );
  342. if (!b) {
  343. if (GetLastError() == ERROR_NO_TOKEN) {
  344. //
  345. // We're not impersonating, try the process token
  346. //
  347. b = OpenProcessToken(
  348. GetCurrentProcess(),
  349. TOKEN_QUERY,
  350. &TokenHandle
  351. );
  352. if (!b) {
  353. return FALSE;
  354. }
  355. } else {
  356. //
  357. // We failed for some unexpected reason, return NULL and
  358. // let the caller figure it out if he so chooses.
  359. //
  360. return FALSE;
  361. }
  362. }
  363. ReturnLength = GetSidLengthRequired( SID_MAX_SUB_AUTHORITIES ) + sizeof( TOKEN_USER );
  364. TokenInfo = (PTOKEN_USER)malloc( ReturnLength );
  365. if (TokenInfo != NULL) {
  366. b = GetTokenInformation (
  367. TokenHandle,
  368. TokenGroups,
  369. TokenInfo,
  370. ReturnLength,
  371. &ReturnLength
  372. );
  373. if (b) {
  374. Result = TokenInfo;
  375. } else {
  376. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
  377. //
  378. // Reallocate TokenInfo
  379. //
  380. free( TokenInfo );
  381. TokenInfo = (PTOKEN_USER)malloc( ReturnLength );
  382. if (TokenInfo != NULL) {
  383. b = GetTokenInformation (
  384. TokenHandle,
  385. TokenGroups,
  386. TokenInfo,
  387. ReturnLength,
  388. &ReturnLength
  389. );
  390. if (b) {
  391. Result = TokenInfo;
  392. }
  393. } else {
  394. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  395. return FALSE;
  396. }
  397. }
  398. }
  399. } else {
  400. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  401. return FALSE;
  402. }
  403. DWORD dwSidSize = 0;
  404. SID_NAME_USE SidType;
  405. DWORD strSize = 80;
  406. WCHAR str [80];
  407. SID_NAME_USE sidType;
  408. BOOL bProceede = TRUE;
  409. DWORD dwRet = LookupAccountName (
  410. NULL,
  411. L"Administrators",
  412. NULL,
  413. &dwSidSize,
  414. str,
  415. &strSize,
  416. &sidType );
  417. if ( dwSidSize == 0)
  418. if ( !dwRet ) {
  419. cBase.PrintErrorWin32 ( GetLastError () );
  420. bProceede = FALSE;
  421. }
  422. PSID psid = NULL;
  423. if ( bProceede )
  424. if ( dwSidSize ) {
  425. psid = (PSID) GlobalAlloc ( GPTR, dwSidSize );
  426. if ( psid == NULL )
  427. bProceede = FALSE;
  428. else {
  429. strSize = 80;
  430. dwRet = LookupAccountName (
  431. NULL,
  432. L"Administrators",
  433. psid,
  434. &dwSidSize,
  435. str,
  436. &strSize,
  437. &sidType );
  438. if ( ! dwRet )
  439. bProceede = FALSE;
  440. }
  441. }
  442. //now check
  443. if ( Result == NULL )
  444. bProceede = FALSE;
  445. TOKEN_GROUPS *pGroups = ( TOKEN_GROUPS *)Result;
  446. if ( bProceede )
  447. for ( int i=0; i < pGroups->GroupCount; i++ ) {
  448. if ( EqualSid ( pGroups->Groups [i].Sid, psid ) ){
  449. bRetCode = TRUE;
  450. break;
  451. }
  452. };
  453. if ( psid != NULL )
  454. GlobalFree ( psid );
  455. if ( Result != NULL )
  456. free ( Result );
  457. */
  458. return bRetCode;
  459. }