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.

434 lines
13 KiB

  1. //
  2. // Profwiz.cpp doesn't use cmutoa but does include this function. Thus we want the W versions instead of the
  3. // U versions for profwiz.
  4. //
  5. #ifndef _CMUTOA
  6. #define CharNextU CharNextW
  7. #define CharPrevU CharPrevW
  8. #define lstrlenU lstrlenW
  9. #define lstrcpyU lstrcpyW
  10. #define lstrcpynU lstrcpynW
  11. #endif
  12. /*
  13. //+----------------------------------------------------------------------------
  14. //
  15. // Function: HrParseCustomActionString
  16. //
  17. // Synopsis: This function takes a custom action string retrieved from a
  18. // cms file and parses it into the various parts of a custom
  19. // action (program, parameters, function name)
  20. //
  21. // Arguments: LPTSTR pszStringToParse - custom action buffer to be parsed into
  22. // the various parts of a custom action
  23. // LPTSTR pszProgram - output buffer to hold the program string
  24. // LPTSTR pszParameters - output buffer to hold the parameters string
  25. // LPTSTR pszFunctionName - output buffer to hold the function name, if any
  26. //
  27. // Returns: HRESULT - standard COM error codes
  28. //
  29. // History: quintinb Created Header 02/26/00
  30. //
  31. //+----------------------------------------------------------------------------
  32. HRESULT HrParseCustomActionString(LPTSTR pszStringToParse, LPTSTR pszProgram, LPTSTR pszParameters, LPTSTR pszFunctionName)
  33. {
  34. if ((NULL == pszStringToParse) || (TEXT('\0') == pszStringToParse[0]) || (NULL == pszProgram) ||
  35. (NULL == pszParameters) || (NULL == pszFunctionName))
  36. {
  37. return E_INVALIDARG;
  38. }
  39. //
  40. // Make sure the strings are blank in case we don't touch them (szFunctionName and szParameters especially)
  41. //
  42. pszProgram[0] = TEXT('\0');
  43. pszParameters[0] = TEXT('\0');
  44. pszFunctionName[0] = TEXT('\0');
  45. //
  46. // Here are the cases we need to handle:
  47. // 1) +longfilename+
  48. // 2) +longfilename+ params
  49. // 3) +longfilename+,dllfuncname
  50. // 4) +longfilename+,dllfuncname params
  51. // 5) filename
  52. // 6) filename params
  53. // 7) filename,dllfuncname
  54. // 8) filename,dllfuncname params
  55. //
  56. // Walk the string to find the seperator chars
  57. //
  58. LPTSTR pszCurrent = pszStringToParse;
  59. LPTSTR pszFirstPlus = NULL;
  60. LPTSTR pszSecondPlus = NULL;
  61. LPTSTR pszFirstSpace = NULL;
  62. LPTSTR pszFirstComma = NULL;
  63. while (pszCurrent && (TEXT('\0') != *pszCurrent))
  64. {
  65. if ((TEXT('+') == *pszCurrent) && (NULL == pszFirstComma) && (NULL == pszFirstSpace))
  66. {
  67. //
  68. // Keep track of the plus signs, unless we have already seen a space
  69. // or a comma. In which case these chars are in the parameters and
  70. // meaningless to us.
  71. //
  72. if (NULL == pszFirstPlus)
  73. {
  74. pszFirstPlus = pszCurrent;
  75. }
  76. else if (NULL == pszSecondPlus)
  77. {
  78. pszSecondPlus = pszCurrent;
  79. }
  80. }
  81. else if ((TEXT(',') == *pszCurrent) && (NULL == pszFirstSpace))
  82. {
  83. //
  84. // If we have already seen a space, then the comma is part of
  85. // the parameters and meaningless to us.
  86. //
  87. pszFirstComma = pszCurrent;
  88. }
  89. else if ((TEXT(' ') == *pszCurrent))
  90. {
  91. if ((NULL == pszFirstPlus) && (NULL == pszFirstSpace))
  92. {
  93. //
  94. // Then we have no plus signs and no previous space, save the space as
  95. // it is the start of the parameters.
  96. //
  97. pszFirstSpace = pszCurrent;
  98. }
  99. else if (pszFirstPlus && pszSecondPlus && (NULL == pszFirstSpace))
  100. {
  101. //
  102. // Then we have both plus signs but no space yet, grab it
  103. // because this is the start of the parameters
  104. //
  105. pszFirstSpace = pszCurrent;
  106. }
  107. }
  108. pszCurrent = CharNextU(pszCurrent);
  109. }
  110. //
  111. // From the markers we have, figure out the beginning and end of the program string
  112. //
  113. LPTSTR pszStartOfProgram = NULL;
  114. LPTSTR pszEndOfProgram = NULL;
  115. if (pszFirstPlus)
  116. {
  117. if (pszSecondPlus)
  118. {
  119. pszStartOfProgram = CharNextU(pszFirstPlus);
  120. pszEndOfProgram = CharPrevU(pszStringToParse, pszSecondPlus);
  121. }
  122. else
  123. {
  124. //
  125. // We have a string with the first char as a plus sign but no second +.
  126. // The format isn't correct.
  127. //
  128. CMASSERTMSG(FALSE, TEXT("CustomActionList::ParseCustomActionString - Incorrect format in the passed in string to parse, missing + sign."));
  129. return E_UNEXPECTED;
  130. }
  131. }
  132. else
  133. {
  134. pszStartOfProgram = pszStringToParse;
  135. if (pszFirstComma)
  136. {
  137. pszEndOfProgram = CharPrevU(pszStringToParse, pszFirstComma);
  138. }
  139. else if (pszFirstSpace)
  140. {
  141. pszEndOfProgram = CharPrevU(pszStringToParse, pszFirstSpace);
  142. }
  143. else
  144. {
  145. //
  146. // Nothing in the string but the program
  147. //
  148. pszEndOfProgram = pszStringToParse + lstrlenU(pszStringToParse) - 1;
  149. }
  150. }
  151. //
  152. // Now copy out the necessary parts
  153. //
  154. int iSize = (int)(pszEndOfProgram - pszStartOfProgram + 2);
  155. lstrcpynU(pszProgram, pszStartOfProgram, iSize);
  156. if (pszFirstComma)
  157. {
  158. if (pszFirstSpace)
  159. {
  160. iSize = (int)(pszFirstSpace - pszFirstComma);
  161. lstrcpynU(pszFunctionName, CharNextU(pszFirstComma), iSize);
  162. }
  163. else
  164. {
  165. lstrcpyU(pszFunctionName, CharNextU(pszFirstComma));
  166. }
  167. }
  168. if (pszFirstSpace)
  169. {
  170. lstrcpyU(pszParameters, CharNextU(pszFirstSpace));
  171. }
  172. return S_OK;
  173. }
  174. */
  175. //+----------------------------------------------------------------------------
  176. //
  177. // Function: HrParseCustomActionString
  178. //
  179. // Synopsis: This function takes a custom action string retrieved from a
  180. // cms file and parses it into the various parts of a custom
  181. // action (program, parameters, function name)
  182. //
  183. // Arguments: LPTSTR pszStringToParse - custom action buffer to be parsed into
  184. // the various parts of a custom action
  185. // LPTSTR pszProgram - output buffer to hold the program string
  186. // LPTSTR pszParameters - output buffer to hold the parameters string
  187. // LPTSTR pszFunctionName - output buffer to hold the function name, if any
  188. //
  189. // Returns: HRESULT - standard COM error codes
  190. //
  191. // History: quintinb Created Header 02/26/00
  192. //
  193. //+----------------------------------------------------------------------------
  194. HRESULT HrParseCustomActionString(LPTSTR pszStringToParse, LPTSTR* ppszProgram, LPTSTR* ppszParameters, LPTSTR* ppszFunctionName)
  195. {
  196. if ((NULL == pszStringToParse) || (TEXT('\0') == pszStringToParse[0]) || (NULL == ppszProgram) ||
  197. (NULL == ppszParameters) || (NULL == ppszFunctionName))
  198. {
  199. return E_INVALIDARG;
  200. }
  201. //
  202. // NULL out the string pointers to start with
  203. //
  204. *ppszProgram = NULL;
  205. *ppszParameters = NULL;
  206. *ppszFunctionName = NULL;
  207. //
  208. // Here are the cases we need to handle:
  209. // 1) +longfilename+
  210. // 2) +longfilename+ params
  211. // 3) +longfilename+,dllfuncname
  212. // 4) +longfilename+,dllfuncname params
  213. // 5) filename
  214. // 6) filename params
  215. // 7) filename,dllfuncname
  216. // 8) filename,dllfuncname params
  217. //
  218. // Walk the string to find the seperator chars
  219. //
  220. LPTSTR pszCurrent = pszStringToParse;
  221. LPTSTR pszFirstPlus = NULL;
  222. LPTSTR pszSecondPlus = NULL;
  223. LPTSTR pszFirstSpace = NULL;
  224. LPTSTR pszFirstComma = NULL;
  225. while (pszCurrent && (TEXT('\0') != *pszCurrent))
  226. {
  227. if ((TEXT('+') == *pszCurrent) && (NULL == pszFirstComma) && (NULL == pszFirstSpace))
  228. {
  229. //
  230. // Keep track of the plus signs, unless we have already seen a space
  231. // or a comma. In which case these chars are in the parameters and
  232. // meaningless to us.
  233. //
  234. if (NULL == pszFirstPlus)
  235. {
  236. pszFirstPlus = pszCurrent;
  237. }
  238. else if (NULL == pszSecondPlus)
  239. {
  240. pszSecondPlus = pszCurrent;
  241. }
  242. }
  243. else if ((TEXT(',') == *pszCurrent) && (NULL == pszFirstSpace))
  244. {
  245. //
  246. // If we have already seen a space, then the comma is part of
  247. // the parameters and meaningless to us.
  248. //
  249. pszFirstComma = pszCurrent;
  250. }
  251. else if ((TEXT(' ') == *pszCurrent))
  252. {
  253. if ((NULL == pszFirstPlus) && (NULL == pszFirstSpace))
  254. {
  255. //
  256. // Then we have no plus signs and no previous space, save the space as
  257. // it is the start of the parameters.
  258. //
  259. pszFirstSpace = pszCurrent;
  260. }
  261. else if (pszFirstPlus && pszSecondPlus && (NULL == pszFirstSpace))
  262. {
  263. //
  264. // Then we have both plus signs but no space yet, grab it
  265. // because this is the start of the parameters
  266. //
  267. pszFirstSpace = pszCurrent;
  268. }
  269. }
  270. pszCurrent = CharNextU(pszCurrent);
  271. }
  272. //
  273. // From the markers we have, figure out the beginning and end of the program string
  274. //
  275. LPTSTR pszStartOfProgram = NULL;
  276. LPTSTR pszEndOfProgram = NULL;
  277. if (pszFirstPlus)
  278. {
  279. if (pszSecondPlus)
  280. {
  281. pszStartOfProgram = CharNextU(pszFirstPlus);
  282. pszEndOfProgram = CharPrevU(pszStringToParse, pszSecondPlus);
  283. }
  284. else
  285. {
  286. //
  287. // We have a string with the first char as a plus sign but no second +.
  288. // The format isn't correct.
  289. //
  290. CMASSERTMSG(FALSE, TEXT("CustomActionList::ParseCustomActionString - Incorrect format in the passed in string to parse, missing + sign."));
  291. return E_UNEXPECTED;
  292. }
  293. }
  294. else
  295. {
  296. pszStartOfProgram = pszStringToParse;
  297. if (pszFirstComma)
  298. {
  299. pszEndOfProgram = CharPrevU(pszStringToParse, pszFirstComma);
  300. }
  301. else if (pszFirstSpace)
  302. {
  303. pszEndOfProgram = CharPrevU(pszStringToParse, pszFirstSpace);
  304. }
  305. else
  306. {
  307. //
  308. // Nothing in the string but the program
  309. //
  310. pszEndOfProgram = pszStringToParse + lstrlenU(pszStringToParse) - 1;
  311. }
  312. }
  313. //
  314. // Now copy out the necessary parts
  315. //
  316. HRESULT hr = E_OUTOFMEMORY;
  317. int iSize = (int)(pszEndOfProgram - pszStartOfProgram + 2);
  318. *ppszProgram = (LPTSTR)CmMalloc(sizeof(TCHAR)*iSize);
  319. if (*ppszProgram)
  320. {
  321. lstrcpynU(*ppszProgram, pszStartOfProgram, iSize);
  322. if (pszFirstComma)
  323. {
  324. if (pszFirstSpace)
  325. {
  326. iSize = (int)(pszFirstSpace - pszFirstComma);
  327. *ppszFunctionName = (LPTSTR)CmMalloc(sizeof(TCHAR)*iSize);
  328. if (*ppszFunctionName)
  329. {
  330. lstrcpynU(*ppszFunctionName, CharNextU(pszFirstComma), iSize);
  331. }
  332. else
  333. {
  334. goto exit;
  335. }
  336. }
  337. else
  338. {
  339. iSize = lstrlen(CharNextU(pszFirstComma)) + 1;
  340. *ppszFunctionName = (LPTSTR)CmMalloc(sizeof(TCHAR)*iSize);
  341. if (*ppszFunctionName)
  342. {
  343. lstrcpyU(*ppszFunctionName, CharNextU(pszFirstComma));
  344. }
  345. else
  346. {
  347. goto exit;
  348. }
  349. }
  350. }
  351. else
  352. {
  353. *ppszFunctionName = CmStrCpyAlloc(TEXT(""));
  354. }
  355. if (pszFirstSpace)
  356. {
  357. iSize = lstrlen(CharNextU(pszFirstSpace)) + 1;
  358. *ppszParameters = (LPTSTR)CmMalloc(sizeof(TCHAR)*iSize);
  359. if (*ppszParameters)
  360. {
  361. lstrcpyU(*ppszParameters, CharNextU(pszFirstSpace));
  362. }
  363. else
  364. {
  365. goto exit;
  366. }
  367. }
  368. else
  369. {
  370. *ppszParameters = CmStrCpyAlloc(TEXT(""));
  371. }
  372. if (*ppszParameters && *ppszFunctionName && *ppszProgram)
  373. {
  374. hr = S_OK;
  375. }
  376. }
  377. else
  378. {
  379. goto exit;
  380. }
  381. exit:
  382. MYDBGASSERT(SUCCEEDED(hr));
  383. if (FAILED(hr))
  384. {
  385. CMTRACE1(TEXT("HrParseCustomActionString failed, hr = 0x%x"), hr);
  386. CmFree(*ppszFunctionName);
  387. CmFree(*ppszProgram);
  388. CmFree(*ppszParameters);
  389. *ppszProgram = NULL;
  390. *ppszParameters = NULL;
  391. *ppszFunctionName = NULL;
  392. }
  393. return hr;
  394. }