/****************************************************************************** Source File: Glue.CPP This file contains the functions needed to make the GPD parser code work on both platforms, as well as stubs to support function I do not need to supply. Copyright (c) 1997 by Microsoft Corporation, All Rights Reserved. A Pretty Penny Enterprises Production Change History: 03/28/1997 Bob_Kjelgaard@Prodigy.Net Created it ******************************************************************************/ #include "StdAfx.H" #include "ProjNode.H" #include "Resource.H" #include "GPDFile.H" // I'll use a class to guarantee memory never leaks from here. class CMaps { CObArray m_coaMaps; public: CMaps() { m_coaMaps.Add(NULL); } ~CMaps() { for (int i = 0; i < m_coaMaps.GetSize(); i++) if (m_coaMaps[i]) delete m_coaMaps[i]; } unsigned Count() { return (unsigned)m_coaMaps.GetSize(); } unsigned HandleFor(CByteArray* cba) { for (unsigned u = 1; u < Count(); u++) { if (!m_coaMaps[u]) { m_coaMaps[u] = cba; return u; } } m_coaMaps.Add(cba); return Count(); } void Free(unsigned u) { if (!u || u >= Count() || !m_coaMaps[u]) return; delete m_coaMaps[u]; m_coaMaps[u] = NULL; } }; static CMaps scmAll; extern "C" unsigned MapFileIntoMemory(LPCWSTR pstrFile, PVOID *ppvData, PDWORD pdwSize) { if (!pstrFile || !ppvData || !pdwSize) return 0; CFile cfMap; CByteArray* pcbaMap = new CByteArray; CString csFile(pstrFile); if (!pcbaMap) return 0; if (!cfMap.Open(csFile, CFile::modeRead | CFile::shareDenyWrite)) return 0; try { pcbaMap -> SetSize(*pdwSize = cfMap.GetLength()); cfMap.Read(pcbaMap -> GetData(), cfMap.GetLength()); *ppvData = pcbaMap -> GetData(); return scmAll.HandleFor(pcbaMap); } catch (CException *pce) { pce -> ReportError(); pce -> Delete(); } return 0; } extern "C" void UnmapFileFromMemory(unsigned uFile) { scmAll.Free(uFile); } // This one is just a stub to make the whole thing work for us- we don't use // the checksum- it's there for the end product to tell if a GPD file has // been altered since it was converted lase. extern "C" DWORD ComputeCrc32Checksum(PBYTE pbuf,DWORD dwCount, DWORD dwChecksum) { return dwCount ^ dwChecksum ^ (PtrToUlong(pbuf)); } // The next two variables are used to control how and when GPD parsing/conversion // log messages are saved. // pcsaLog Ptr to string array to load with messages // bEnableLogging True iff logging is enabled static CStringArray* pcsaLog = NULL ; static bool bEnableLogging = false ; /****************************************************************************** CModelData::SetLog Prepare to log parse/conversion error and warning messages. ******************************************************************************/ void CModelData::SetLog() { m_csaConvertLog.RemoveAll() ; pcsaLog = &m_csaConvertLog ; bEnableLogging = true ; } /****************************************************************************** CModelData::EndLog Turn off parse/conversion error and warning message logging. ******************************************************************************/ void CModelData::EndLog() { pcsaLog = NULL ; bEnableLogging = false ; } /****************************************************************************** DebugPrint This routine is called to log the parsing/conversion error and warning messages. ******************************************************************************/ extern "C" void DebugPrint(LPCTSTR pstrFormat, ...) { CString csOutput; va_list ap; // Don't do anything if logging is not enabled. if (!bEnableLogging) return ; va_start(ap, pstrFormat); vsprintf(csOutput.GetBuffer(1000), pstrFormat, ap); va_end(ap); csOutput.ReleaseBuffer(); csOutput.TrimLeft(); CStringArray& csaError = *pcsaLog; // If this routine is being called when we're NOT recording problems with a // GPD, display the message when debugging. if (pcsaLog == NULL) { CString csmsg ; csmsg.LoadString(IDS_XXXUnexpectedCPError) ; csmsg += csOutput ; AfxMessageBox(csmsg, MB_ICONEXCLAMATION) ; //#ifdef _DEBUG // afxDump << csOutput ; // if (csOutput.Right(1) != _T("\n")) // afxDump << _T("\n") ; //#endif return ; } ; if (!csaError.GetSize()) { csaError.Add(csOutput); return; } if (csaError[-1 + csaError.GetSize()].Find(_T('\n')) >= 0) { csaError[-1 + csaError.GetSize()].TrimRight(); pcsaLog -> Add(csOutput); } else csaError[-1 + csaError.GetSize()] += csOutput; } /****************************************************************************** MDSCreateFileW I implement a version of this API here which calls the ANSI API, so I can compile the parser code with UNICODE on, but still run the resulting binary on Win95. ******************************************************************************/ extern "C" HANDLE MDSCreateFileW(LPCWSTR lpstrFile, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpsa, DWORD dwCreateFlags, DWORD dwfAttributes, HANDLE hTemplateFile) { CString csFile(lpstrFile); // Let CString conversions do the hard work! return CreateFile(csFile, dwDesiredAccess, dwShareMode, lpsa, dwCreateFlags, dwfAttributes, hTemplateFile); }