#include "stdafx.hxx" #include "vs_idl.hxx" #include "vswriter.h" #include "vsbackup.h" #include "compont.h" #include #include #include #include #include // // CWriterComponentsSelection class // CWriterComponentsSelection::CWriterComponentsSelection() { m_WriterId = GUID_NULL; m_uNumComponents = 0; m_uNumSubcomponents = 0; m_ppwszComponentLogicalPaths = NULL; m_ppwszSubcomponentLogicalPaths = NULL; } CWriterComponentsSelection::~CWriterComponentsSelection() { if ((m_uNumComponents > 0) && (m_ppwszComponentLogicalPaths != NULL)) { for (UINT i=0; i 0) && (m_ppwszSubcomponentLogicalPaths != NULL)) { for (UINT i=0; i\ // 3. The selction criteria is component-name (only if logical-path is NULL) for (UINT i=0; i(pp); (*pUnk) = static_cast(this); return S_OK; } ULONG CWritersSelection::AddRef() { return ::InterlockedIncrement(&m_lRef); } ULONG CWritersSelection::Release() { LONG l = ::InterlockedDecrement(&m_lRef); if (l == 0) delete this; // We assume that we always allocate this object on the heap! return l; } STDMETHODIMP CWritersSelection::BuildChosenComponents ( WCHAR *pwszComponentsFileName ) { HRESULT hr = S_OK; HANDLE hFile = INVALID_HANDLE_VALUE; DWORD dwBytesToRead = 0; DWORD dwBytesRead; // Create the file hFile = CreateFile(pwszComponentsFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { DWORD dwLastError = GetLastError(); wprintf(L"Invalid components file, CreateFile returned = %lu\n", dwLastError); return HRESULT_FROM_WIN32(dwLastError); } if ((dwBytesToRead = GetFileSize(hFile, NULL)) <= 0) { CloseHandle(hFile); DWORD dwLastError = GetLastError(); wprintf(L"Invalid components file, GetFileSize returned = %lu\n", dwLastError); return HRESULT_FROM_WIN32(dwLastError); } if (dwBytesToRead > 0x100000) { CloseHandle(hFile); wprintf(L"Invalid components file, Provide a file with a size of less than 1 MB\n"); return E_FAIL; } char * pcBuffer = (PCHAR) malloc (dwBytesToRead); if (! pcBuffer) { CloseHandle(hFile); return E_OUTOFMEMORY; } // Read the components info if (! ReadFile(hFile, (LPVOID)pcBuffer, dwBytesToRead, &dwBytesRead, NULL)) { DWORD dwLastError = GetLastError(); CloseHandle(hFile); free (pcBuffer); wprintf(L"Invalid components file, ReadFile returned = %lu\n", dwLastError); return HRESULT_FROM_WIN32(dwLastError); } CloseHandle(hFile); if (dwBytesToRead != dwBytesRead) { free (pcBuffer); wprintf(L"Components selection file is supposed to have %lu bytes but only %lu bytes are read\n", dwBytesToRead, dwBytesRead); return E_FAIL; } // Allocate a buffer to work with WCHAR * pwcBuffer = (PWCHAR) malloc ((dwBytesToRead+1) * sizeof(WCHAR)); if (! pwcBuffer) { free (pcBuffer); return E_OUTOFMEMORY; } // Simple pasring, assume ANSI, Format: // "writer1-id": "component1.1-name", "component1.2-name",... ; "writer2-id": "component2.1-name", ... CWriterComponentsSelection* pWriterComponents = NULL; try { VSS_ID WriterId = GUID_NULL; BOOL bBeforeWriter = TRUE; BOOL bBeforeComponents = TRUE; BOOL bInString = FALSE; char* pcStart = NULL; for (char* pcCurrent = pcBuffer; pcCurrent < (pcBuffer+dwBytesToRead); pcCurrent++) { switch (*pcCurrent) { case ':': if (bBeforeWriter && !bInString) { bBeforeWriter = FALSE; } else if (bBeforeComponents && !bInString) { bBeforeComponents = FALSE; } else if (!bInString) { throw(E_FAIL); } break; case ';': if (bBeforeWriter || bInString) { throw(E_FAIL); } else { // If we have a valid writer - add it to the map if ((pWriterComponents != NULL) && (WriterId != GUID_NULL)) { if (!m_WritersMap.Add(WriterId, pWriterComponents)) { delete pWriterComponents; throw E_OUTOFMEMORY; } pWriterComponents = NULL; WriterId = GUID_NULL; } bBeforeWriter = TRUE; } break; case ',': if (bBeforeWriter || bInString) { throw(E_FAIL); } break; case '"': if (! bInString) { // Mark string-start for later pcStart = pcCurrent + 1; } else if (pcStart == pcCurrent) { // empty string - skip it } else { // String ends - convert to WCHAR and process DWORD dwSize = (DWORD)mbstowcs(pwcBuffer, pcStart, pcCurrent - pcStart); pwcBuffer[dwSize] = NULL; if (dwSize <= 0) { throw(E_FAIL); } if (bBeforeWriter) { // If before-writer - must be a writer GUID HRESULT hrConvert = CLSIDFromString(pwcBuffer, &WriterId); if ((! SUCCEEDED(hrConvert)) && (hrConvert != REGDB_E_WRITEREGDB)) { wprintf(L"A writer id in the components selection file is in invalid GUID format\n"); throw(E_FAIL); } if (pWriterComponents != NULL) { // Previous writer info was not ended correctly throw(E_FAIL); } pWriterComponents = new CWriterComponentsSelection; if (pWriterComponents == NULL) { throw(E_OUTOFMEMORY); } pWriterComponents->SetWriter(WriterId); } else if (bBeforeComponents) { // Must be a component logical-path , name or logical-path\name if (pWriterComponents != NULL) { pWriterComponents->AddSelectedComponent(pwcBuffer); } } else { // Must be a component logical-path , name or logical-path\name if (pWriterComponents != NULL) { pWriterComponents->AddSelectedSubcomponent(pwcBuffer); } } } // Flip in-string flag bInString = (! bInString); break; case ' ': break; case '\n': case '\t': case '\r': if (bInString) { throw(E_FAIL); } break; default: if (! bInString) { throw(E_FAIL); } break; } } } catch (HRESULT hrParse) { hr = hrParse; if (hr == E_FAIL) { wprintf(L"Invalid format of components selection file\n"); } if (pWriterComponents != NULL) { // Error int he middle of writer-components creation (not added to the map yet...) delete pWriterComponents; } } free (pcBuffer); free (pwcBuffer); return hr; } BOOL CWritersSelection::IsComponentSelected ( IN VSS_ID WriterId, IN WCHAR* pwszComponentLogicalPath, IN WCHAR* pwszComponentName ) { CWriterComponentsSelection* pWriterComponents = m_WritersMap.Lookup(WriterId); if (pWriterComponents == NULL) { // No component is selected for this writer return FALSE; } // There are components selected for this writer, check if this specific one is selected return pWriterComponents->IsComponentSelected(pwszComponentLogicalPath, pwszComponentName); } BOOL CWritersSelection::IsSubcomponentSelected ( IN VSS_ID WriterId, IN WCHAR* pwszComponentLogicalPath, IN WCHAR* pwszComponentName ) { CWriterComponentsSelection* pWriterComponents = m_WritersMap.Lookup(WriterId); if (pWriterComponents == NULL) { // No component is selected for this writer return FALSE; } // There are subccomponents selected for this writer, check if this specific one is selected return pWriterComponents->IsSubcomponentSelected(pwszComponentLogicalPath, pwszComponentName); } const WCHAR* const * CWritersSelection::GetComponents ( IN VSS_ID WriterId ) { CWriterComponentsSelection* pWriterComponents = m_WritersMap.Lookup(WriterId); if (pWriterComponents == NULL) { return NULL; } return pWriterComponents->GetComponents(); } const WCHAR* const * CWritersSelection::GetSubcomponents ( IN VSS_ID WriterId ) { CWriterComponentsSelection* pWriterComponents = m_WritersMap.Lookup(WriterId); if (pWriterComponents == NULL) { return NULL; } return pWriterComponents->GetSubcomponents(); } const UINT CWritersSelection::GetComponentsCount ( IN VSS_ID WriterId ) { CWriterComponentsSelection* pWriterComponents = m_WritersMap.Lookup(WriterId); if (pWriterComponents == NULL) { return NULL; } return pWriterComponents->GetComponentsCount(); } const UINT CWritersSelection::GetSubcomponentsCount ( IN VSS_ID WriterId ) { CWriterComponentsSelection* pWriterComponents = m_WritersMap.Lookup(WriterId); if (pWriterComponents == NULL) { return NULL; } return pWriterComponents->GetSubcomponentsCount(); }