//************************************************************* // // Copyright (c) Microsoft Corporation 1998 // All rights reserved // // cspath.cxx // // Class for building and setting the ClassStore path in the // registry. // //************************************************************* #include "appmgext.hxx" CSPath::CSPath() { _pwszPath = 0; } CSPath::~CSPath() { if ( _pwszPath ) LocalFree( _pwszPath ); } DWORD CSPath::AddComponent( WCHAR * pwszDSPath, WCHAR * pwszDisplayName ) { WCHAR * pwszCSPath; WCHAR * pwszNewPath; DWORD Size; HRESULT hr; DWORD Status; if ( ! pwszDSPath ) return ERROR_SUCCESS; hr = CsGetClassStorePath( pwszDSPath, &pwszCSPath ); if ( hr != S_OK ) { // // This call was simply a string manipulation, it should // only fail due to out of memory // DebugMsg((DM_VERBOSE, IDS_NO_CLASSSTORE, pwszDisplayName, hr)); return (DWORD) hr; } Size = 0; if ( _pwszPath ) Size += lstrlen(_pwszPath) * sizeof(WCHAR); Size += (lstrlen(pwszCSPath) + 2) * sizeof(WCHAR); pwszNewPath = (WCHAR *) LocalAlloc( 0, Size ); if ( ! pwszNewPath ) { Status = ERROR_NOT_ENOUGH_MEMORY; } else { hr = StringCchCopy( pwszNewPath, Size, pwszCSPath ); if (FAILED(hr)) { LocalFree(pwszNewPath); Status = HRESULT_CODE(hr); } else { hr = StringCchCat( pwszNewPath, Size, L";" ); if (SUCCEEDED(hr)) { if ( _pwszPath ) { hr = StringCchCat( pwszNewPath, Size, _pwszPath ); } } if (FAILED(hr)) { LocalFree(pwszNewPath); Status = HRESULT_CODE(hr); } else { LocalFree( _pwszPath ); _pwszPath = pwszNewPath; Status = ERROR_SUCCESS; } } } LocalFree( pwszCSPath ); return Status; } DWORD CSPath::Commit( HANDLE hToken ) { DWORD Status; if ( _pwszPath ) { Status = WriteClassStorePath(hToken, _pwszPath); DebugMsg((DM_VERBOSE, IDS_CSPATH, _pwszPath)); } else { (void) WriteClassStorePath(hToken, L""); Status = CS_E_NO_CLASSSTORE; DebugMsg((DM_VERBOSE, IDS_NOCSPATH)); } return Status; } DWORD CSPath::WriteClassStorePath( HANDLE hToken, LPWSTR pwszClassStorePath ) { DWORD err; LPWSTR wszIniFilePath; HRESULT hr; DWORD dwSize; err = GetScriptDirPath( hToken, sizeof(APPMGMT_INI_FILENAME) / sizeof(WCHAR), &wszIniFilePath, &dwSize); if (ERROR_SUCCESS != err) { return err; } hr = StringCchCat(wszIniFilePath, dwSize, APPMGMT_INI_FILENAME); if (FAILED(hr)) { err = HRESULT_CODE(hr); } if (ERROR_SUCCESS == err) { err = WriteClassStorePathToFile( wszIniFilePath, pwszClassStorePath); } delete [] wszIniFilePath; return err; } LONG CSPath::WriteClassStorePathToFile( WCHAR* wszIniFilePath, WCHAR* wszClassStorePath ) { HANDLE hFile; BOOL bStatus; DWORD dwWritten; // // This method attempts to write the class store path // into a file in a non-roaming portion of the user's profile. // // The format of the file is simple: it is a sequence of unicode // characters terminated by a null unicode character -- i.e., // its contents are simply the exact bytes of the wszClassStorePath // parameter, including the terminating character. // // Clients reading the file should verify that the very last character // of the file is a null terminator in order to detect corrupt files. // // // First, attempt to open the file, creating it if it does not exist // hFile = CreateFile( wszIniFilePath, GENERIC_WRITE, 0, // do not allow anyone else access while we are modifying the file NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_SYSTEM, NULL); // // If we can't create the file, we have failed // if ( INVALID_HANDLE_VALUE == hFile ) { return GetLastError(); } LONG Status; Status = ERROR_SUCCESS; // // Now erease the data in it -- truncate the file to the current file pointer, // which is at the beginning of the file // bStatus = SetEndOfFile( hFile ); // // If we cannot erase the current contents, this is a failure // if ( ! bStatus ) { Status = GetLastError(); goto cleanup_and_exit; } // // Now write the class store path into the file -- we simply do a memory copy // of the string into the file // bStatus = WriteFile( hFile, wszClassStorePath, ( lstrlen(wszClassStorePath) + 1 ) * sizeof(*wszClassStorePath), &dwWritten, NULL); // // If the write failed, find out why and return that status // if ( ! bStatus ) { Status = GetLastError(); } cleanup_and_exit: // // Free our file resource since its no longer needed // CloseHandle( hFile ); // // Everything worked, we return a success code // return Status; }