/* Copyright (c) 2000 Microsoft Corporation Module Name: setting.cpp Abstract: CSetting object. Used to support Remote Assistance Channel settings. Revision History: created steveshi 08/23/00 */ #include "stdafx.h" #include "SAFRCFileDlg.h" #include "setting.h" #include "userenv.h" #include "stdio.h" const TCHAR cstrRCBDYINI[] = _T("RcBuddy.ini"); const TCHAR cstrRCBDYAPP[] = _T("RcBuddyChannel"); const TCHAR cstrSubDir[] = _T("\\Local Settings\\Application Data\\RcIncidents"); extern HINSTANCE g_hInstance; BOOL CreateRAIncidentDirectory(LPTSTR path, LPCTSTR subPath); /********************************************************* Func: GetProfileString Abstract: Get profile string inside the channel's setting file. Params: bstrSec: Section key. pVal: Output string (default is "0", if not found.) *********************************************************/ HRESULT CSetting::GetProfileString(BSTR bstrSec, BSTR* pVal) { HRESULT hr = S_FALSE; TCHAR sBuf[512]; DWORD dwSize; USES_CONVERSION; if (FAILED(InitProfile())) goto done; dwSize = GetPrivateProfileString(cstrRCBDYAPP, W2T(bstrSec), TEXT("0"), &sBuf[0], 512, m_pIniFile); *pVal = CComBSTR(sBuf).Copy(); hr = S_OK; done: return hr; } /********************************************************* Func: SetProfileString Abstract: Set profile string inside the channel's setting file. Params: bstrSec: Section key. bstrVal: New value *********************************************************/ HRESULT CSetting::SetProfileString(BSTR bstrSec, BSTR bstrVal) { HRESULT hr = S_FALSE; USES_CONVERSION; if (FAILED(InitProfile())) goto done; //MessageBox(NULL,m_pIniFile,OLE2T(bstrSec),MB_OK); if (!WritePrivateProfileString(cstrRCBDYAPP, W2T(bstrSec), W2T(bstrVal), m_pIniFile)) goto done; hr = S_OK; done: return hr; } /********************************************************* Func: get_GetUserProfileDirectory Abstract: Return user's profile directory *********************************************************/ HRESULT CSetting::get_GetUserProfileDirectory(/*[out, retval]*/ BSTR *pVal) { HRESULT hr = S_FALSE; if (FAILED(hr = InitProfile())) goto done; *pVal = CComBSTR(m_pProfileDir).Detach(); done: return hr; } /********************************************************* Func: get_GetUserTempFileName Abstract: Return a temp file name under user's profile directory *********************************************************/ HRESULT CSetting::get_GetUserTempFileName(/*[out, retval]*/ BSTR *pVal) { HRESULT hr = S_FALSE; TCHAR sFile[MAX_PATH + 256]; if(FAILED(InitProfile())) goto done; // Get Temp file name if (!GetTempFileName(m_pProfileDir, _T("RC"), 0, &sFile[0])) goto done; *pVal = CComBSTR(sFile).Copy(); hr = S_OK; done: return hr; } ////////////////////////////////////////////////////////////////////////////////////// // Helper functions used to support the above methods or properties ///////////////////////////// /********************************************************* Func: InitProfile Abstract: Create the setting file. A RCIncidents subdir will be created under user's profile dir. A RcBuddy.ini file be created as the user's RA channel setting file. *********************************************************/ HRESULT CSetting::InitProfile() { HRESULT hr = E_FAIL; if (m_pProfileDir && m_pIniFile) // No need to process return S_OK; if (m_pProfileDir || m_pIniFile) // Only one has value: Error. No need to process either. return E_FAIL; // Get User profile directory HANDLE hProcess = GetCurrentProcess(); TCHAR* pPath = NULL; TCHAR sPath[MAX_PATH]; ULONG ulSize = sizeof(sPath) - sizeof(cstrSubDir) -1; // preserve space for subdir. TCHAR sFile[MAX_PATH + 256]; HANDLE hToken = NULL; int iRet = 0; BOOL bNeedFree = FALSE; DWORD dwSizePtr=0; if (!OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_WRITE, &hToken)) goto done; if (!GetUserProfileDirectory(hToken, &sPath[0], &ulSize)) // Buffer not big enough { if (ulSize == sizeof(sPath)-1) // Not because of insufficent space. goto done; //SWI dwSizePtr=ulSize+1+sizeof(cstrSubDir); pPath = (TCHAR*)malloc((dwSizePtr)*sizeof(TCHAR)); if (!pPath) { hr = E_OUTOFMEMORY; goto done; } bNeedFree = TRUE; if (!GetUserProfileDirectory(hToken, pPath, &ulSize)) { hr = HRESULT_FROM_WIN32(GetLastError()); goto done; } } if (!pPath) { dwSizePtr=MAX_PATH; pPath = sPath; } // Create RCIncidents sub dir // _tcscat(pPath, sSubDir); // iRet = SHCreateDirectoryEx(NULL, pPath, NULL); BOOL retVal= CreateRAIncidentDirectory(pPath, cstrSubDir); if (retVal == FALSE) goto done; //SWI //_tcscat(pPath, cstrSubDir); hr=StringCchCat(pPath,dwSizePtr,cstrSubDir); if(FAILED(hr)) { goto done; } // if (iRet != ERROR_SUCCESS && iRet != ERROR_ALREADY_EXISTS) // goto done; // Set variables iRet = (_tcslen(pPath) + 1) * sizeof(TCHAR); m_pProfileDir = (TCHAR*)malloc(iRet); if (!m_pProfileDir) { hr = E_OUTOFMEMORY; goto done; } memcpy(m_pProfileDir, pPath, iRet); dwSizePtr= iRet + (1+sizeof(cstrRCBDYINI))*sizeof(TCHAR); m_pIniFile = (TCHAR*)malloc(dwSizePtr); if (!m_pIniFile) { hr = E_OUTOFMEMORY; goto done; } //SWI //_stprintf(m_pIniFile, _T("%s\\%s"), m_pProfileDir, cstrRCBDYINI); hr=StringCbPrintf(m_pIniFile,dwSizePtr,_T("%s\\%s"), m_pProfileDir, cstrRCBDYINI); done: if (hToken) CloseHandle(hToken); if (bNeedFree) free(pPath); return hr; } /********************************************************* Func: get_GetPropertyInBlob Abstract: Get the specified property value in Blob Params: bstrBlob: Blob for searching. (ex: 8;PASS=ABC ) bstrName: property name. (ex: "PASS", without '=' char) *********************************************************/ HRESULT CSetting::get_GetPropertyInBlob(/*[in]*/ BSTR bstrBlob, /*[in]*/ BSTR bstrName, /*[out, retval]*/ BSTR *pVal) { HRESULT hRet = S_FALSE; WCHAR *p1, *p2, *pEnd; LONG lTotal =0; size_t lProp = 0; size_t iNameLen; if (!bstrBlob || *bstrBlob==L'\0' || !bstrName || *bstrName ==L'\0'|| !pVal) return FALSE; iNameLen = wcslen(bstrName); pEnd = bstrBlob + wcslen(bstrBlob); p1 = p2 = bstrBlob; while (1) { // get porperty length while (*p2 != L';' && *p2 != L'\0' && iswdigit(*p2) ) p2++; if (*p2 != L';') goto done; *p2 = L'\0'; // set it to get length lProp = _wtol(p1); *p2 = L';'; // revert it back. // get property string p1 = ++p2; while (*p2 != L'=' && *p2 != L'\0' && p2 < p1+lProp) p2++; if (*p2 != L'=') goto done; if ((p2-p1==iNameLen) && (wcsncmp(p1, bstrName, iNameLen)==0) ) { if (lProp == iNameLen+1) // A=B= case (no value) goto done; WCHAR C = *(p2 + lProp-iNameLen); *(p2 + lProp-iNameLen) = L'\0'; *pVal = SysAllocString(p2+1); *(p2 + lProp-iNameLen) = C; hRet = S_OK; break; } // check next property p2 = p1 = p1 + lProp; if (p2 > pEnd) break; } done: return hRet; } STDMETHODIMP CSetting::AddPropertyToBlob(BSTR pName, BSTR pValue, BSTR poldBlob, BSTR *pnewBlob) { WCHAR *pszBuf = NULL; LONG len, lOldBlob = 0; BOOL bHasValue = FALSE; DWORD dwSizePtr=0; if(!pName || *pName==L'\0' || !pnewBlob) { goto done; } if(poldBlob && *poldBlob != L'\0') lOldBlob = wcslen(poldBlob); len = wcslen(pName) + 1; // ;pName=pValue 1 is for the '=' if (pValue && *pValue != L'\0') { len += wcslen(pValue); bHasValue = TRUE; } //SWI dwSizePtr=len + lOldBlob + 1; pszBuf = new WCHAR[dwSizePtr]; if (lOldBlob > 0) { if (bHasValue) { //SWI //swprintf(pszBuf, L"%s%d;%s=%s", poldBlob, len, pName, pValue); StringCchPrintfW(pszBuf,dwSizePtr,L"%s%d;%s=%s", poldBlob, len, pName, pValue); } else { //SWI //swprintf(pszBuf, L"%s%d;%s=", poldBlob, len, pName); StringCchPrintfW(pszBuf,dwSizePtr,L"%s%d;%s=", poldBlob, len, pName); } } else { if (bHasValue) //SWI //swprintf(pszBuf, L"%d;%s=%s", len, pName, pValue); StringCchPrintfW(pszBuf,dwSizePtr, L"%d;%s=%s", len, pName, pValue); else //SWI //swprintf(pszBuf, L"%d;%s=", len, pName); StringCchPrintfW(pszBuf,dwSizePtr, L"%d;%s=", len, pName); } done: *pnewBlob = ::SysAllocString(pszBuf); if (pszBuf) delete pszBuf; return S_OK; } BOOL CreateRAIncidentDirectory(LPTSTR path, LPCTSTR subPath) { BOOL bRetVal = FALSE; TCHAR seps[] = _T("\\"); LPTSTR ptrDirPath = NULL; LPTSTR ptrSubDirPath = NULL; DWORD dwSizePtrDir=0,dwSizePtrSubDir=0; HRESULT hr=S_OK; //SWI dwSizePtrDir=strlen(path) + strlen(subPath) + 1; ptrDirPath = new TCHAR[dwSizePtrDir]; if (ptrDirPath == NULL) { bRetVal = FALSE; goto done; } //SWI //lstrcpy(ptrDirPath,path); hr=StringCchCopy(ptrDirPath,dwSizePtrDir,path); if(FAILED(hr)) { bRetVal = FALSE; goto done; } dwSizePtrSubDir=strlen(subPath) + 1; ptrSubDirPath = new TCHAR[dwSizePtrSubDir]; if (ptrSubDirPath == NULL) { bRetVal = FALSE; goto done; } //SWI //lstrcpy(ptrSubDirPath,subPath); hr=StringCchCopy(ptrSubDirPath,dwSizePtrSubDir,subPath); if(FAILED(hr)) { bRetVal = FALSE; goto done; } LPTSTR token; token= _tcstok(ptrSubDirPath, seps); while( token != NULL ) { //lstrcat(ptrDirPath,_T("\\")); //lstrcat(ptrDirPath,token); hr=StringCchCat(ptrDirPath,dwSizePtrDir,_T("\\")); if(FAILED(hr)) { bRetVal = FALSE; goto done; } hr=StringCchCat(ptrDirPath,dwSizePtrDir,token); if(FAILED(hr)) { bRetVal = FALSE; goto done; } //MessageBox(NULL,ptrDirPath,token,MB_OK); if (CreateDirectory(ptrDirPath,NULL) == 0) { DWORD err = GetLastError(); if ((err != ERROR_ALREADY_EXISTS) && (err != ERROR_SUCCESS)) { bRetVal = FALSE; goto done; } } /* Get next token: */ token = _tcstok(NULL, seps); } bRetVal = TRUE; done: if (ptrDirPath) delete ptrDirPath; if (ptrSubDirPath) delete ptrSubDirPath; return bRetVal; }