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.

339 lines
7.4 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: util.cpp
  4. //
  5. // Module: CMDL32.EXE
  6. //
  7. // Synopsis: Utility routines specific to CMDL
  8. //
  9. // Copyright (c) 1996-1998 Microsoft Corporation
  10. //
  11. // Author: nickball Created 4/8/98
  12. //
  13. //+----------------------------------------------------------------------------
  14. #include "cmmaster.h"
  15. //
  16. // Definitions
  17. //
  18. #define MAX_CMD_ARGS 15
  19. typedef enum _CMDLN_STATE
  20. {
  21. CS_END_SPACE, // done handling a space
  22. CS_BEGIN_QUOTE, // we've encountered a begin quote
  23. CS_END_QUOTE, // we've encountered a end quote
  24. CS_CHAR, // we're scanning chars
  25. CS_DONE
  26. } CMDLN_STATE;
  27. //
  28. // Helper function to determine if a file open error
  29. // is due to the fact that a file doesn't exist
  30. //
  31. BOOL IsErrorForUnique(DWORD dwErrCode, LPSTR lpszFile)
  32. {
  33. if (!lpszFile)
  34. {
  35. MYDBGASSERT(lpszFile);
  36. return TRUE;
  37. }
  38. // If the file exists, return false, its not a unique file error
  39. switch (dwErrCode)
  40. {
  41. case ERROR_FILE_EXISTS:
  42. case ERROR_ACCESS_DENIED:
  43. case ERROR_ALREADY_EXISTS:
  44. return (FALSE);
  45. default:
  46. break;
  47. }
  48. return (TRUE);
  49. }
  50. //
  51. // Helper function to retrieve the version number from the version file
  52. //
  53. LPTSTR GetVersionFromFile(LPSTR lpszFile)
  54. {
  55. MYDBGASSERT(lpszFile);
  56. LPTSTR pszVerNew = NULL;
  57. if (NULL == lpszFile)
  58. {
  59. return NULL;
  60. }
  61. //
  62. // We simply read the version file contents to get the version number
  63. //
  64. HANDLE hFileSrc = CreateFile(lpszFile,
  65. GENERIC_READ,
  66. FILE_SHARE_READ,
  67. NULL,
  68. OPEN_EXISTING,
  69. FILE_ATTRIBUTE_NORMAL,
  70. NULL);
  71. MYDBGTST(hFileSrc == INVALID_HANDLE_VALUE,("GetVersionFromFile() CreateFile() failed - %s.", lpszFile));
  72. if (hFileSrc != INVALID_HANDLE_VALUE)
  73. {
  74. DWORD dwSize = GetFileSize(hFileSrc, NULL);
  75. MYDBGTST(dwSize >= 0x7FFF,("GetVersionFromFile() Version file is too large - %s.", lpszFile));
  76. if (dwSize < 0x7FFF)
  77. {
  78. // Read in contennts
  79. DWORD dwBytesIn;
  80. pszVerNew = (LPTSTR) CmMalloc(dwSize);
  81. if (pszVerNew)
  82. {
  83. // Read entire file contents into buffer
  84. int nRead = ReadFile(hFileSrc, pszVerNew, dwSize, &dwBytesIn, NULL);
  85. MYDBGTST(!nRead,("GetVersionFromFile() ReadFile() failed - %s.",lpszFile));
  86. if (nRead)
  87. {
  88. // Make sure that the ver string is properly truncated
  89. LPTSTR pszTmp = pszVerNew;
  90. while (*pszTmp)
  91. {
  92. // Truncate the version string to the first tab, newline, or carriage return.
  93. if (*pszTmp == '\t' || *pszTmp == '\n' || *pszTmp == '\r')
  94. {
  95. *pszTmp = 0;
  96. break;
  97. }
  98. pszTmp++;
  99. }
  100. }
  101. }
  102. MYDBGTST(!pszVerNew,("GetVersionFromFile() CmMalloc(%u) failed.",dwSize));
  103. }
  104. CloseHandle(hFileSrc);
  105. }
  106. return pszVerNew;
  107. }
  108. //
  109. // Helper function to create a temp directory. Note that we
  110. // expect pszDir to be at least MAX_PATH + 1.
  111. //
  112. BOOL CreateTempDir(LPTSTR pszDir)
  113. {
  114. TCHAR szTmp[MAX_PATH+1];
  115. BOOL bRes = FALSE;
  116. if (pszDir)
  117. {
  118. UINT uReturn = GetTempFileName(TEXT("."), TEXT("000"), 0, szTmp);
  119. if (0 == uReturn)
  120. {
  121. DWORD dwError = GetLastError();
  122. MYDBG(("CreateTempDir() GetTempFileName failed, GLE=%u.", dwError));
  123. }
  124. else
  125. {
  126. MYVERIFY(DeleteFile(szTmp));
  127. bRes = CreateDirectory(szTmp, NULL);
  128. if (!bRes)
  129. {
  130. MYDBG(("CreateTempDir() CreateDirectory() failed, GLE=%u.",GetLastError()));
  131. }
  132. else
  133. {
  134. lstrcpy(pszDir, szTmp);
  135. }
  136. }
  137. }
  138. return bRes;
  139. }
  140. //
  141. // Get the last character(DBCS-enabled)
  142. //
  143. TCHAR GetLastChar(LPTSTR pszStr)
  144. {
  145. LPTSTR pszPrev;
  146. if (!pszStr)
  147. {
  148. return 0;
  149. }
  150. pszPrev = pszStr;
  151. while (*pszStr)
  152. {
  153. pszPrev = pszStr;
  154. pszStr = CharNext(pszStr);
  155. }
  156. return *pszPrev;
  157. }
  158. //+----------------------------------------------------------------------------
  159. //
  160. // Function: GetCmArgV
  161. //
  162. // Synopsis: Simulates ArgV using GetCommandLine
  163. //
  164. // Arguments: LPTSTR pszCmdLine - Ptr to a copy of the command line to be processed
  165. //
  166. // Returns: LPTSTR * - Ptr to a ptr array containing the arguments. Caller is
  167. // responsible for releasing memory.
  168. //
  169. // History: nickball Created 4/9/98
  170. //
  171. //+----------------------------------------------------------------------------
  172. LPTSTR *GetCmArgV(LPTSTR pszCmdLine)
  173. {
  174. MYDBGASSERT(pszCmdLine);
  175. if (NULL == pszCmdLine || NULL == pszCmdLine[0])
  176. {
  177. return NULL;
  178. }
  179. //
  180. // Allocate Ptr array, up to MAX_CMD_ARGS ptrs
  181. //
  182. LPTSTR *ppCmArgV = (LPTSTR *) CmMalloc(sizeof(LPTSTR) * MAX_CMD_ARGS);
  183. if (NULL == ppCmArgV)
  184. {
  185. return NULL;
  186. }
  187. //
  188. // Declare locals
  189. //
  190. LPTSTR pszCurr;
  191. LPTSTR pszNext;
  192. LPTSTR pszToken;
  193. CMDLN_STATE state;
  194. state = CS_CHAR;
  195. int ndx = 0;
  196. //
  197. // Parse out pszCmdLine and store pointers in ppCmArgV
  198. //
  199. pszCurr = pszToken = pszCmdLine;
  200. do
  201. {
  202. switch (*pszCurr)
  203. {
  204. case TEXT(' '):
  205. if (state == CS_CHAR)
  206. {
  207. //
  208. // We found a token
  209. //
  210. pszNext = CharNext(pszCurr);
  211. *pszCurr = TEXT('\0');
  212. ppCmArgV[ndx] = pszToken;
  213. ndx++;
  214. pszCurr = pszToken = pszNext;
  215. state = CS_END_SPACE;
  216. continue;
  217. }
  218. else
  219. {
  220. if (state == CS_END_SPACE || state == CS_END_QUOTE)
  221. {
  222. pszToken = CharNext(pszToken);
  223. }
  224. }
  225. break;
  226. case TEXT('\"'):
  227. if (state == CS_BEGIN_QUOTE)
  228. {
  229. //
  230. // We found a token
  231. //
  232. pszNext = CharNext(pszCurr);
  233. *pszCurr = TEXT('\0');
  234. //
  235. // skip the opening quote
  236. //
  237. pszToken = CharNext(pszToken);
  238. ppCmArgV[ndx] = pszToken;
  239. ndx++;
  240. pszCurr = pszToken = pszNext;
  241. state = CS_END_QUOTE;
  242. continue;
  243. }
  244. else
  245. {
  246. state = CS_BEGIN_QUOTE;
  247. }
  248. break;
  249. case TEXT('\0'):
  250. if (state != CS_END_QUOTE)
  251. {
  252. //
  253. // End of the line, set last token
  254. //
  255. ppCmArgV[ndx] = pszToken;
  256. }
  257. state = CS_DONE;
  258. break;
  259. default:
  260. if (state == CS_END_SPACE || state == CS_END_QUOTE)
  261. {
  262. state = CS_CHAR;
  263. }
  264. break;
  265. }
  266. pszCurr = CharNext(pszCurr);
  267. } while (state != CS_DONE);
  268. return ppCmArgV;
  269. }