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.

344 lines
12 KiB

  1. #ifndef __MRU_H_INCLUDED
  2. #define __MRU_H_INCLUDED
  3. #include <windows.h>
  4. #include <shlobj.h>
  5. #include <wiacrc32.h>
  6. #include "simstr.h"
  7. #include "simidlst.h"
  8. #include "destdata.h"
  9. #define CURRENT_REGISTRY_DATA_FORMAT_VERSION 3
  10. class CMruStringList : public CSimpleLinkedList<CSimpleString>
  11. {
  12. private:
  13. int m_nNumToWrite;
  14. enum
  15. {
  16. DefaultNumToWrite=20
  17. };
  18. private:
  19. CMruStringList( const CMruStringList & );
  20. CMruStringList &operator=( const CMruStringList & );
  21. public:
  22. CMruStringList( int nNumToWrite=DefaultNumToWrite )
  23. : m_nNumToWrite(nNumToWrite)
  24. {
  25. }
  26. bool Read( HKEY hRoot, LPCTSTR pszKey, LPCTSTR pszValueName )
  27. {
  28. CSimpleReg reg( hRoot, pszKey, false, KEY_READ );
  29. if (reg.OK())
  30. {
  31. if (REG_MULTI_SZ==reg.Type(pszValueName))
  32. {
  33. int nSize = reg.Size(pszValueName);
  34. if (nSize)
  35. {
  36. PBYTE pData = new BYTE[nSize];
  37. if (pData)
  38. {
  39. if (reg.QueryBin( pszValueName, pData, nSize ))
  40. {
  41. for (LPTSTR pszCurr=reinterpret_cast<LPTSTR>(pData);*pszCurr;pszCurr+=lstrlen(pszCurr)+1)
  42. {
  43. Append( pszCurr );
  44. }
  45. }
  46. delete[] pData;
  47. }
  48. }
  49. }
  50. }
  51. return(true);
  52. }
  53. bool Write( HKEY hRoot, LPCTSTR pszKey, LPCTSTR pszValueName )
  54. {
  55. CSimpleReg reg( hRoot, pszKey, true, KEY_WRITE );
  56. if (reg.OK())
  57. {
  58. int nLengthInChars = 0, nCount;
  59. Iterator i;
  60. for (i=Begin(),nCount=0;i != End() && nCount < m_nNumToWrite;++i,++nCount)
  61. nLengthInChars += (*i).Length() + 1;
  62. if (nLengthInChars)
  63. {
  64. ++nLengthInChars;
  65. LPTSTR pszMultiStr = new TCHAR[nLengthInChars];
  66. if (pszMultiStr)
  67. {
  68. LPTSTR pszCurr = pszMultiStr;
  69. for (i = Begin(), nCount=0;i != End() && nCount < m_nNumToWrite;++i,++nCount)
  70. {
  71. lstrcpy(pszCurr,(*i).String());
  72. pszCurr += (*i).Length() + 1;
  73. }
  74. *pszCurr = TEXT('\0');
  75. reg.SetBin( pszValueName, reinterpret_cast<PBYTE>(pszMultiStr), nLengthInChars*sizeof(TCHAR), REG_MULTI_SZ );
  76. delete[] pszMultiStr;
  77. }
  78. }
  79. }
  80. return(true);
  81. }
  82. void Add( CSimpleString str )
  83. {
  84. if (str.Length())
  85. {
  86. Remove(str);
  87. Prepend(str);
  88. }
  89. }
  90. void PopulateComboBox( HWND hWnd )
  91. {
  92. SendMessage( hWnd, CB_RESETCONTENT, 0, 0 );
  93. for (Iterator i = Begin();i != End();++i)
  94. {
  95. SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM)((*i).String()));
  96. }
  97. }
  98. };
  99. class CMruDestinationData : public CSimpleLinkedList<CDestinationData>
  100. {
  101. private:
  102. int m_nNumToWrite;
  103. enum
  104. {
  105. DefaultNumToWrite=20
  106. };
  107. struct REGISTRY_SIGNATURE
  108. {
  109. DWORD dwSize;
  110. DWORD dwVersion;
  111. DWORD dwCount;
  112. DWORD dwCrc;
  113. };
  114. private:
  115. CMruDestinationData( const CMruDestinationData & );
  116. CMruDestinationData &operator=( const CMruDestinationData & );
  117. public:
  118. CMruDestinationData( int nNumToWrite=DefaultNumToWrite )
  119. : m_nNumToWrite(nNumToWrite)
  120. {
  121. }
  122. bool Read( HKEY hRoot, LPCTSTR pszKey, LPCTSTR pszValueName )
  123. {
  124. //
  125. // Open the registry
  126. //
  127. CSimpleReg reg( hRoot, pszKey, false, KEY_READ );
  128. if (reg.OK())
  129. {
  130. //
  131. // Make sure the type is correct
  132. //
  133. if (REG_BINARY==reg.Type(pszValueName))
  134. {
  135. //
  136. // Get the size and make sure it is at least as large as the signature structure
  137. //
  138. DWORD nSize = reg.Size(pszValueName);
  139. if (nSize >= sizeof(REGISTRY_SIGNATURE))
  140. {
  141. //
  142. // Allocate a block to hold the data
  143. //
  144. PBYTE pData = new BYTE[nSize];
  145. if (pData)
  146. {
  147. //
  148. // Get the data
  149. //
  150. if (reg.QueryBin( pszValueName, pData, nSize ))
  151. {
  152. //
  153. // Copy the blob to a registry signature structure
  154. //
  155. REGISTRY_SIGNATURE RegistrySignature = {0};
  156. CopyMemory( &RegistrySignature, pData, sizeof(REGISTRY_SIGNATURE) );
  157. //
  158. // Make sure the version and struct size are correct, and the count is non-zero. Just ignore it if it isn't.
  159. //
  160. if (RegistrySignature.dwSize == sizeof(REGISTRY_SIGNATURE) && RegistrySignature.dwVersion == CURRENT_REGISTRY_DATA_FORMAT_VERSION && RegistrySignature.dwCount)
  161. {
  162. //
  163. // Raw data starts at the end of the structure
  164. //
  165. PBYTE pCurr = pData + sizeof(REGISTRY_SIGNATURE);
  166. //
  167. // Get the CRC for this blob and make sure it matches
  168. //
  169. DWORD dwCrc = WiaCrc32::GenerateCrc32( nSize - sizeof(REGISTRY_SIGNATURE), pCurr );
  170. if (dwCrc == RegistrySignature.dwCrc)
  171. {
  172. //
  173. // Loop through all of the entries
  174. //
  175. for (int i=0;i<static_cast<int>(RegistrySignature.dwCount);i++)
  176. {
  177. //
  178. // Copy the item size
  179. //
  180. DWORD dwItemSize = 0;
  181. CopyMemory( &dwItemSize, pCurr, sizeof(DWORD) );
  182. //
  183. // Increment the current pointer beyond the size
  184. //
  185. pCurr += sizeof(DWORD);
  186. //
  187. // Make sure the item size is non-zero
  188. //
  189. if (dwItemSize)
  190. {
  191. //
  192. // Create a CDestinationData with this blob
  193. //
  194. CDestinationData DestinationData;
  195. DestinationData.SetRegistryData(pCurr,dwItemSize);
  196. //
  197. // Add it to the list
  198. //
  199. Append( DestinationData );
  200. }
  201. //
  202. // Increment the current pointer to the end of the blob
  203. //
  204. pCurr += dwItemSize;
  205. }
  206. }
  207. }
  208. }
  209. //
  210. // Delete the registry data blob
  211. //
  212. delete[] pData;
  213. }
  214. }
  215. }
  216. }
  217. return true;
  218. }
  219. bool Write( HKEY hRoot, LPCTSTR pszKey, LPCTSTR pszValueName )
  220. {
  221. CSimpleReg reg( hRoot, pszKey, true, KEY_WRITE );
  222. if (reg.OK())
  223. {
  224. //
  225. // Find the size needed for the data. Initialize to the size of the registry signature struct.
  226. //
  227. DWORD nLengthInBytes = sizeof(REGISTRY_SIGNATURE);
  228. DWORD dwCount=0;
  229. //
  230. // Loop through each item and add up the number of bytes required to store it as a blob
  231. //
  232. Iterator ListIter=Begin();
  233. while (ListIter != End() && dwCount < static_cast<DWORD>(m_nNumToWrite))
  234. {
  235. nLengthInBytes += (*ListIter).RegistryDataSize() + sizeof(DWORD);
  236. ++dwCount;
  237. ++ListIter;
  238. }
  239. //
  240. // Allocate some memory to hold the blob
  241. //
  242. PBYTE pItems = new BYTE[nLengthInBytes];
  243. if (pItems)
  244. {
  245. //
  246. // Start at the end of the registry signature struct
  247. //
  248. PBYTE pCurr = pItems + sizeof(REGISTRY_SIGNATURE);
  249. //
  250. // Initialize the length remaining to the total length minus the size of the registry signature struct
  251. //
  252. DWORD nLengthRemaining = nLengthInBytes - sizeof(REGISTRY_SIGNATURE);
  253. //
  254. // Loop through the list, stopping when we get to the max number of items to write
  255. //
  256. ListIter=Begin();
  257. DWORD dwCurr = 0;
  258. while (ListIter != End() && dwCurr < dwCount)
  259. {
  260. //
  261. // Get the size of this blob
  262. //
  263. DWORD dwSize = (*ListIter).RegistryDataSize();
  264. if (dwSize)
  265. {
  266. //
  267. // Copy the size to our buffer, and increment the current pointer
  268. //
  269. CopyMemory( pCurr, &dwSize, sizeof(DWORD) );
  270. pCurr += sizeof(DWORD);
  271. //
  272. // Get the blob for this item
  273. //
  274. (*ListIter).GetRegistryData( pCurr, nLengthRemaining );
  275. //
  276. // Increment the current pointer
  277. //
  278. pCurr += (*ListIter).RegistryDataSize();
  279. }
  280. ++dwCurr;
  281. ++ListIter;
  282. }
  283. //
  284. // Initialize the registry signature struct
  285. //
  286. REGISTRY_SIGNATURE RegistrySignature = {0};
  287. RegistrySignature.dwSize = sizeof(REGISTRY_SIGNATURE);
  288. RegistrySignature.dwVersion = CURRENT_REGISTRY_DATA_FORMAT_VERSION;
  289. RegistrySignature.dwCount = dwCount;
  290. RegistrySignature.dwCrc = WiaCrc32::GenerateCrc32( nLengthInBytes - sizeof(REGISTRY_SIGNATURE), pItems + sizeof(REGISTRY_SIGNATURE) );
  291. //
  292. // Copy the registry signature struct to the buffer
  293. //
  294. CopyMemory( pItems, &RegistrySignature, sizeof(REGISTRY_SIGNATURE) );
  295. //
  296. // Save the data to the registry
  297. //
  298. reg.SetBin( pszValueName, pItems, nLengthInBytes, REG_BINARY );
  299. //
  300. // Free the temp buffer
  301. //
  302. delete[] pItems;
  303. }
  304. }
  305. return(true);
  306. }
  307. Iterator Add( CDestinationData item )
  308. {
  309. if (item.IsValid())
  310. {
  311. Remove(item);
  312. return Prepend(item);
  313. }
  314. return End();
  315. }
  316. };
  317. #endif //__MRU_H_INCLUDED