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.

444 lines
8.2 KiB

  1. // RegDataItem.cpp: implementation of the CRegDataItem class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "RegDataItem.h"
  5. #include "RegFile.h"
  6. #include <tchar.h>
  7. //////////////////////////////////////////////////////////////////////
  8. // Construction/Destruction
  9. //////////////////////////////////////////////////////////////////////
  10. CRegDataItem::CRegDataItem()
  11. : m_DataLen(0), m_NameLen(0), m_pDataBuf(NULL), m_Type(0),m_bIsEmpty(true),
  12. m_bDontDeleteData(false)
  13. {
  14. }
  15. CRegDataItem::~CRegDataItem()
  16. {
  17. if (!m_bDontDeleteData)
  18. delete m_pDataBuf;
  19. // delete m_pName;
  20. }
  21. int CRegDataItem::CompareTo(const CRegDataItem &r)
  22. {
  23. if ((m_bIsEmpty) && (r.m_bIsEmpty))
  24. return 0;
  25. else if ((m_bIsEmpty) && (!r.m_bIsEmpty))
  26. return 2;
  27. else if ((!m_bIsEmpty) && (r.m_bIsEmpty))
  28. return -1;
  29. else
  30. {
  31. int code = _tcscmp(m_Name, r.m_Name);
  32. if (code == 0) //names are the same, so compare item's data
  33. {
  34. if ((m_Type == r.m_Type)
  35. && (m_DataLen == r.m_DataLen)
  36. && (memcmp(m_pDataBuf, r.m_pDataBuf, m_DataLen) == 0))
  37. return 0;
  38. else
  39. return 1;
  40. }
  41. else if (code > 0)
  42. return 2;
  43. else
  44. return -1;
  45. }
  46. }
  47. LPTSTR GetCopy(LPCTSTR str)
  48. {
  49. if (str == NULL)
  50. return NULL;
  51. int len = _tcsclen(str) + 1;
  52. LPTSTR temp = new TCHAR[len];
  53. if (temp == NULL)
  54. {
  55. LOG0(LOG_ERROR,"Couldn't allocate buffer in GetCopy(LPCTSTR)");
  56. return NULL;
  57. }
  58. else
  59. {
  60. _tcscpy(temp, str);
  61. return temp;
  62. }
  63. }
  64. void CRegDataItem::WriteToInfFile(CRegFile &file, bool bWriteValueData)
  65. {
  66. LPTSTR RootKeyName;
  67. LPTSTR SubKeyName;
  68. SplitString(m_KeyName, RootKeyName, SubKeyName, TEXT('\\'));
  69. file.WriteString(RootKeyName);
  70. file.WriteString(TEXT(","));
  71. file.WriteString(SubKeyName);
  72. delete[] RootKeyName;
  73. delete[] SubKeyName;
  74. if (m_Name != NULL)
  75. {
  76. LPTSTR Name = GetQuotedString(m_Name);
  77. file.WriteString(TEXT(","));
  78. file.WriteString(Name);
  79. delete[] Name;
  80. if (bWriteValueData)
  81. {
  82. file.WriteString(TEXT(","));
  83. WriteDataString(file);
  84. }
  85. }
  86. file.WriteNewLine();
  87. }
  88. LPTSTR CRegDataItem::GetQuotedString(LPCTSTR str)
  89. {
  90. int i=0, specialchars=0;
  91. TCHAR quote = TEXT('\"');
  92. if (str == NULL)
  93. return NULL;
  94. while (str[i] != 0)
  95. {
  96. if (str[i] == quote)
  97. specialchars++;
  98. i++;
  99. }
  100. LPTSTR temp = new TCHAR[i+specialchars+3];
  101. //include the chars of original string,
  102. // the escape characters needed for each specialchar
  103. // 1 char for the NULL
  104. // 2 chars for the quotes (") at the beginning and end of string
  105. int k=1;
  106. for (int j=0; j<i; j++)
  107. {
  108. if (str[j] == quote)
  109. {
  110. temp[k] = quote;
  111. k++;
  112. }
  113. temp[k] = str[j];
  114. k++;
  115. }
  116. temp[0] = quote;
  117. temp[k] = quote;
  118. temp[k+1] = NULL;
  119. return temp;
  120. }
  121. void CRegDataItem::SplitString(LPCTSTR source, LPTSTR& first, LPTSTR& last, TCHAR separator)
  122. {
  123. LPTSTR str=GetCopy(source);
  124. if (str == NULL)
  125. {
  126. LOG0(LOG_ERROR, "Could not get copy of string in CRegDataItem::SplitString");
  127. return;
  128. }
  129. for (int i=0; str[i] != NULL; i++)
  130. {
  131. if (str[i] == separator)
  132. break;
  133. }
  134. if (str[i] == separator)
  135. {
  136. last = GetQuotedString(str+i+1);
  137. str[i]=NULL;
  138. }
  139. else
  140. {
  141. str[i]=NULL;
  142. last = GetQuotedString(str+i);
  143. }
  144. first = GetQuotedString(str);
  145. delete[] str;
  146. }
  147. void CRegDataItem::WriteDataString(CRegFile& file)
  148. {
  149. //10 chars - hex type string
  150. //1 char - comma
  151. //x chars - data string
  152. // case String -
  153. DWORD InfCode = 1;
  154. LPTSTR DataString = NULL;
  155. TCHAR TypeStr[20];
  156. switch (m_Type)
  157. {
  158. case REG_BINARY: InfCode = 0x00000001;
  159. DataString=GetBinaryString(); break;
  160. case REG_DWORD: InfCode = 0x00010001;
  161. DataString = GetDwordString(); break;
  162. // case REG_DWORD_BIG_ENDIAN: break;
  163. case REG_EXPAND_SZ: InfCode = 0x00020000;
  164. DataString=GetQuotedString((LPCTSTR)m_pDataBuf); break;
  165. case REG_MULTI_SZ: WriteInfCode(file,0x00010000);
  166. WriteMultiString(file); return;
  167. case REG_SZ: InfCode = 0x00000000;
  168. DataString=GetQuotedString((LPCTSTR)m_pDataBuf); break;
  169. // case REG_LINK: break;
  170. case REG_NONE: InfCode = 0x00020001;
  171. DataString = GetBinaryString(); break;
  172. // case REG_QWORD: break;
  173. // case REG_RESOURCE_LIST: break;
  174. default:
  175. {
  176. //The code will contain the bits of m_Type in its highword, and
  177. //0x0001 in its low word. This is how we specify a custom type
  178. //for an inf file.
  179. InfCode = m_Type;
  180. InfCode = InfCode << 16;
  181. InfCode +=1;
  182. DataString = GetBinaryString();
  183. }
  184. break;
  185. };
  186. LPTSTR result;
  187. if (m_DataLen > 0)
  188. {
  189. int len = _tcsclen(DataString);
  190. result = new TCHAR[len + 20];
  191. _stprintf(result,TEXT("0x%08X,%s"), InfCode, DataString);
  192. }
  193. else
  194. {
  195. result = new TCHAR[20];
  196. _stprintf(result,TEXT("0x%08X"), InfCode);
  197. }
  198. delete[] DataString;
  199. file.WriteString(result);
  200. delete[] result;
  201. }
  202. LPTSTR CRegDataItem::GetBinaryString()
  203. {
  204. if (m_DataLen == 0)
  205. return NULL;
  206. int len = m_DataLen*3+1;
  207. LPTSTR result = new TCHAR[len];
  208. LPTSTR temp = result;
  209. for (DWORD i=0; i<m_DataLen; i++)
  210. {
  211. DWORD val = (DWORD)m_pDataBuf[i];
  212. _stprintf(temp,TEXT("%02X,"), val);
  213. temp+=3;
  214. }
  215. result[len-2]=NULL;
  216. return result;
  217. //return GetCopy("Binary String Data");
  218. }
  219. LPTSTR CRegDataItem::GetDwordString()
  220. {
  221. LPTSTR result = new TCHAR[20];
  222. _stprintf(result,TEXT("0x%08X"), *((DWORD*)m_pDataBuf));
  223. return result;
  224. }
  225. void CRegDataItem::WriteMultiString(CRegFile& file)
  226. {
  227. /* for (DWORD i=0; i <m_DataLen; i++)
  228. {
  229. if (m_pData[i] == NULL)
  230. NumBlanks++;
  231. }
  232. */
  233. if (m_DataLen == 1) //no multistrings - only one NULL character
  234. return file.WriteString(TEXT(",\"\""));
  235. else
  236. {
  237. LPTSTR buf = (LPTSTR)m_pDataBuf;
  238. while (true)
  239. {
  240. file.WriteString(TEXT(","));
  241. LPTSTR temp = GetQuotedString(buf);
  242. if (temp == NULL)
  243. {
  244. LOG0(LOG_ERROR, "Couldn't allocate quoted string in 'WriteMultiString'");
  245. return;
  246. }
  247. file.WriteString(temp);
  248. delete[] temp;
  249. while(*buf != NULL)
  250. buf++;
  251. if (*(buf+1) == NULL)
  252. break;
  253. else
  254. buf++;
  255. }
  256. }
  257. /* DWORD NumBlanks=0;
  258. for (DWORD i=0; i <m_DataLen; i++)
  259. {
  260. if (m_pData[i] == NULL)
  261. NumBlanks++;
  262. }
  263. if (NumBlanks == 1) //no multistrings - only one NULL character
  264. return GetQuotedString((LPCTSTR)m_pData);
  265. else
  266. {
  267. CSmartBuffer<LPTSTR> multi;
  268. LPCTSTR temp = (LPCTSTR)m_pData;
  269. multi.AddElement(GetQuotedString(temp));
  270. int memneeded=0;
  271. for (DWORD i=0; i <m_DataLen; i++)
  272. {
  273. if ((m_pData[i] == NULL) && (i < (m_DataLen-2)))
  274. {
  275. multi.AddElement(GetQuotedString((LPCTSTR)m_pData+i+1);
  276. memneeded += multi.
  277. }
  278. }
  279. }*/
  280. }
  281. void CRegDataItem::WriteInfCode(CRegFile &file, DWORD InfCode)
  282. {
  283. TCHAR result[20];
  284. _stprintf(result,TEXT("0x%08X"), InfCode);
  285. file.WriteString(result);
  286. }
  287. void CRegDataItem::WriteToFile(CRegFile &file)
  288. {
  289. if (!m_bIsEmpty)
  290. {
  291. if (m_KeyName != NULL)
  292. {
  293. file.WriteString(m_KeyName);
  294. file.WriteNewLine();
  295. }
  296. if (m_Name != NULL) //this data item contains a registry data value
  297. {
  298. TCHAR t;
  299. switch(m_Type)
  300. {
  301. case REG_BINARY: t=L'B'; break;
  302. case REG_DWORD: t=L'd'; break;
  303. case REG_DWORD_BIG_ENDIAN: t=L'D'; break;
  304. case REG_EXPAND_SZ: t=L'E'; break;
  305. case REG_MULTI_SZ: t=L'M'; break;
  306. case REG_SZ: t=L'S'; break;
  307. case REG_LINK: t=L'L'; break;
  308. case REG_NONE: t=L'N'; break;
  309. case REG_QWORD: t=L'Q'; break;
  310. case REG_RESOURCE_LIST: t=L'R'; break;
  311. default: t=L'Z'; break; //unknown type! it does occur in the registry! HKLM
  312. };
  313. int NameLen = _tcsclen(m_Name);
  314. TCHAR* temp = new TCHAR[NameLen+100];
  315. _stprintf(temp, TEXT("S%u:%s = %c(%u)%u:"), NameLen, (LPCTSTR)m_Name, t, m_Type, m_DataLen);
  316. file.WriteString(temp);
  317. delete [] temp;
  318. //unicode ***********************************
  319. if ((m_DataLen %2) != 0)
  320. {
  321. BYTE nullByte=0;
  322. file.WriteData(&nullByte, 1);
  323. }
  324. // ***********************************
  325. file.WriteData(m_pDataBuf, m_DataLen);
  326. file.WriteNewLine();
  327. }
  328. }
  329. }