|
|
/*++
Copyright (c) 1999-2000 Microsoft Corporation
Module Name:
wow64ipc.c
Abstract:
This module will do the communication machanism among different processes that need to interact with the wow64 services, like winlogon will notify wow64svc.
Author:
ATM Shafiqul Khalid (askhalid) 22-Mar-2000
Revision History:
--*/
#include <windows.h>
#include <memory.h>
#include <wow64reg.h>
#include <stdio.h>
#include "reflectr.h"
#define SHMEMSIZE 4096
LPVOID lpvMem = NULL; // pointer to shared memory
HANDLE hMapObject = NULL;
HANDLE hWow64Event = NULL; HANDLE hWow64Mutex = NULL;
LIST_OBJECT *pList = NULL;
//SECURITY_DESCRIPTOR sdWow64SharedMemory;
//SECURITY_ATTRIBUTES saWow64SharedMemory;
BOOL Wow64CreateLock ( DWORD dwOption ) /*++
Routine Description:
Create or open Event wow64 service need to check.
Arguments:
dwOption - OPEN_EXISTING_SHARED_MEMORY -- shouldn't be the first process to create this.
Return Value:
TRUE if the function has successfully created/opened the memory. FALSE otherwise.
--*/
{ hWow64Mutex = CreateMutex( NULL, // SD
FALSE,// initial owner
WOW64_SVC_REFLECTOR_MUTEX_NAME // object name
); if ( hWow64Mutex == NULL ) return FALSE;
if ( GetLastError() != ERROR_ALREADY_EXISTS && dwOption == OPEN_EXISTING_SHARED_RESOURCES) {
Wow64CloseLock (); return FALSE; }
return TRUE;
}
VOID Wow64CloseLock ()
/*++
Routine Description:
Close wow64 service event.
Arguments:
None.
Return Value:
None.
--*/ { if ( NULL != hWow64Mutex ) CloseHandle ( hWow64Mutex ); hWow64Mutex = NULL; } Wow64CreateEvent ( DWORD dwOption, HANDLE *hEvent ) /*++
Routine Description:
Create or open Event wow64 service need to check.
Arguments:
dwOption - OPEN_EXISTING_SHARED_MEMORY -- shouldn't be the first process to create this.
Return Value:
TRUE if the function has successfully created/opened the memory. FALSE otherwise.
--*/
{ *hEvent = NULL;
hWow64Event = CreateEvent( NULL, // SD
TRUE, // reset type
FALSE,// initial state
WOW64_SVC_REFLECTOR_EVENT_NAME // object name
); if ( hWow64Event == NULL ) return FALSE;
if ( GetLastError() != ERROR_ALREADY_EXISTS && dwOption == OPEN_EXISTING_SHARED_RESOURCES) {
Wow64CloseEvent (); return FALSE; }
*hEvent = hWow64Event; return TRUE;
}
VOID Wow64CloseEvent ()
/*++
Routine Description:
Close wow64 service event.
Arguments:
None.
Return Value:
None.
--*/ { if ( NULL != hWow64Event ) CloseHandle ( hWow64Event ); hWow64Event = NULL; }
BOOL LockSharedMemory () { DWORD Ret; Ret = WaitForSingleObject( hWow64Mutex, 1000*5*60); // 5 min is good enough
//
// now you can access shared memory
//
//Log information if error occur
if ( Ret == WAIT_OBJECT_0 || Ret == WAIT_ABANDONED ) return TRUE;
//
// check for abandaned case
//
return FALSE;
}
BOOL UnLockSharedMemory () { if ( ReleaseMutex ( hWow64Mutex ) ) return TRUE;
return FALSE; }
BOOL CreateSharedMemory ( DWORD dwOption ) /*++
Routine Description:
Create or open shared memory, used by different process.
Arguments:
dwOption - OPEN_EXISTING_SHARED_MEMORY -- shouldn't be the first process to create this.
Return Value:
TRUE if the function has successfully created/opened the memory. FALSE otherwise.
--*/
{ BOOL fInit;
//if (!InitializeSecurityDescriptor( &sdWow64SharedMemory, SECURITY_DESCRIPTOR_REVISION ))
// return FALSE;
// saWow64SharedMemory.nLength = sizeof ( SECURITY_ATTRIBUTES );
// saWow64SharedMemory.bInheritHandle = TRUE;
// saWow64SharedMemory.lpSecurityDescriptor = &sdWow64SharedMemory;
// Create a named file mapping object.
hMapObject = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file
NULL, //&saWow64SharedMemory, // no security attributes
PAGE_READWRITE, // read/write access
0, // size: high 32-bits
SHMEMSIZE, // size: low 32-bits
SHRED_MEMORY_NAME ); // name of map object
if (hMapObject == NULL) return FALSE; // The first process to attach initializes memory.
fInit = (GetLastError() != ERROR_ALREADY_EXISTS);
if (fInit && dwOption == OPEN_EXISTING_SHARED_RESOURCES ) {
CloseSharedMemory (); return FALSE; // no shared memory exist
} // Get a pointer to the file-mapped shared memory.
pList = (LIST_OBJECT *) MapViewOfFile( hMapObject, // object to map view of
FILE_MAP_WRITE, // read/write access
0, // high offset: map from
0, // low offset: beginning
0); // default: map entire file
if (pList == NULL) return FALSE; // Initialize memory if this is the first process.
if (fInit) { memset( ( PBYTE )pList, '\0', SHMEMSIZE); pList->MaxCount = ( SHMEMSIZE - sizeof ( LIST_OBJECT ) ) / (LIST_NAME_LEN*sizeof (WCHAR)); }
//
// Also initialize all the locking and synchronization object
//
if ( !Wow64CreateLock ( dwOption ) ) { CloseSharedMemory (); return FALSE; } return TRUE; }
VOID CloseSharedMemory () {
if (pList != NULL ) UnmapViewOfFile(pList); pList = NULL; // Close the process's handle to the file-mapping object.
if ( hMapObject!= NULL ) CloseHandle(hMapObject); hMapObject = NULL;
Wow64CloseLock (); }
// initially try to transfer only one object
BOOL EnQueueObject ( PWCHAR pObjName, WCHAR Type ) /*++
Routine Description:
Put an object name in the queue.
Arguments:
pObjName - Name of the object to put in the quque. Type - L: Loading hive U: Unloading Hive
Return Value:
TRUE if the function has successfully created/opened the memory. FALSE otherwise.
--*/ { // lpvMem check if this value is NULL
// wait to get the lock on shared memory
DWORD Len; DWORD i;
if ( pList == NULL ) return FALSE;
Len = wcslen (pObjName); if (Len == 0 || Len > 256 ) return FALSE;
if (!LockSharedMemory ()) return FALSE;
if ( pList->Count == pList->MaxCount ) { UnLockSharedMemory (); return FALSE; }
for ( i=0; i<pList->MaxCount; i++) { if (pList->Name[i][0] == UNICODE_NULL ) break; }
if ( i == pList->MaxCount ) { UnLockSharedMemory (); return FALSE; }
wcscpy ( pList->Name[i], pObjName); pList->Count++; pList->Name[i][LIST_NAME_LEN-1] = Type;
UnLockSharedMemory (); SignalWow64Svc ();
// write data
// release data
return TRUE; }
BOOL DeQueueObject ( PWCHAR pObjName, PWCHAR Type ) /*++
Routine Description:
Get a name of object from the queue.
Arguments:
pObjName - Name of the object that receive the name. Type - L: Loading hive U: Unloading Hive
Return Value:
TRUE if the function has successfully created/opened the memory. FALSE otherwise.
--*/ { // lpvMem check if this value is NULL
// wait to get the lock on shared memory
DWORD Len; DWORD i;
if ( pList == NULL ) return FALSE;
if (!LockSharedMemory ()) return FALSE;
if ( pList->Count == 0 ) { UnLockSharedMemory (); return FALSE; }
for ( i=0; i < pList->MaxCount; i++) { if (pList->Name[i][0] != UNICODE_NULL ) break; }
if ( i == pList->MaxCount ) { UnLockSharedMemory (); return FALSE; }
wcscpy ( pObjName, pList->Name[i]); pList->Name[i][0] = UNICODE_NULL;
pList->Count--; *Type = pList->Name[i][LIST_NAME_LEN-1];
UnLockSharedMemory (); //SignalWow64Svc ();
// write data
// release data
return TRUE; } //signal wowservice to receive the data.
BOOL SignalWow64Svc () { //this might be a simple event trigger or set event
if ( SetEvent ( hWow64Event ) ) return TRUE;
return FALSE;
}
BOOL CheckAdminPriviledge () /*++
Routine Description:
Check if the running thread has admin priviledge.
Arguments:
None.
Return Value:
TRUE if the calling thread has admin proviledge. FALSE otherwise.
--*/ { BOOL bRetCode = FALSE; /*
HANDLE TokenHandle; BOOL b; DWORD ReturnLength;
PTOKEN_USER TokenInfo;
//
// If we're impersonating, use the thread token, otherwise
// use the process token.
//
PTOKEN_USER Result = NULL;
b = OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, FALSE, &TokenHandle );
if (!b) {
if (GetLastError() == ERROR_NO_TOKEN) {
//
// We're not impersonating, try the process token
//
b = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
if (!b) {
return FALSE; }
} else {
//
// We failed for some unexpected reason, return NULL and
// let the caller figure it out if he so chooses.
//
return FALSE; } }
ReturnLength = GetSidLengthRequired( SID_MAX_SUB_AUTHORITIES ) + sizeof( TOKEN_USER );
TokenInfo = (PTOKEN_USER)malloc( ReturnLength );
if (TokenInfo != NULL) {
b = GetTokenInformation ( TokenHandle, TokenGroups, TokenInfo, ReturnLength, &ReturnLength );
if (b) {
Result = TokenInfo;
} else {
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
//
// Reallocate TokenInfo
//
free( TokenInfo );
TokenInfo = (PTOKEN_USER)malloc( ReturnLength );
if (TokenInfo != NULL) {
b = GetTokenInformation ( TokenHandle, TokenGroups, TokenInfo, ReturnLength, &ReturnLength );
if (b) {
Result = TokenInfo; }
} else {
SetLastError( ERROR_NOT_ENOUGH_MEMORY ); return FALSE; } } }
} else {
SetLastError( ERROR_NOT_ENOUGH_MEMORY ); return FALSE; }
DWORD dwSidSize = 0; SID_NAME_USE SidType; DWORD strSize = 80; WCHAR str [80]; SID_NAME_USE sidType; BOOL bProceede = TRUE;
DWORD dwRet = LookupAccountName ( NULL, L"Administrators", NULL, &dwSidSize, str, &strSize, &sidType );
if ( dwSidSize == 0) if ( !dwRet ) { cBase.PrintErrorWin32 ( GetLastError () ); bProceede = FALSE;
}
PSID psid = NULL;
if ( bProceede ) if ( dwSidSize ) { psid = (PSID) GlobalAlloc ( GPTR, dwSidSize );
if ( psid == NULL ) bProceede = FALSE; else { strSize = 80; dwRet = LookupAccountName ( NULL, L"Administrators", psid, &dwSidSize, str, &strSize, &sidType ); if ( ! dwRet ) bProceede = FALSE; } }
//now check
if ( Result == NULL ) bProceede = FALSE;
TOKEN_GROUPS *pGroups = ( TOKEN_GROUPS *)Result; if ( bProceede ) for ( int i=0; i < pGroups->GroupCount; i++ ) { if ( EqualSid ( pGroups->Groups [i].Sid, psid ) ){ bRetCode = TRUE; break; } };
if ( psid != NULL ) GlobalFree ( psid );
if ( Result != NULL ) free ( Result );
*/ return bRetCode; }
|