Leaked source code of windows server 2003
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.

277 lines
7.7 KiB

  1. /*
  2. These strings have no terminal nuls.
  3. To easily form these strings in the VC editor, type the string, then do a regexp search/replace on the
  4. string, replace . with '\0',
  5. */
  6. const CHAR Regedit4SignatureA[] = { 'R','E','G','E','D','I','T','4' };
  7. const NativeUnicodeMarker = 0xFEFF;
  8. const ReversedUnicodeMarker = 0xFFFE;
  9. const WCHAR Regedit5SignatureW[] = { NativeUnicodeMarker,
  10. 'W','i','n','d','o','w','s',' ',
  11. 'R','e','g','i','s','t','r','y',' ',
  12. 'E','d','i','t','o','r',' ',
  13. 'V','e','r','s','i','o','n',' ',
  14. '5','.','0','0'
  15. };
  16. class CFusionStringPoolIndex;
  17. class CFusionStringPool;
  18. class CFusionStringPoolIndex
  19. {
  20. public:
  21. CFusionStringPoolIndex();
  22. BOOL Init(CFusionStringPool * Pool);
  23. int (__cdecl * m_compare)(PCWSTR, PCWSTR); // wcscmp or _wcsicmp
  24. CFusionArray<ULONG> m_Index;
  25. CFusionStringPool * m_Pool;
  26. };
  27. class CFusionStringPool
  28. {
  29. public:
  30. CFusionStringPool();
  31. BOOL Add(PCWSTR String, ULONG Length, ULONG& Index);
  32. CFusionArray<ULONG> m_Index;
  33. CFusionByteBuffer m_Blob;
  34. int (__cdecl * m_compare)(PCWSTR, PCWSTR); // wcscmp or _wcsicmp
  35. };
  36. BOOL CFusionStringPool::Add(PCWSTR String, ULONG Length, ULONG& Index)
  37. {
  38. FN_PROLOG_WIN32
  39. WCHAR UnicodeNull = 0;
  40. SIZE_T OldSize = 0;
  41. ULONG Mono = m_MonotonicIndex.GetSizeAsULONG();
  42. Index = Mono;
  43. IFW32FALSE_EXIT(m_MonotonicIndex.Win32SetSize(Mono + 1));
  44. IFW32FALSE_EXIT(m_Blob.Win32SetSize((OldSize = m_Blob.GetSize()) + Length + sizoef(WCHAR)));
  45. OldSize *= sizeof(WCHAR);
  46. Length *= sizeof(WCHAR);
  47. CopyMemory(&m_Blob[0] + OldSize, String, Length);
  48. CopyMemory(&m_Blob[0] + OldSize + Length, &UnicodeNull, sizeof(WCHAR));
  49. FN_EPILOG;
  50. }
  51. BOOL CFusionStringPool::Optimize()
  52. {
  53. FN_PROLOG_WIN32
  54. if ( m_NumberOfStrings == m_NumberOfCaseSensitiveSortedStrings
  55. && m_NumberOfStrings == m_NumberOfCaseInsensitiveSortedStrings
  56. )
  57. {
  58. FN_SUCCESSFUL_EXIT;
  59. }
  60. FN_EPILOG;
  61. }
  62. void CFusionInMemoryRegValue::TakeValue(CFusionInMemoryRegValue& x)
  63. {
  64. FN_PROLOG_WIN32
  65. this->m_String.TakeValue(x.m_String);
  66. this->m_Binary.TakeValue(x.m_Binary);
  67. this->m_ResourceList.TakeValue(x.m_ResourceList);
  68. this->m_MultiString.TakeValue(x.m_MultiString);
  69. this->m_Dword = x.m_Dword;
  70. this->m_Type = x.m_Type;
  71. FN_EPILOG
  72. }
  73. BOOL CFusionInMemoryRegValue::Win32Assign(const CFusionInMemoryRegValue& x)
  74. {
  75. FN_PROLOG_WIN32
  76. CFusionInMemoryRegValue temp;
  77. IFW32FALSE_EXIT(Temp.m_String.Win32Assign(x.m_String));
  78. IFW32FALSE_EXIT(Temp.m_Binary.Win32Assign(x.m_Binary));
  79. IFW32FALSE_EXIT(Temp.m_ResourceList.Win32Assign(x.m_ResourceList));
  80. IFW32FALSE_EXIT(Temp.m_MultiString.Win32Assign(x.m_MultiString));
  81. Temp.m_Dword = x.m_Dword;
  82. Temp.m_Type = x.m_Type;
  83. this->TakeValue(Temp);
  84. FN_EPILOG
  85. }
  86. BOOL g_fBreakOnUnregonizedRegistryFile;
  87. BOOL CFusionRegistryTextFile::DetermineType(PVOID p, SIZE_T n, PCSTR& a, PCWSTR& w, SIZE_T& cch)
  88. // NOTE that like regedit, we don't allow whitespace
  89. {
  90. FN_PROLOG_WIN32
  91. a = NULL;
  92. w = NULL;
  93. if (n >= sizeof(Regedit5SignatureW)
  94. && memcmp(p, Regedit5SignatureW, sizeof(Regedit5SignatureW)) == 0)
  95. {
  96. *w = p;
  97. *cch = n / sizeof(*w);
  98. *w += NUMBER_OF();
  99. n -= NUMBER_OF(Regedit5SignatureW);
  100. }
  101. else
  102. if (n >= sizeof(Regedit4SignatureA)
  103. && memcmp(p, Regedit4SignatureA, sizeof(Regedit4SignatureA)) == 0)
  104. {
  105. *a = p;
  106. *cch = n / sizeof(*a);
  107. *a += NUMBER_OF(Regedit4SignatureA);
  108. n -= NUMBER_OF();
  109. }
  110. else
  111. {
  112. FusionpDbgPrint("SXS: Unrecognized registry file, ed g_fBreakOnUnregonizedRegistryFile 1 if reproable.\n");
  113. if (g_fBreakOnUnregonizedRegistryTextFile)
  114. FusionpDbgBreak();
  115. ::FusionpSetLastError(ERROR_INVALID_PARAMETER);
  116. goto Exit;
  117. }
  118. FN_EPILOG;
  119. }
  120. template <typename T>
  121. void SkipWhitespace(T*& rpt, SIZE_T& rcch, SIZE_T& rlines)
  122. {
  123. SIZE_T lines = 0;
  124. SIZE_T cch = rcch;
  125. T* pt = rpt;
  126. while (cch != 0)
  127. {
  128. switch (*pt)
  129. {
  130. default:
  131. goto Done;
  132. case ' ':
  133. case '\t':
  134. break;
  135. case '\r':
  136. if (cch != 1 && *(pt + 1) == '\n')
  137. {
  138. --ch;
  139. ++pt;
  140. }
  141. // FALLTHROUGH
  142. case '\n':
  143. lines += 1;
  144. break;
  145. }
  146. --ch;
  147. ++pt;
  148. }
  149. Done:
  150. rpt = pt;
  151. rcch = cch;
  152. rlines += lines;
  153. }
  154. BOOL CFusionRegistryTextFile::ParseError(PCWSTR, ...)
  155. {
  156. }
  157. template <typename T>
  158. BOOL CFusionRegistryTextFile::VerifyFirstKeyPathElement(const F::CBaseStringBuffer& KeyPath)
  159. {
  160. const static UNICODE_STRING hkey_local_machine = RTL_CONSTANT_STRING(L"HKEY_LOCAL_MACHINE");
  161. const static UNICODE_STRING hkey_current_user = RTL_CONSTANT_STRING(L"HKEY_CURRENT_USER");
  162. const static UNICODE_STRING hkey_classes_root = RTL_CONSTANT_STRING(L"HKEY_CLASSES_ROOT");
  163. const static UNICODE_STRING hkey_users = RTL_CONSTANT_STRING(L"HKEY_USERS");
  164. PARAMETER_CHECK(
  165. ::FusionpEqualStrings(KeyPath, hkey_local_machine, TRUE)
  166. || ::FusionpEqualStrings(KeyPath, hkey_current_user, TRUE)
  167. || ::FusionpEqualStrings(KeyPath, hkey_classes_root, TRUE)
  168. || ::FusionpEqualStrings(KeyPath, hkey_users, TRUE));
  169. FN_EPILOG
  170. }
  171. template <typename T>
  172. BOOL CFusionRegistryTextFile::ReadKeyPath(T* s, SIZE_T n, F::CBaseStringBuffer& KeyPath)
  173. {
  174. bool first = true;
  175. while (n != 0 && *s != ']')
  176. {
  177. ReadKeyPathElement();
  178. if (first)
  179. VerifyFirstKeyPathElement();
  180. }
  181. }
  182. template <typename T>
  183. BOOL CFusionRegistryTextFile::ReadMappedGeneric(T* s, SIZE_T n)
  184. {
  185. SIZE_T line = 1;
  186. while (n != 0)
  187. {
  188. SkipWhitespace(s, n, line);
  189. if (n == 0) break;
  190. switch (*s)
  191. {
  192. case '[':
  193. ++s;
  194. --n;
  195. ReadKeyPath(s, n);
  196. break;
  197. default:
  198. ParseError(L"invalid char %c, expected '['", *s);
  199. break;
  200. }
  201. }
  202. }
  203. BOOL CFusionRegistryTextFile::ReadMappedA(PCSTR s, SIZE_T n)
  204. {
  205. }
  206. BOOL CFusionRegistryTextFile::ReadMappedW(PCWSTR s, SIZE_T n)
  207. {
  208. }
  209. BOOL CFusionRegistryTextFile::Read(PCWSTR FileName)
  210. {
  211. FN_PROLOG_WIN32
  212. F::CFile File;
  213. F::CFileMapping FileMapping;
  214. F::CMappedViewOfFile MappedView;
  215. ULONGLONG FileSize = 0;
  216. PCSTR FileA = NULL;
  217. PCWSTR FileW = NULL;
  218. SIZE_T Cch = 0;
  219. PARAMETER_CHECK(FileName != NULL);
  220. PARAMETER_CHECK(FileName[0] != 0);
  221. IFW32FALSE_EXIT(File.Win32CreateFile(FileName, GENERIC_READ | DELETE, FILE_SHARE_READ | FILE_SHARE_DELETE,
  222. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN));
  223. IFW32FALSE_EXIT(File.Win32GetFileSize(FileSize));
  224. PARAMETER_CHECK(FileSize != 0);
  225. IFW32FALSE_EXIT(FileMapping.Win32CreateFileMapping(FileMapping, PAGE_READONLY);
  226. IFW32FALSE_EXIT(MappedView.Win32MapViewOfFile(FileMapping, FILE_MAP_READ);
  227. IFW32FALSE_EXIT(this->DetermineType(MappedView, FileSize, FileSize, FileA, FileW, Cch));
  228. INTERNAL_ERROR_CHECK(FileA != NULL || FileW != NULL);
  229. if (FileA != NULL)
  230. IFW32FALSE_EXIT(this->ReadMappedA(FileA, Cch);
  231. else if (FileW != NULL)
  232. IFW32FALSE_EXIT(this->ReadMappedW(FileW, Cch);
  233. FN_EPILOG;
  234. }