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.

524 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: fparse.cpp
  8. //
  9. // Contents: File parsing api -- INI file types
  10. //
  11. // History: 01-Oct-1997 pberkman create
  12. //
  13. //--------------------------------------------------------------------------
  14. #include "global.hxx"
  15. #include "fparse.hxx"
  16. fParse_::fParse_(WCHAR *pwszFilename, BOOL *pfFailed, DWORD dwMaxLine0, DWORD dwFileAccess, DWORD dwFileSharing)
  17. {
  18. hFile = INVALID_HANDLE_VALUE;
  19. dwMaxLine = dwMaxLine0;
  20. pwszCurrentLine = NULL;
  21. dwCurLineFilePos = 0;
  22. dwLastGroupFilePos = 0;
  23. dwLastTagFilePos = 0;
  24. fEOF = FALSE;
  25. pwszTempFName = NULL;
  26. pwszLastGroupTag = NULL;
  27. __try
  28. {
  29. hFile = CreateFileU(
  30. pwszFilename,
  31. dwFileAccess,
  32. dwFileSharing,
  33. NULL,
  34. OPEN_EXISTING,
  35. FILE_ATTRIBUTE_NORMAL,
  36. NULL);
  37. pwszCurrentLine = new WCHAR[dwMaxLine];
  38. if (pwszFName = new WCHAR[wcslen(pwszFilename) + 1])
  39. {
  40. wcscpy(pwszFName, pwszFilename);
  41. }
  42. if ((hFile == INVALID_HANDLE_VALUE) ||
  43. (pwszCurrentLine == NULL) ||
  44. (pwszFName == NULL))
  45. {
  46. *pfFailed = TRUE;
  47. }
  48. else
  49. {
  50. *pfFailed = FALSE;
  51. }
  52. } // __try
  53. __except(EXCEPTION_EXECUTE_HANDLER)
  54. {
  55. *pfFailed = TRUE;
  56. }
  57. if (*pfFailed)
  58. {
  59. if (hFile != INVALID_HANDLE_VALUE)
  60. {
  61. CloseHandle(hFile);
  62. hFile = INVALID_HANDLE_VALUE;
  63. }
  64. if (pwszCurrentLine != NULL)
  65. {
  66. DELETE_OBJECT(pwszCurrentLine);
  67. pwszCurrentLine = NULL;
  68. }
  69. if (pwszFName != NULL)
  70. {
  71. DELETE_OBJECT(pwszFName);
  72. pwszFName = NULL;
  73. }
  74. }
  75. }
  76. fParse_::~fParse_(void)
  77. {
  78. if (hFile != INVALID_HANDLE_VALUE)
  79. {
  80. CloseHandle(hFile);
  81. }
  82. if (pwszCurrentLine)
  83. {
  84. DELETE_OBJECT(pwszCurrentLine);
  85. }
  86. DELETE_OBJECT(pwszLastGroupTag);
  87. if (pwszTempFName)
  88. {
  89. CopyFileU(pwszTempFName, pwszFName, FALSE);
  90. DeleteFileU(pwszTempFName);
  91. delete pwszTempFName;
  92. }
  93. if (pwszFName != NULL)
  94. {
  95. DELETE_OBJECT(pwszFName);
  96. }
  97. }
  98. BOOL fParse_::AddTagToFile(WCHAR *pwszGroup, WCHAR *pwszTag, WCHAR *pwszValue)
  99. {
  100. if (!(this->pwszCurrentLine) || (this->hFile == INVALID_HANDLE_VALUE))
  101. {
  102. return(FALSE);
  103. }
  104. char szTFile[MAX_PATH * 2];
  105. WCHAR wszGroup[MAX_PATH];
  106. HANDLE hTFile;
  107. DWORD ccTFile;
  108. DWORD cbWrite;
  109. BOOL fWritten;
  110. if (!(pwszLastGroupTag))
  111. {
  112. return(FALSE);
  113. }
  114. if (pwszTag[0] != L'[')
  115. {
  116. wcscpy(&wszGroup[0], L"[");
  117. wcscat(&wszGroup[0], pwszGroup);
  118. wcscat(&wszGroup[0], L"]");
  119. }
  120. else
  121. {
  122. wcscpy(&wszGroup[0], pwszTag);
  123. }
  124. szTFile[0] = NULL;
  125. GetTempFileName(".", "FPS", 0, &szTFile[0]);
  126. if (!(szTFile[0]))
  127. {
  128. return(FALSE);
  129. }
  130. ccTFile = MultiByteToWideChar(0, 0, &szTFile[0], -1, NULL, 0);
  131. if (ccTFile < 1)
  132. {
  133. return(FALSE);
  134. }
  135. if (!(pwszTempFName = new WCHAR[ccTFile + 1]))
  136. {
  137. return(FALSE);
  138. }
  139. MultiByteToWideChar(0, 0, &szTFile[0], -1, pwszTempFName, ccTFile + 1);
  140. hTFile = CreateFileU(pwszTempFName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
  141. FILE_ATTRIBUTE_NORMAL, NULL);
  142. if (hTFile == INVALID_HANDLE_VALUE)
  143. {
  144. return(FALSE);
  145. }
  146. SetFilePointer(this->hFile, 0, NULL, FILE_BEGIN);
  147. fWritten = FALSE;
  148. while (this->GetNextLine())
  149. {
  150. szTFile[0] = NULL;
  151. WideCharToMultiByte(0, 0, this->pwszCurrentLine, wcslen(this->pwszCurrentLine) + 1,
  152. &szTFile[0], MAX_PATH * 2, NULL, NULL);
  153. if (szTFile[0])
  154. {
  155. WriteFile(hTFile, &szTFile[0], strlen(&szTFile[0]), &cbWrite, NULL);
  156. if (!(fWritten))
  157. {
  158. this->EOLRemove();
  159. if (_memicmp(this->pwszCurrentLine, &wszGroup[0],
  160. wcslen(&wszGroup[0]) * sizeof(WCHAR)) == 0)
  161. {
  162. //
  163. // add our line
  164. //
  165. szTFile[0] = NULL;
  166. WideCharToMultiByte(0, 0, pwszTag, wcslen(pwszTag) + 1, &szTFile[0], MAX_PATH, NULL, NULL);
  167. WriteFile(hTFile, &szTFile[0], strlen(&szTFile[0]), &cbWrite, NULL);
  168. WriteFile(hTFile, "=", 1, &cbWrite, NULL);
  169. szTFile[0] = NULL;
  170. WideCharToMultiByte(0, 0, pwszValue, wcslen(pwszValue) + 1, &szTFile[0], MAX_PATH * 2, NULL, NULL);
  171. WriteFile(hTFile, &szTFile[0], strlen(&szTFile[0]), &cbWrite, NULL);
  172. WriteFile(hTFile, "\r\n", 2, &cbWrite, NULL);
  173. fWritten = TRUE;
  174. }
  175. }
  176. }
  177. }
  178. CloseHandle(hTFile);
  179. this->Reset();
  180. return(TRUE);
  181. }
  182. void fParse_::Reset(void)
  183. {
  184. this->dwCurLineFilePos = 0;
  185. this->dwLastGroupFilePos = 0;
  186. this->dwLastTagFilePos = 0;
  187. SetFilePointer(this->hFile, 0, NULL, FILE_BEGIN);
  188. }
  189. BOOL fParse_::PositionAtLastGroup(void)
  190. {
  191. if (SetFilePointer(this->hFile, this->dwLastGroupFilePos, NULL,
  192. FILE_BEGIN) == 0xFFFFFFFF)
  193. {
  194. return(FALSE);
  195. }
  196. return(TRUE);
  197. }
  198. BOOL fParse_::PositionAtLastTag(void)
  199. {
  200. if (this->dwLastTagFilePos == 0)
  201. {
  202. return(FALSE);
  203. }
  204. if (SetFilePointer(this->hFile, this->dwLastTagFilePos, NULL,
  205. FILE_BEGIN) == 0xFFFFFFFF)
  206. {
  207. return(FALSE);
  208. }
  209. return(TRUE);
  210. }
  211. BOOL fParse_::GetLineInCurrentGroup(void)
  212. {
  213. if (this->dwLastGroupFilePos == 0)
  214. {
  215. return(FALSE);
  216. }
  217. if (this->dwLastTagFilePos == 0)
  218. {
  219. this->PositionAtLastGroup();
  220. }
  221. while (this->GetNextLine() > 0)
  222. {
  223. if ((this->pwszCurrentLine[0] == L'#') ||
  224. (this->pwszCurrentLine[0] == L';') ||
  225. (this->pwszCurrentLine[0] == 0x000d))
  226. {
  227. continue;
  228. }
  229. if (this->pwszCurrentLine[0] == L'[')
  230. {
  231. this->pwszCurrentLine[0] = NULL;
  232. return(FALSE);
  233. }
  234. this->EOLRemove();
  235. if (wcslen(this->pwszCurrentLine) > 0)
  236. {
  237. this->dwLastTagFilePos = this->dwCurLineFilePos;
  238. return(TRUE);
  239. }
  240. }
  241. this->pwszCurrentLine[0] = NULL;
  242. return(FALSE);
  243. }
  244. BOOL fParse_::FindTagInCurrentGroup(WCHAR *pwszTag)
  245. {
  246. if (this->dwLastGroupFilePos == 0)
  247. {
  248. return(FALSE);
  249. }
  250. WCHAR wszCheck[MAX_PATH];
  251. WCHAR wszCheck2[MAX_PATH];
  252. wcscpy(&wszCheck[0], pwszTag);
  253. wcscat(&wszCheck[0], L"=");
  254. wcscpy(&wszCheck2[0], pwszTag);
  255. wcscpy(&wszCheck2[0], L" =");
  256. this->PositionAtLastGroup();
  257. while (this->GetNextLine() > 0)
  258. {
  259. if ((this->pwszCurrentLine[0] == L'#') ||
  260. (this->pwszCurrentLine[0] == L';') ||
  261. (this->pwszCurrentLine[0] == 0x000d))
  262. {
  263. continue;
  264. }
  265. if (this->pwszCurrentLine[0] == L'[')
  266. {
  267. this->pwszCurrentLine[0] = NULL;
  268. return(FALSE);
  269. }
  270. if ((_memicmp(this->pwszCurrentLine, &wszCheck[0], wcslen(&wszCheck[0]) * sizeof(WCHAR)) == 0) ||
  271. (_memicmp(this->pwszCurrentLine, &wszCheck2[0], wcslen(&wszCheck2[0]) * sizeof(WCHAR)) == 0))
  272. {
  273. this->dwLastTagFilePos = this->dwCurLineFilePos;
  274. this->EOLRemove();
  275. return(TRUE);
  276. }
  277. }
  278. this->pwszCurrentLine[0] = NULL;
  279. return(FALSE);
  280. }
  281. BOOL fParse_::FindTagFromCurrentPos(WCHAR *pwszTag)
  282. {
  283. WCHAR wszCheck[MAX_PATH];
  284. WCHAR wszCheck2[MAX_PATH];
  285. wcscpy(&wszCheck[0], pwszTag);
  286. wcscat(&wszCheck[0], L"=");
  287. wcscpy(&wszCheck2[0], pwszTag);
  288. wcscat(&wszCheck2[0], L" =");
  289. this->dwLastTagFilePos++;
  290. while (this->GetNextLine() > 0)
  291. {
  292. if ((this->pwszCurrentLine[0] == L'#') ||
  293. (this->pwszCurrentLine[0] == L';') ||
  294. (this->pwszCurrentLine[0] == 0x000d))
  295. {
  296. continue;
  297. }
  298. if ((_memicmp(this->pwszCurrentLine, &wszCheck[0], wcslen(&wszCheck[0]) * sizeof(WCHAR)) == 0) ||
  299. (_memicmp(this->pwszCurrentLine, &wszCheck2[0], wcslen(&wszCheck2[0]) * sizeof(WCHAR)) == 0))
  300. {
  301. this->dwLastTagFilePos = this->dwCurLineFilePos;
  302. this->EOLRemove();
  303. return(TRUE);
  304. }
  305. }
  306. this->pwszCurrentLine[0] = NULL;
  307. return(FALSE);
  308. }
  309. DWORD fParse_::GetNextLine(void)
  310. {
  311. if (!(this->pwszCurrentLine) ||
  312. (this->hFile == INVALID_HANDLE_VALUE))
  313. {
  314. return(0);
  315. }
  316. DWORD dwHold;
  317. DWORD cbRead;
  318. DWORD cwbRead;
  319. DWORD dw;
  320. int iAmt;
  321. BYTE *pb;
  322. if ((dwHold = SetFilePointer(this->hFile, 0, NULL, FILE_CURRENT)) == 0xFFFFFFFF)
  323. {
  324. return(0);
  325. }
  326. __try
  327. {
  328. pb = new BYTE[dwMaxLine + 2];
  329. }
  330. __except(EXCEPTION_EXECUTE_HANDLER)
  331. {
  332. pb = NULL;
  333. }
  334. if (pb == NULL)
  335. {
  336. return(0);
  337. }
  338. cbRead = 0;
  339. if (ReadFile(this->hFile, pb, dwMaxLine, &cbRead, NULL))
  340. {
  341. if (cbRead == 0)
  342. {
  343. this->fEOF = TRUE;
  344. delete pb;
  345. return(0);
  346. }
  347. pb[cbRead] = 0x00;
  348. this->fEOF = FALSE;
  349. if (cbRead > 0)
  350. {
  351. iAmt = 0;
  352. for (dw = 0; dw < (cbRead - 1); dw++)
  353. {
  354. if ((pb[dw] == 0x0d) ||
  355. (pb[dw] == 0x0a))
  356. {
  357. iAmt++;
  358. if (pb[dw + 1] == 0x0a)
  359. {
  360. dw++;
  361. iAmt++;
  362. }
  363. if (SetFilePointer(this->hFile, dwHold + (dw + 1),
  364. NULL, FILE_BEGIN) == 0xFFFFFFFF)
  365. {
  366. this->dwCurLineFilePos = 0;
  367. }
  368. else
  369. {
  370. this->dwCurLineFilePos = SetFilePointer(this->hFile, 0, NULL, FILE_CURRENT) - iAmt;
  371. }
  372. pb[dw + 1] = 0x00;
  373. cwbRead = MultiByteToWideChar(0, 0, (const char *)pb, -1,
  374. pwszCurrentLine, dwMaxLine);
  375. delete pb;
  376. return(cwbRead + 1);
  377. }
  378. }
  379. }
  380. }
  381. else
  382. {
  383. delete pb;
  384. return(0);
  385. }
  386. if (pb[cbRead - 1] == 0x1a) /* EOF */
  387. {
  388. cbRead--;
  389. this->dwCurLineFilePos = 0;
  390. this->fEOF = TRUE;
  391. }
  392. else
  393. {
  394. this->dwCurLineFilePos = dwHold;
  395. }
  396. pb[cbRead] = 0x00;
  397. cwbRead = MultiByteToWideChar(0, 0, (const char *)pb, -1,
  398. pwszCurrentLine, dwMaxLine);
  399. delete pb;
  400. return(cwbRead);
  401. }
  402. void fParse_::EOLRemove(void)
  403. {
  404. DWORD i;
  405. DWORD ccLen;
  406. ccLen = wcslen(this->pwszCurrentLine);
  407. for (i = 0; i < ccLen; i++)
  408. {
  409. if ((this->pwszCurrentLine[i] == (WCHAR)0x0a) ||
  410. (this->pwszCurrentLine[i] == (WCHAR)0x0d))
  411. {
  412. this->pwszCurrentLine[i] = NULL;
  413. return;
  414. }
  415. }
  416. this->pwszCurrentLine[ccLen] = NULL;
  417. }