Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
6.7 KiB

  1. //=============================================================================
  2. // File: rsrctmpl.cpp
  3. // Author: a-jammar
  4. // Covers: reading template from resources
  5. //
  6. // Copyright (c) 1998-1999 Microsoft Corporation
  7. //
  8. // This file contains the functions necessary to read the template information
  9. // from the resources of this DLL. The template information is reconstructed
  10. // from the resources so we can use the existing template parsing functions.
  11. //=============================================================================
  12. #include "stdafx.h"
  13. #include "gather.h"
  14. #include "gathint.h"
  15. #include "resrc1.h"
  16. static BOOL fTemplateLoaded = FALSE;
  17. static DWORD dwTemplateInfoLen = 0;
  18. static unsigned char * pTemplateInfo = NULL;
  19. // This table contains the keywords found in the template stream.
  20. #define KEYWORD_COUNT 19
  21. char * KEYWORD_STRING[KEYWORD_COUNT] =
  22. {
  23. "node", "columns", "line", "field", "enumlines", "(", ")", "{", "}",
  24. ",", "\"basic\"", "\"advanced\"", "\"BASIC\"", "\"ADVANCED\"",
  25. "\"static\"", "\"LEXICAL\"", "\"VALUE\"", "\"NONE\"", "\"\""
  26. };
  27. //-----------------------------------------------------------------------------
  28. // To support the way template information is loaded from resources now, we
  29. // need to have an external entry point into this DLL (so we can get the
  30. // default information like we template info from other DLLs).
  31. //
  32. // A pointer to the reconstructed template file is returned to the caller,
  33. // as well as the length of the file. If a NULL pointer is passed as the
  34. // parameter, the buffer containing the template file is deleted (to
  35. // reclaim space).
  36. //-----------------------------------------------------------------------------
  37. void LoadTemplate();
  38. extern "C" __declspec(dllexport)
  39. DWORD __cdecl GetTemplate(void ** ppBuffer)
  40. {
  41. TRY
  42. {
  43. if (!fTemplateLoaded)
  44. {
  45. LoadTemplate();
  46. fTemplateLoaded = TRUE;
  47. }
  48. if (ppBuffer == NULL)
  49. {
  50. if (pTemplateInfo)
  51. delete pTemplateInfo;
  52. fTemplateLoaded = FALSE;
  53. dwTemplateInfoLen = 0;
  54. pTemplateInfo = NULL;
  55. return 0;
  56. }
  57. *ppBuffer = (void *)pTemplateInfo;
  58. return dwTemplateInfoLen;
  59. }
  60. CATCH_ALL(e)
  61. {
  62. #ifdef _DEBUG
  63. e->ReportError();
  64. #endif
  65. }
  66. END_CATCH_ALL
  67. return 0;
  68. }
  69. //-----------------------------------------------------------------------------
  70. // The LoadTemplate function needs to load the template information out of
  71. // our resources, and create a buffer which contains the restored template
  72. // file to return to our caller (through GetTemplate).
  73. //-----------------------------------------------------------------------------
  74. void LoadTemplate()
  75. {
  76. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  77. CMapWordToPtr mapNonLocalized;
  78. HRSRC hrsrcNFN;
  79. HGLOBAL hglbNFN;
  80. unsigned char *pData;
  81. WORD wID;
  82. CString strToken, *pstrToken;
  83. // Load the non-localized strings from the custom resource type and create
  84. // a map of ID to strings. Because these are non-localized strings, they
  85. // will not be stored as UNICODE.
  86. hrsrcNFN = FindResource(AfxGetResourceHandle(), _T("#1"), _T("MSINonLocalizedTokens"));
  87. if(hrsrcNFN)
  88. hglbNFN = LoadResource(AfxGetResourceHandle(), hrsrcNFN);
  89. if(hglbNFN)
  90. pData = (unsigned char *)LockResource(hglbNFN);
  91. while (pData && *((WORD UNALIGNED *)pData))
  92. {
  93. wID = (WORD)(((WORD)*pData++) << 8); // deal with the byte order explicitly to avoid
  94. wID |= (WORD)*pData++; // endian problems.
  95. pstrToken = new CString((char *)pData);
  96. pData += strlen((char *)pData) + 1;
  97. if (pstrToken)
  98. mapNonLocalized.SetAt(wID, (void *)pstrToken);
  99. }
  100. // Load the binary stream of token identifiers into memory.
  101. HRSRC hrsrcNFB = FindResource(AfxGetResourceHandle(), _T("#1"), _T("MSITemplateStream"));
  102. HGLOBAL hglbNFB;
  103. unsigned char *pStream = NULL;
  104. if(hrsrcNFB)
  105. hglbNFB = LoadResource(AfxGetResourceHandle(), hrsrcNFB);
  106. if(hglbNFB)
  107. pStream = (unsigned char *) LockResource(hglbNFB);
  108. if (pStream != NULL)
  109. {
  110. // The first DWORD in the stream is the size of the original text file. We'll
  111. // use this to allocate our buffer to store the reconstituted file.
  112. DWORD dwSize;
  113. dwSize = ((DWORD)*pStream++) << 24;
  114. dwSize |= ((DWORD)*pStream++) << 16;
  115. dwSize |= ((DWORD)*pStream++) << 8;
  116. dwSize |= ((DWORD)*pStream++);
  117. // The size stored with for an Ansi text file. We need to adjust for the
  118. // fact that our reconstituted file will be UNICODE. We also want to add
  119. // a word to the front of the stream to hold the UNICODE file marker (so
  120. // we can use the same functions to read a file or this stream).
  121. dwSize *= sizeof(TCHAR);
  122. dwSize += sizeof(WORD);
  123. pTemplateInfo = new unsigned char[dwSize];
  124. dwTemplateInfoLen = 0;
  125. if (pTemplateInfo == NULL)
  126. return;
  127. // Write the UNICODE file marker.
  128. wID = 0xFEFF;
  129. memcpy(&pTemplateInfo[dwTemplateInfoLen], (void *)&wID, sizeof(WORD));
  130. dwTemplateInfoLen += sizeof(WORD);
  131. // Process the stream a token at a time.
  132. while (pStream && *pStream)
  133. {
  134. if ((*pStream & 0x80) == 0x00)
  135. {
  136. // A byte with the high bit clear refers to a keyword. Look up the keyword
  137. // from the table, and add it to the restored file.
  138. wID = (WORD)(((WORD)*pStream++) - 1); ASSERT(wID <= KEYWORD_COUNT);
  139. if (wID <= KEYWORD_COUNT)
  140. strToken = KEYWORD_STRING[wID];
  141. }
  142. else
  143. {
  144. wID = (WORD)(((WORD)*pStream++) << 8); // deal with the byte order explicitly to avoid
  145. wID |= (WORD)*pStream++; // endian problems.
  146. if ((wID & 0xC000) == 0x8000)
  147. {
  148. // A byte with the high bit set, but the next to high bit clear indicates
  149. // the ID is actually a word, and should be used to get a non-localized
  150. // string. Get the string out of the map we created and add it to the file.
  151. if (mapNonLocalized.Lookup((WORD)(wID & 0x7FFF), (void *&)pstrToken))
  152. strToken = *pstrToken;
  153. else
  154. ASSERT(FALSE);
  155. }
  156. else
  157. {
  158. // A byte with the two MSB set indicates that the ID is a word, and should
  159. // be used to reference a localized string out of the string table in this
  160. // module's resources. This string will be UNICODE.
  161. VERIFY(strToken.LoadString((wID & 0x3FFF) + IDS_MSITEMPLATEBASE));
  162. strToken = _T("\"") + strToken + _T("\"");
  163. }
  164. }
  165. // Store the token on the end of our buffer. The data in this buffer must
  166. // be UNICODE, so we'll need to convert the string if necessary.
  167. if (dwTemplateInfoLen + strToken.GetLength() * sizeof(TCHAR) < dwSize)
  168. {
  169. memcpy(&pTemplateInfo[dwTemplateInfoLen], (void *)(LPCTSTR)strToken, strToken.GetLength() * sizeof(TCHAR));
  170. dwTemplateInfoLen += strToken.GetLength() * sizeof(TCHAR);
  171. }
  172. else
  173. ASSERT(FALSE);
  174. }
  175. }
  176. // Delete the contents of the lookup table.
  177. for (POSITION pos = mapNonLocalized.GetStartPosition(); pos != NULL;)
  178. {
  179. mapNonLocalized.GetNextAssoc(pos, wID, (void *&)pstrToken);
  180. if (pstrToken)
  181. delete pstrToken;
  182. }
  183. }