//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1993. // // File: reserved.cxx // // Contents: Class that implements reserved memory for properties. // This implementation is in the form of two derivations // of the CReservedMemory class. // // Classes: CWin32ReservedMemory // CWin31ReservedMemory // // History: 1-Mar-95 BillMo Created. // 29-Aug-96 MikeHill Split CReservedMemory into CWin31 & CWin32 // // Notes: // // Codework: // //-------------------------------------------------------------------------- #include #include "reserved.hxx" #ifdef _MAC_NODOC ASSERTDATA // File-specific data for FnAssert #endif // Instantiate the appropriate object. #ifdef _MAC CWin31ReservedMemory g_ReservedMemory; #else CWin32ReservedMemory g_ReservedMemory; #endif //+---------------------------------------------------------------------------- // // Method: CWin32ReservedMemory::_Init // // Synopsis: Prepare as much as possible during initialization, in order // to be able to provide memory in LockMemory. // // Inputs: None. // // Returns: None. // //+---------------------------------------------------------------------------- #ifndef _MAC HRESULT CWin32ReservedMemory::_Init(VOID) { HRESULT hr = E_FAIL; SID_IDENTIFIER_AUTHORITY Sa = SECURITY_CREATOR_SID_AUTHORITY; ULONG cInits; // Ensure this method is called once and only once. This // is necessary since this class is implemented as a global // variable. cInits = InterlockedIncrement( &_cInits ); if( 1 < cInits ) { // We've already been initialized (probably simultaneously // in another thread). NOTE: This leaves one small race where // this thread really needs to use the reserved memory before // the other thread has finished initializing it. If that window // is hit, it won't cause a corruption, but will cause an out-of-mem // error to occur. InterlockedDecrement( &_cInits ); hr = S_OK; goto Exit; } // Create a creator/owner SID. We'll give the creator/owner // full access to the temp file. if( !AllocateAndInitializeSid( &Sa, // Top-level authority 1, SECURITY_CREATOR_OWNER_RID, 0, 0, 0, 0, 0, 0, 0, &_pCreatorOwner )) { hr = HRESULT_FROM_WIN32( GetLastError() ); _pCreatorOwner = NULL; goto Exit; } // Create a DACL that just gives the Creator/Owner full access. if (!InitializeAcl( &_DaclBuffer.acl, sizeof(_DaclBuffer), ACL_REVISION)) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto Exit; } if (!AddAccessAllowedAce( &_DaclBuffer.acl, ACL_REVISION, STANDARD_RIGHTS_ALL | GENERIC_ALL, _pCreatorOwner )) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto Exit; } // Set up the security descriptor with that DACL in it. InitializeSecurityDescriptor( &_sd, SECURITY_DESCRIPTOR_REVISION ); if( !SetSecurityDescriptorDacl( &_sd, TRUE, &_DaclBuffer.acl, FALSE )) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto Exit; } // Put the security descriptor into the security attributes. memset( &_secattr, 0, sizeof(_secattr) ); _secattr.nLength = sizeof(SECURITY_ATTRIBUTES); _secattr.lpSecurityDescriptor = &_sd; _secattr.bInheritHandle = FALSE; // Initialize the critical section. __try { InitializeCriticalSection( &_critsec ); _fInitialized = TRUE; } __except( EXCEPTION_EXECUTE_HANDLER ) { hr = HRESULT_FROM_WIN32( GetExceptionCode() ); goto Exit; } hr = S_OK; Exit: return hr; } #endif // #ifndef _MAC //+---------------------------------------------------------------------------- // // Method: CWin32ReservedMemory::~CWin32ReservedMemory // // Inputs: N/A // // Returns: N/A // //+---------------------------------------------------------------------------- #ifndef _MAC CWin32ReservedMemory::~CWin32ReservedMemory() { if( _fInitialized ) DeleteCriticalSection( &_critsec ); if( NULL != _pCreatorOwner ) FreeSid( _pCreatorOwner ); FreeResources(); } //+---------------------------------------------------------------------------- // // Method: CWin32ReservedMemory::FreeResources // // Inputs: N/A // // Returns: Void // // Synopsis: Free the view, the mapping, and the file. // //+---------------------------------------------------------------------------- void CWin32ReservedMemory::FreeResources() { if( NULL != _pb ) { UnmapViewOfFile( _pb ); _pb = NULL; } if( NULL != _hMapping ) { CloseHandle( _hMapping ); _hMapping = NULL; } if( INVALID_HANDLE_VALUE != _hFile ) { CloseHandle( _hFile ); _hFile = INVALID_HANDLE_VALUE; } } #endif // #ifndef _MAC //+---------------------------------------------------------------------------- // // Method: CWin32ReservedMemory::LockMemory // // Synopsis: Use a temporary file to get enough memory to hold the // largest possible property set and return a pointer to // that mapping. // // Inputs: None. // // Returns: Lock() returns a pointer to the locked memory. // //+---------------------------------------------------------------------------- #ifndef _MAC BYTE * CWin32ReservedMemory::LockMemory(VOID) { WCHAR wszTempFileName[ MAX_PATH + 64 ]; ULONG cchPath = 0; // If for some reason initialization failed, there's nothing we can do, // we'll return NULL. if( !_fInitialized ) goto Exit; // Lock down this class until the caller has completed. // This isn't really necessary, since this class could be // a member variable instead of a global, but that is too // much of a change for NT5. EnterCriticalSection( &_critsec ); // Get the temp directory. cchPath = GetTempPath( MAX_PATH + 1, wszTempFileName ); if( 0 == cchPath || cchPath > MAX_PATH + 1 ) goto Exit; // Create a temporary file. We can't use GetTempFileName, because it creates // the file, and consequently the DACL we pass in on CreateFile gets ignored. SYSTEMTIME st; FILETIME ft; GetSystemTime( &st ); SystemTimeToFileTime( &st, &ft ); wsprintf( &wszTempFileName[cchPath], L"OLEPROPSTG_%08x%08x.tmp", ft.dwHighDateTime, ft.dwLowDateTime ); _hFile = CreateFile( wszTempFileName, GENERIC_WRITE|GENERIC_READ|DELETE, 0, &_secattr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, INVALID_HANDLE_VALUE ); if( INVALID_HANDLE_VALUE == _hFile ) goto Exit; // Map the temporary file. _hMapping = CreateFileMappingA(_hFile, // handle of file to map NULL, // optional security attributes PAGE_READWRITE, // protection for mapping object 0, // high-order 32 bits of object size CBMAXPROPSETSTREAM, // low-order 32 bits of object size NULL); // name of file-mapping object if( NULL == _hMapping ) goto Exit; // Map a view. _pb = (BYTE*)MapViewOfFile(_hMapping, // file-mapping object to map into address space FILE_MAP_WRITE, // access mode 0, // high-order 32 bits of file offset 0, // low-order 32 bits of file offset 0); // number of bytes to map if( NULL == _pb ) goto Exit; Exit: // If there was an error, free everything. if( NULL == _pb ) { FreeResources(); LeaveCriticalSection( &_critsec ); } return _pb; } //+---------------------------------------------------------------------------- // // Method: CWin32ReservedMemory // // Synopsis: Free the temp file and its mapping, and leave the critical // section. // //+---------------------------------------------------------------------------- VOID CWin32ReservedMemory::UnlockMemory(VOID) { FreeResources(); LeaveCriticalSection( &_critsec ); } #endif // #ifndef _MAC //+---------------------------------------------------------------------------- // // Method: CWin31ReservedMemory::LockMemory/UnlockMemory // // Synopsis: This derivation of the CReservedMemory does not provide // a locking mechanism, so no locking is performed. The Lock // method simply returns the shared memory buffer. // // Inputs: None. // // Returns: Nothing // //+---------------------------------------------------------------------------- #ifdef _MAC BYTE * CWin31ReservedMemory::LockMemory(VOID) { DfpAssert( !_fLocked ); #if DBG==1 _fLocked = TRUE; #endif return (BYTE*) g_pbPropSetReserved; } VOID CWin31ReservedMemory::UnlockMemory(VOID) { // No locking required on the Mac. DfpAssert( _fLocked ); #if DBG==1 _fLocked = FALSE; #endif } #endif // #ifdef _MAC