|
|
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
share.cpp
Abstract:
SIS Groveler shared data class
Authors:
John Douceur, 1998
Environment:
User Mode
Revision History:
--*/
#include "all.hxx"
static const _TCHAR map_name[] = _T("Groveler Shared Memory"); static const _TCHAR mutex_name[] = _T("Groveler Shared Memory Mutex"); static const int mutex_timeout = 500;
#define ALIGN_INT64(x) \
(((x+sizeof(__int64)-1)/sizeof(__int64))*sizeof(__int64))
SharedData::SharedData( int num_records, _TCHAR **drive_names) { ASSERT(this != 0); ASSERT(num_records <= max_shared_data_records); map_ok = false; mutex = 0; map_handle = 0; map_address = 0; shared_num_records = 0; shared_records = 0; security_identifier = 0; access_control_list = 0; ZeroMemory(&security_attributes, sizeof(SECURITY_ATTRIBUTES)); ZeroMemory(&security_descriptor, sizeof(SECURITY_DESCRIPTOR));
//
// Initailize a Security descriptor so we can setup secure access
// to a shared file.
//
security_attributes.bInheritHandle = FALSE; security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES); security_attributes.lpSecurityDescriptor = (void *)&security_descriptor;
BOOL success = InitializeSecurityDescriptor(&security_descriptor, SECURITY_DESCRIPTOR_REVISION); if (!success) { DWORD err = GetLastError(); PRINT_DEBUG_MSG(( _T("GROVELER: InitializeSecurityDescriptor() failed with error %d\n"), err)); return; }
SID_IDENTIFIER_AUTHORITY sid_authority = SECURITY_NT_AUTHORITY; success = AllocateAndInitializeSid( &sid_authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &security_identifier); if (!success) { DWORD err = GetLastError(); PRINT_DEBUG_MSG(( _T("GROVELER: AllocateAndInitializeSid() failed with error %d\n"), err)); return; }
//
// Create ACL
//
DWORD acl_size = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(security_identifier); access_control_list = (PACL)new BYTE[acl_size];
success = InitializeAcl( access_control_list, acl_size, ACL_REVISION); if (!success) { DWORD err = GetLastError(); PRINT_DEBUG_MSG((_T("GROVELER: InitializeAcl() failed with error %d\n"), err)); return; }
success = AddAccessAllowedAce( access_control_list, ACL_REVISION, GENERIC_ALL, security_identifier); if (!success) { DWORD err = GetLastError(); PRINT_DEBUG_MSG((_T("GROVELER: AddAccessAllowedAce() failed with error %d\n"), err)); return; }
success = SetSecurityDescriptorDacl( &security_descriptor, TRUE, access_control_list, FALSE); if (!success) { DWORD err = GetLastError(); PRINT_DEBUG_MSG((_T("GROVELER: SetSecurityDescriptorDacl() failed with error %d\n"), err)); return; }
//
// Create a named mutex
//
mutex = new NamedMutex(mutex_name, &security_attributes); ASSERT(mutex != 0);
//
// Calcualte size of mapped file
//
int map_size = ALIGN_INT64(sizeof(int)) + ALIGN_INT64(max_shared_data_records * sizeof(SharedDataRecord)); bool ok = mutex->acquire(mutex_timeout); if (!ok) { PRINT_DEBUG_MSG((_T("GROVELER: Mutex::acquire() failed\n"))); return; }
//
// Create the mapped file. Note that it will be backed by system paging
// files.
//
map_handle = CreateFileMapping((HANDLE)-1, &security_attributes, PAGE_READWRITE, 0, map_size, map_name); DWORD map_error = GetLastError(); if (map_handle == 0) { PRINT_DEBUG_MSG((_T("GROVELER: CreateFileMapping() failed with error %d\n"), map_error)); return; } ASSERT(map_error == NO_ERROR || map_error == ERROR_ALREADY_EXISTS);
//
// Map a view for this file
//
map_address = MapViewOfFile(map_handle, FILE_MAP_ALL_ACCESS, 0, 0, map_size); if (map_address == 0) { DWORD err = GetLastError(); PRINT_DEBUG_MSG((_T("GROVELER: MapViewOfFile() failed with error %d\n"), err)); return; }
shared_num_records = (int *)map_address; shared_records = (SharedDataRecord *)ALIGN_INT64((DWORD_PTR)(shared_num_records + 1));
local_num_records = __max(num_records, 0); ZeroMemory(local_records, max_shared_data_records * sizeof(SharedDataRecord));
ASSERT(local_num_records == 0 || drive_names != 0);
for (int index = 0; index < local_num_records; index++) { local_records[index].driveName = drive_names[index]; }
map_ok = true; if (num_records >= 0 || map_error == NO_ERROR) { bool ok = send_values(); }
ok = mutex->release(); if (!ok) { PRINT_DEBUG_MSG((_T("GROVELER: Mutex::release() failed\n"))); } }
SharedData::~SharedData() { ASSERT(this != 0); ASSERT(mutex != 0); delete mutex; mutex = 0; if (map_address != 0) { int ok = UnmapViewOfFile(map_address); if (!ok) { DWORD err = GetLastError(); PRINT_DEBUG_MSG((_T("GROVELER: UnmapViewOfFile() failed with error %d\n"), err)); } map_address = 0; } if (map_handle != 0) { int ok = CloseHandle(map_handle); if (!ok) { DWORD err = GetLastError(); PRINT_DEBUG_MSG((_T("GROVELER: CloseHandle() failed with error %d\n"), err)); } map_handle = 0; } if (security_identifier != 0) { FreeSid(security_identifier); security_identifier = 0; } if (access_control_list != 0) { delete[] access_control_list; access_control_list = 0; } }
int SharedData::count_of_records() const { ASSERT(this != 0); return local_num_records; }
//_TCHAR
//SharedData::drive_letter(
// int record_index) const
//{
// ASSERT(this != 0);
// ASSERT(record_index >= 0);
// ASSERT(record_index < max_shared_data_records);
// ASSERT(record_index < local_num_records);
// return local_records[record_index].drive_letter;
//}
__int64 SharedData::get_value( int record_index, SharedDataField field) { ASSERT(this != 0); ASSERT(record_index >= 0); ASSERT(record_index < max_shared_data_records); ASSERT(record_index < local_num_records); ASSERT(field >= 0); ASSERT(field < num_shared_data_fields); return local_records[record_index].fields[field]; }
void SharedData::set_value( int record_index, SharedDataField field, __int64 value) { ASSERT(this != 0); ASSERT(record_index >= 0); ASSERT(record_index < max_shared_data_records); ASSERT(record_index < local_num_records); ASSERT(field >= 0); ASSERT(field < num_shared_data_fields); local_records[record_index].fields[field] = value; }
void SharedData::increment_value( int record_index, SharedDataField field, __int64 value) { ASSERT(this != 0); ASSERT(record_index >= 0); ASSERT(record_index < max_shared_data_records); ASSERT(record_index < local_num_records); ASSERT(field >= 0); ASSERT(field < num_shared_data_fields); local_records[record_index].fields[field] += value; }
bool SharedData::send_values() { ASSERT(this != 0); if (map_ok) { bool ok = mutex->acquire(mutex_timeout); if (ok) { ASSERT(shared_num_records != 0); *shared_num_records = local_num_records; ASSERT(shared_records != 0); ASSERT(local_records != 0); for (int index = 0; index < local_num_records; index++) { shared_records[index] = local_records[index]; } ok = mutex->release(); if (!ok) { PRINT_DEBUG_MSG((_T("GROVELER: Mutex::release() failed\n"))); } } else { PRINT_DEBUG_MSG((_T("GROVELER: Mutex::acquire() failed\n"))); } return ok; } else { return false; } }
bool SharedData::receive_values() { ASSERT(this != 0); if (map_ok) { bool ok = mutex->acquire(mutex_timeout); if (ok) { ASSERT(shared_num_records != 0); local_num_records = *shared_num_records; ASSERT(shared_records != 0); ASSERT(local_records != 0); for (int index = 0; index < local_num_records; index++) { local_records[index] = shared_records[index]; } ok = mutex->release(); if (!ok) { PRINT_DEBUG_MSG((_T("GROVELER: Mutex::release() failed\n"))); } } else { PRINT_DEBUG_MSG((_T("GROVELER: Mutex::acquire() failed\n"))); } return ok; } else { return false; } }
bool SharedData::extract_values( int *num_records, SharedDataRecord *records) { ASSERT(this != 0); if (map_ok) { bool ok = mutex->acquire(mutex_timeout); if (ok) { ASSERT(shared_num_records != 0); ASSERT(num_records != 0); *num_records = *shared_num_records; ASSERT(shared_records != 0); ASSERT(records != 0); for (int index = 0; index < *num_records; index++) { records[index] = shared_records[index]; } ok = mutex->release(); if (!ok) { PRINT_DEBUG_MSG((_T("GROVELER: Mutex::release() failed\n"))); } } else { PRINT_DEBUG_MSG((_T("GROVELER: Mutex::acquire() failed\n"))); } return ok; } else { return false; } }
|