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.

385 lines
10 KiB

  1. /*++
  2. Copyright (c) 1993-1994 Microsoft Corporation
  3. Module Name:
  4. initodat.c
  5. Abstract:
  6. Routines for converting Perf???.ini to Perf???.dat files.
  7. Author:
  8. HonWah Chan (a-honwah) October, 1993
  9. Revision History:
  10. --*/
  11. #include "initodat.h"
  12. #include "strids.h"
  13. #include "common.h"
  14. #include "tchar.h"
  15. #define ALLOCMEM(x) HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, (DWORD)(x))
  16. #define FREEMEM(x) HeapFree (GetProcessHeap(), 0, (LPVOID)(x))
  17. BOOL
  18. MakeUpgradeFilename (
  19. LPCTSTR szDataFileName,
  20. LPTSTR szUpgradeFileName
  21. )
  22. {
  23. BOOL bReturn = FALSE;
  24. // note: assumes szUpgradeFileName buffer is large enough for result
  25. TCHAR szDrive[_MAX_DRIVE];
  26. TCHAR szDir[_MAX_DIR];
  27. TCHAR szFileName[_MAX_FNAME];
  28. TCHAR szExt[_MAX_EXT];
  29. _tsplitpath(szDataFileName,
  30. (LPTSTR)szDrive,
  31. (LPTSTR)szDir,
  32. (LPTSTR)szFileName,
  33. (LPTSTR)szExt);
  34. // see if the filename fits the "PERF[C|H]XXX" format
  35. if (((szFileName[4] == TEXT('C')) || (szFileName[4] == TEXT('H'))) ||
  36. ((szFileName[4] == TEXT('c')) || (szFileName[4] == TEXT('h')))) {
  37. // then it's the correct format so change the 4th letter up 1 letter
  38. szFileName[4] += 1;
  39. // and make a new path
  40. _tmakepath (szUpgradeFileName,
  41. (LPCTSTR)szDrive,
  42. (LPCTSTR)szDir,
  43. (LPCTSTR)szFileName,
  44. (LPCTSTR)szExt);
  45. bReturn = TRUE;
  46. } else {
  47. // bogus name so return false
  48. }
  49. return bReturn;
  50. }
  51. BOOL
  52. GetFilesFromCommandLine (
  53. IN LPTSTR lpCommandLine,
  54. #ifdef FE_SB
  55. OUT UINT *puCodePage,
  56. #endif
  57. OUT LPTSTR *lpFileNameI,
  58. OUT LPTSTR *lpFileNameD
  59. )
  60. /*++
  61. GetFilesFromCommandLine
  62. parses the command line to retrieve the ini filename that should be
  63. the first and only argument.
  64. Arguments
  65. lpCommandLine pointer to command line (returned by GetCommandLine)
  66. lpFileNameI pointer to buffer that will receive address of the
  67. validated input filename entered on the command line
  68. lpFileNameD pointer to buffer that will receive address of the
  69. optional output filename entered on the command line
  70. Return Value
  71. TRUE if a valid filename was returned
  72. FALSE if the filename is not valid or missing
  73. error is returned in GetLastError
  74. --*/
  75. {
  76. INT iNumArgs;
  77. HFILE hIniFile;
  78. OFSTRUCT ofIniFile;
  79. LPSTR lpIniFileName = NULL;
  80. LPTSTR lpExeName = NULL;
  81. LPTSTR lpIniName = NULL;
  82. // check for valid arguments
  83. if (lpCommandLine == NULL) return (FALSE);
  84. if (*lpFileNameI == NULL) return (FALSE);
  85. if (*lpFileNameD == NULL) return (FALSE);
  86. // allocate memory for parsing operation
  87. lpExeName = ALLOCMEM (FILE_NAME_BUFFER_SIZE * sizeof(TCHAR));
  88. lpIniName = ALLOCMEM (FILE_NAME_BUFFER_SIZE * sizeof(TCHAR));
  89. lpIniFileName = ALLOCMEM (FILE_NAME_BUFFER_SIZE);
  90. if ((lpExeName == NULL) ||
  91. (lpIniFileName == NULL) ||
  92. (lpIniName == NULL)) {
  93. if (lpExeName) FREEMEM (lpExeName);
  94. if (lpIniFileName) FREEMEM (lpIniFileName);
  95. if (lpIniName) FREEMEM (lpIniName);
  96. return FALSE;
  97. } else {
  98. // get strings from command line
  99. #ifdef FE_SB
  100. iNumArgs = _stscanf (lpCommandLine, (LPCTSTR)TEXT(" %s %d %s %s "), lpExeName, puCodePage, lpIniName, *lpFileNameD);
  101. #else
  102. iNumArgs = _stscanf (lpCommandLine, (LPCTSTR)TEXT(" %s %s %s "), lpExeName, lpIniName, *lpFileNameD);
  103. #endif
  104. #ifdef FE_SB
  105. if (iNumArgs < 3 || iNumArgs > 4) {
  106. #else
  107. if (iNumArgs < 2 || iNumArgs > 3) {
  108. #endif
  109. // wrong number of arguments
  110. FREEMEM (lpExeName);
  111. FREEMEM (lpIniFileName);
  112. FREEMEM (lpIniName);
  113. return FALSE;
  114. } else {
  115. // see if file specified exists
  116. // file name is always an ANSI buffer
  117. wcstombs (lpIniFileName, lpIniName, lstrlenW(lpIniName)+1);
  118. FREEMEM (lpIniName);
  119. FREEMEM (lpExeName);
  120. hIniFile = OpenFile (lpIniFileName,
  121. &ofIniFile,
  122. OF_PARSE);
  123. if (hIniFile != HFILE_ERROR) {
  124. hIniFile = OpenFile (lpIniFileName,
  125. &ofIniFile,
  126. OF_EXIST);
  127. if ((hIniFile && hIniFile != HFILE_ERROR) ||
  128. (GetLastError() == ERROR_FILE_EXISTS)) {
  129. // file exists, so return name and success
  130. // return full pathname if found
  131. mbstowcs (*lpFileNameI, ofIniFile.szPathName, lstrlenA(ofIniFile.szPathName)+1);
  132. FREEMEM (lpIniFileName);
  133. return TRUE;
  134. } else {
  135. // filename was on command line, but not valid so return
  136. // false, but send name back for error message
  137. mbstowcs (*lpFileNameI, lpIniFileName, lstrlenA(lpIniFileName)+1);
  138. FREEMEM (lpIniFileName);
  139. return FALSE;
  140. }
  141. } else {
  142. FREEMEM (lpIniFileName);
  143. return FALSE;
  144. }
  145. }
  146. }
  147. }
  148. BOOL VerifyIniData(
  149. IN PVOID pValueBuffer,
  150. IN ULONG ValueLength
  151. )
  152. /*++
  153. VerifyIniData
  154. This routine does some simple check to see if the ini file is good.
  155. Basically, it is looking for (ID, Text) and checking that ID is an
  156. integer. Mostly in case of missing comma or quote, the ID will be
  157. an invalid integer.
  158. --*/
  159. {
  160. INT iNumArg;
  161. INT TextID;
  162. LPTSTR lpID = NULL;
  163. LPTSTR lpText = NULL;
  164. LPTSTR lpLastID;
  165. LPTSTR lpLastText;
  166. LPTSTR lpInputBuffer = (LPTSTR) pValueBuffer;
  167. LPTSTR lpBeginBuffer = (LPTSTR) pValueBuffer;
  168. BOOL returnCode = TRUE;
  169. UINT NumOfID = 0;
  170. ULONG CurrentLength;
  171. #pragma warning ( disable : 4127 )
  172. while (TRUE) {
  173. // save up the last items for summary display later
  174. lpLastID = lpID;
  175. lpLastText = lpText;
  176. // increment to next ID and text location
  177. lpID = lpInputBuffer;
  178. CurrentLength = (ULONG)((PBYTE)lpID - (PBYTE)lpBeginBuffer + sizeof(WCHAR));
  179. if (CurrentLength >= ValueLength)
  180. break;
  181. try {
  182. lpText = lpID + lstrlen (lpID) + 1;
  183. lpInputBuffer = lpText + lstrlen (lpText) + 1;
  184. iNumArg = _stscanf (lpID, (LPCTSTR)TEXT("%d"), &TextID);
  185. }
  186. except (TRUE) {
  187. iNumArg = -1;
  188. }
  189. if (iNumArg != 1) {
  190. // bad ID
  191. returnCode = FALSE;
  192. break ;
  193. }
  194. NumOfID++;
  195. }
  196. #pragma warning ( default : 4127 )
  197. if (returnCode == FALSE) {
  198. DisplaySummaryError (lpLastID, lpLastText, NumOfID);
  199. }
  200. else {
  201. DisplaySummary (lpLastID, lpLastText, NumOfID);
  202. }
  203. return (returnCode);
  204. }
  205. __cdecl main(
  206. // int argc,
  207. // char *argv[]
  208. )
  209. /*++
  210. main
  211. Arguments
  212. ReturnValue
  213. 0 (ERROR_SUCCESS) if command was processed
  214. Non-Zero if command error was detected.
  215. --*/
  216. {
  217. LPTSTR lpCommandLine;
  218. LPTSTR lpIniFile;
  219. LPTSTR lpDatFile;
  220. UNICODE_STRING IniFileName;
  221. PVOID pValueBuffer;
  222. ULONG ValueLength;
  223. BOOL bStatus;
  224. NTSTATUS NtStatus;
  225. #if 0
  226. // part of bogus filename change code
  227. LPTSTR pchar ;
  228. INT npos;
  229. TCHAR ch = TEXT('f');
  230. #endif
  231. #ifdef FE_SB
  232. UINT uCodePage=CP_ACP;
  233. #endif
  234. lpIniFile = ALLOCMEM (MAX_PATH * sizeof (TCHAR));
  235. lpDatFile = ALLOCMEM (MAX_PATH * sizeof (TCHAR));
  236. if (lpIniFile == NULL) return ERROR_OUTOFMEMORY;
  237. if (lpDatFile == NULL) return ERROR_OUTOFMEMORY;
  238. lstrcpy(lpDatFile, (LPCTSTR)TEXT("\0"));
  239. lpCommandLine = GetCommandLine(); // get command line
  240. if (lpCommandLine == NULL) {
  241. NtStatus = GetLastError();
  242. FREEMEM (lpIniFile);
  243. FREEMEM (lpDatFile);
  244. return NtStatus;
  245. }
  246. // read command line to determine what to do
  247. #ifdef FE_SB // FE_SB
  248. if (GetFilesFromCommandLine (lpCommandLine, &uCodePage, &lpIniFile, &lpDatFile)) {
  249. if (!IsValidCodePage(uCodePage)) {
  250. uCodePage = CP_ACP;
  251. }
  252. #else
  253. if (GetFilesFromCommandLine (lpCommandLine, &lpIniFile, &lpDatFile)) {
  254. #endif // FE_SB
  255. // valid filename (i.e. ini file exists)
  256. IniFileName.Buffer = lpIniFile;
  257. IniFileName.MaximumLength =
  258. IniFileName.Length = (WORD)((lstrlen (lpIniFile) + 1 ) * sizeof(WCHAR)) ;
  259. #ifdef FE_SB
  260. bStatus = DatReadMultiSzFile (uCodePage, &IniFileName,
  261. #else
  262. bStatus = DatReadMultiSzFile (&IniFileName,
  263. #endif
  264. &pValueBuffer,
  265. &ValueLength);
  266. if (bStatus) {
  267. bStatus = VerifyIniData (pValueBuffer, ValueLength);
  268. if (bStatus) {
  269. bStatus = OutputIniData (&IniFileName,
  270. lpDatFile,
  271. pValueBuffer,
  272. ValueLength);
  273. #if 0
  274. // this is a really bogus way to find "PERF" in the
  275. // filename string
  276. //Add the new file that'll be used in upgrade
  277. // find the last "F" in the file name by reversing
  278. // the string, finding the first "F"
  279. // then go to the previous character and incrementing
  280. // it. Finally reverse the characters in the file name
  281. // returning it to the correct order.
  282. //
  283. // this creates the "upgrade" file with a slightly different
  284. // filename that is used by Lodctr to insert the new system
  285. // strings into the existing list of system strings.
  286. //
  287. _tcsrev(lpDatFile);
  288. pchar = _tcschr(lpDatFile,ch);
  289. npos = (INT)(pchar - lpDatFile) - 1;
  290. lpDatFile[npos] = (TCHAR)((lpDatFile[npos]) + 1);
  291. _tcsrev(lpDatFile);
  292. #else
  293. bStatus = MakeUpgradeFilename (
  294. lpDatFile, lpDatFile);
  295. #endif
  296. if (bStatus) {
  297. bStatus = OutputIniData (&IniFileName,
  298. lpDatFile,
  299. pValueBuffer,
  300. ValueLength);
  301. }
  302. }
  303. }
  304. } else {
  305. if (*lpIniFile) {
  306. printf (GetFormatResource(LC_NO_INIFILE), lpIniFile);
  307. } else {
  308. //Incorrect Command Format
  309. // display command line usage
  310. DisplayCommandHelp(LC_FIRST_CMD_HELP, LC_LAST_CMD_HELP);
  311. }
  312. }
  313. if (lpIniFile) FREEMEM (lpIniFile);
  314. if (lpDatFile) FREEMEM (lpDatFile);
  315. return (ERROR_SUCCESS); // success
  316. }