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.

395 lines
9.9 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. /*++
  4. Copyright (c) 1990 Microsoft Corporation
  5. Module Name:
  6. cf.c
  7. Abstract:
  8. 1. Contains code to perform simple text substitutions on a text file.
  9. 2. Contains code to append text entries to a text file.
  10. This module has no external dependencies and is not statically linked
  11. to any part of Setup.
  12. Author:
  13. Ted Miller (tedm) July 1991
  14. --*/
  15. BOOL WriteData(HANDLE Handle,PVOID Data,DWORD DataSize);
  16. BOOL
  17. ConfigFileSubstWorker(
  18. IN LPSTR File,
  19. IN DWORD NumSubsts,
  20. IN LPSTR *Substs
  21. )
  22. {
  23. LPSTR CharPtr,old;
  24. LPSTR FileBuf=NULL,FileBufEnd;
  25. DWORD *StrLenArray;
  26. DWORD FileLength = 0xffffffff;
  27. HANDLE FileHandle = (HANDLE)(-1);
  28. DWORD rcID;
  29. BOOL Match;
  30. DWORD x,i;
  31. char CRLF[2];
  32. BOOL IsCFGFile;
  33. #define ORIGINAL_TEXT(i) Substs[(2*i)]
  34. #define REPLACEMENT_TEXT(i) Substs[(2*i)+1]
  35. #define ORIGINAL_TEXT_LENGTH(i) StrLenArray[i]
  36. CRLF[0] = '\r';
  37. CRLF[1] = '\n';
  38. if((StrLenArray = SAlloc(NumSubsts * sizeof(DWORD))) == NULL) {
  39. SetErrorText(IDS_ERROR_DLLOOM);
  40. return(FALSE);
  41. }
  42. for(i=0; i<NumSubsts; i++) {
  43. ORIGINAL_TEXT_LENGTH(i) = lstrlen(ORIGINAL_TEXT(i));
  44. }
  45. if(((FileHandle = CreateFile(File,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL)) == (HANDLE)(-1))
  46. || ((FileLength = GetFileSize(FileHandle,NULL)) == 0xffffffff)
  47. || ((FileBuf = SAlloc(FileLength+1)) == NULL)
  48. || (ReadFile(FileHandle,FileBuf,FileLength,&i,NULL) == FALSE))
  49. {
  50. if(FileBuf != NULL) {
  51. rcID = IDS_ERROR_READFAILED;
  52. SFree(FileBuf);
  53. } else if(FileLength != 0xffffffff) {
  54. rcID = IDS_ERROR_DLLOOM;
  55. } else if(FileHandle != (HANDLE)-1) {
  56. rcID = IDS_ERROR_NOSIZE;
  57. } else {
  58. rcID = IDS_ERROR_BADFILE;
  59. }
  60. if(rcID != IDS_ERROR_BADFILE) {
  61. CloseHandle(FileHandle);
  62. }
  63. SFree(StrLenArray);
  64. SetErrorText(rcID);
  65. return(FALSE);
  66. }
  67. CloseHandle(FileHandle);
  68. if((FileHandle = CreateFile(File,GENERIC_WRITE,0,NULL,TRUNCATE_EXISTING,0,NULL)) == (HANDLE)(-1)) { // truncate
  69. SFree(StrLenArray);
  70. SFree(FileBuf);
  71. SetErrorText(IDS_ERROR_BADFILE);
  72. return(FALSE);
  73. }
  74. FileBufEnd = FileBuf + FileLength - 1;
  75. if(*FileBufEnd != '\n') {
  76. *(FileBufEnd+1) = '\n';
  77. }
  78. for(CharPtr = FileBuf; CharPtr <= FileBufEnd; CharPtr++) {
  79. if(*CharPtr == '\n') {
  80. *CharPtr = '\0';
  81. }
  82. }
  83. if((x = lstrlen(File)) > 4) {
  84. IsCFGFile = !lstrcmpi(&File[x-4],".cfg");
  85. }
  86. CharPtr = FileBuf-1;
  87. while(++CharPtr <= FileBufEnd) { // skips NUL
  88. while(*CharPtr) {
  89. if(*CharPtr == '\r') {
  90. CharPtr++;
  91. continue;
  92. }
  93. // ignore comments in .cfg files
  94. if(IsCFGFile && (*CharPtr == '/') && (*(CharPtr+1) == '/')) {
  95. old = CharPtr;
  96. while(*CharPtr && (*CharPtr != '\r')) {
  97. CharPtr++;
  98. }
  99. if(!WriteData(FileHandle,old,(DWORD)(CharPtr - old))) {
  100. goto xxx_err1;
  101. }
  102. if(*CharPtr == '\r') {
  103. CharPtr++;
  104. }
  105. continue;
  106. }
  107. Match = FALSE;
  108. for(i=0; i<NumSubsts && !Match; i++) {
  109. if(!strncmp(ORIGINAL_TEXT(i),CharPtr,ORIGINAL_TEXT_LENGTH(i))) {
  110. Match = TRUE;
  111. if(!WriteData(FileHandle,REPLACEMENT_TEXT(i),lstrlen(REPLACEMENT_TEXT(i)))) {
  112. goto xxx_err1;
  113. }
  114. CharPtr += ORIGINAL_TEXT_LENGTH(i);
  115. }
  116. }
  117. if(!Match) {
  118. if(!WriteData(FileHandle,CharPtr,1)) {
  119. goto xxx_err1;
  120. }
  121. CharPtr++;
  122. }
  123. }
  124. if(!WriteData(FileHandle,CRLF,sizeof(CRLF))) {
  125. goto xxx_err1;
  126. }
  127. }
  128. xxx_err1:
  129. FlushFileBuffers(FileHandle);
  130. CloseHandle(FileHandle);
  131. SFree(StrLenArray);
  132. SFree(FileBuf);
  133. return(TRUE);
  134. }
  135. BOOL
  136. BinaryFileSubstWorker(
  137. IN LPSTR File,
  138. IN DWORD NumSubsts,
  139. IN LPSTR *Substs
  140. )
  141. {
  142. LPSTR CharPtr;
  143. LPSTR FileBuf=NULL;
  144. DWORD *StrLenArray;
  145. DWORD FileLength = 0xffffffff;
  146. HANDLE FileHandle = (HANDLE)(-1);
  147. DWORD rcID;
  148. BOOL Match;
  149. DWORD i;
  150. if((StrLenArray = SAlloc(NumSubsts * sizeof(DWORD))) == NULL) {
  151. SetErrorText(IDS_ERROR_DLLOOM);
  152. return(FALSE);
  153. }
  154. // make sure original and replacement text are the same length
  155. // within a given pair
  156. for(i=0; i<NumSubsts; i++) {
  157. ORIGINAL_TEXT_LENGTH(i) = lstrlen(ORIGINAL_TEXT(i));
  158. if(ORIGINAL_TEXT_LENGTH(i) != (DWORD)lstrlen(REPLACEMENT_TEXT(i))) {
  159. SFree(StrLenArray);
  160. SetErrorText(IDS_ERROR_BADARGS);
  161. return(FALSE);
  162. }
  163. }
  164. if(((FileHandle = CreateFile(File,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL)) == (HANDLE)(-1))
  165. || ((FileLength = GetFileSize(FileHandle,NULL)) == 0xffffffff)
  166. || ((FileBuf = SAlloc(FileLength)) == NULL)
  167. || (ReadFile(FileHandle,FileBuf,FileLength,&i,NULL) == FALSE))
  168. {
  169. if(FileBuf != NULL) {
  170. rcID = IDS_ERROR_READFAILED;
  171. SFree(FileBuf);
  172. } else if(FileLength != 0xffffffff) {
  173. rcID = IDS_ERROR_DLLOOM;
  174. } else if(FileHandle != (HANDLE)-1) {
  175. rcID = IDS_ERROR_NOSIZE;
  176. } else {
  177. rcID = IDS_ERROR_BADFILE;
  178. }
  179. if(rcID != IDS_ERROR_BADFILE) {
  180. CloseHandle(FileHandle);
  181. }
  182. SFree(StrLenArray);
  183. SetErrorText(rcID);
  184. return(FALSE);
  185. }
  186. CloseHandle(FileHandle);
  187. if((FileHandle = CreateFile(File,GENERIC_WRITE,0,NULL,TRUNCATE_EXISTING,0,NULL)) == (HANDLE)(-1)) { // truncate
  188. SFree(StrLenArray);
  189. SFree(FileBuf);
  190. SetErrorText(IDS_ERROR_BADFILE);
  191. return(FALSE);
  192. }
  193. for(CharPtr=FileBuf; CharPtr<FileBuf+FileLength; ) {
  194. for(Match=FALSE,i=0; i<NumSubsts && !Match; i++) {
  195. if(!strncmp(ORIGINAL_TEXT(i),CharPtr,ORIGINAL_TEXT_LENGTH(i))) {
  196. Match = TRUE;
  197. if(!WriteData(FileHandle,REPLACEMENT_TEXT(i),lstrlen(REPLACEMENT_TEXT(i)))) {
  198. goto xxx_err2;
  199. }
  200. CharPtr += ORIGINAL_TEXT_LENGTH(i);
  201. }
  202. }
  203. if(!Match) {
  204. if(!WriteData(FileHandle,CharPtr,1)) {
  205. goto xxx_err2;
  206. }
  207. CharPtr++;
  208. }
  209. }
  210. xxx_err2:
  211. FlushFileBuffers(FileHandle);
  212. CloseHandle(FileHandle);
  213. SFree(StrLenArray);
  214. SFree(FileBuf);
  215. return(TRUE);
  216. }
  217. BOOL
  218. ConfigFileAppendWorker(
  219. IN LPSTR File,
  220. IN DWORD NumSubsts,
  221. IN LPSTR *Substs
  222. )
  223. {
  224. HANDLE FileHandle;
  225. DWORD rcID;
  226. DWORD i;
  227. char CRLF[2];
  228. DWORD OriginalAttributes;
  229. OFSTRUCT ReOpen;
  230. CRLF[0] = '\r';
  231. CRLF[1] = '\n';
  232. // See if file exists, if it doesn't open it with create option. else
  233. // Open existing after modifying attributes to FILE_ATTRIBUTE_NORMAL
  234. if (OpenFile(File,&ReOpen,OF_EXIST) == -1) {
  235. OriginalAttributes = FILE_ATTRIBUTE_NORMAL;
  236. FileHandle = CreateFile(
  237. File,
  238. GENERIC_READ | GENERIC_WRITE,
  239. 0,
  240. NULL,
  241. CREATE_NEW,
  242. OriginalAttributes,
  243. NULL
  244. );
  245. if (FileHandle == (HANDLE)-1) {
  246. SetErrorText(IDS_ERROR_BADFILE);
  247. return(FALSE);
  248. }
  249. }
  250. else {
  251. // 1. Modify Attributes
  252. if (!(
  253. ((OriginalAttributes = GetFileAttributes(File)) != -1L)
  254. &&
  255. (
  256. OriginalAttributes == FILE_ATTRIBUTE_NORMAL
  257. ||
  258. SetFileAttributes(File, FILE_ATTRIBUTE_NORMAL)
  259. )
  260. )
  261. ) {
  262. SetErrorText(IDS_ERROR_BADFILE);
  263. return(FALSE);
  264. }
  265. // 2. Open the file
  266. if((FileHandle = CreateFile(
  267. File,
  268. GENERIC_READ | GENERIC_WRITE,
  269. 0,
  270. NULL,
  271. OPEN_EXISTING,
  272. 0,
  273. NULL
  274. )) == (HANDLE)(-1)) {
  275. rcID = IDS_ERROR_BADFILE;
  276. SetErrorText(rcID);
  277. return(FALSE);
  278. }
  279. // 3. Shift file pointer to end
  280. if(SetFilePointer(
  281. FileHandle, // The File Handle
  282. 0L, // Distance to move, low dword
  283. 0L, // Distance to move, high dword
  284. FILE_END // Move Method, (relative to eof)
  285. ) == (DWORD)-1L){
  286. rcID = IDS_ERROR_BADFILE;
  287. CloseHandle(FileHandle);
  288. SetErrorText(rcID);
  289. return(FALSE);
  290. }
  291. } // end of else
  292. // Append all the text entries to the end of the file
  293. for (i = 0; i < NumSubsts; i++)
  294. if(!WriteData (FileHandle, Substs[i], lstrlen(Substs[i])) ||
  295. !WriteData(FileHandle,CRLF,sizeof(CRLF)))
  296. break;
  297. // Clean up
  298. FlushFileBuffers(FileHandle);
  299. CloseHandle(FileHandle);
  300. // reset the attributes to the previous attributes
  301. if(!(OriginalAttributes == FILE_ATTRIBUTE_NORMAL ||
  302. SetFileAttributes(File, OriginalAttributes)))
  303. SetErrorText(IDS_ERROR_BADFILE);
  304. return(TRUE);
  305. }
  306. BOOL
  307. WriteData(
  308. IN HANDLE Handle,
  309. IN PVOID Data,
  310. IN DWORD DataSize
  311. )
  312. {
  313. BOOL rc;
  314. DWORD bw;
  315. if(!(rc = WriteFile(Handle,Data,DataSize,&bw,NULL))) {
  316. SetErrorText(IDS_ERROR_WRITE);
  317. }
  318. return(rc);
  319. }