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.

340 lines
7.7 KiB

  1. /****************************************************************************
  2. *
  3. * resetusr.cpp
  4. *
  5. * Dev applet to change the default speech user
  6. *
  7. * Owner: cthrash
  8. * Copyright (c) 1999 Microsoft Corporation All Rights Reserved.
  9. *
  10. *****************************************************************************/
  11. #include "stdafx.h"
  12. #include "resetusr.h"
  13. /**********************************************************************
  14. * main *
  15. *------*
  16. *
  17. * Description:
  18. *
  19. * Main entry point.
  20. *
  21. * Return:
  22. *
  23. * S_OK, E_INVALIDARG
  24. *
  25. ************************************************************* cthrash */
  26. BOOL g_fVerbose = FALSE;
  27. int APIENTRY
  28. WinMain(
  29. HINSTANCE hInstance,
  30. HINSTANCE hPrevInstance,
  31. LPSTR lpCmdLine,
  32. int nCmdShow)
  33. {
  34. char * pszUserName;
  35. BOOL fReset = ParseCmdLine(lpCmdLine, &pszUserName);
  36. HRESULT hr;
  37. if (fReset)
  38. {
  39. hr = CoInitialize(NULL);
  40. if (SUCCEEDED(hr))
  41. {
  42. hr = ResetUser(pszUserName);
  43. CoUninitialize();
  44. }
  45. }
  46. else
  47. {
  48. hr = Report("Usage:\tresetusr [-v] [user-name]\n"
  49. "\tresetusr [-v] -default\n"
  50. "\tresetusr -?\n",
  51. E_INVALIDARG);
  52. }
  53. return (int)hr;
  54. }
  55. /**********************************************************************
  56. * ParseCmdLine *
  57. *--------------*
  58. *
  59. * Description:
  60. *
  61. * Parse the command line. Argument can be a name, or the string
  62. * -default.
  63. *
  64. * Return:
  65. *
  66. * TRUE -- delete the user specified,
  67. * FALSE -- show usage info
  68. *
  69. ************************************************************* cthrash */
  70. BOOL
  71. ParseCmdLine(
  72. char * pszCmdLine, // [in] Command line arguments
  73. char ** ppszUserName) // [out]
  74. {
  75. BOOL fReset = FALSE;
  76. while (*pszCmdLine)
  77. {
  78. if (0 == strnicmp(pszCmdLine, "-v", 2))
  79. {
  80. g_fVerbose = TRUE;
  81. }
  82. else
  83. {
  84. if (0 == strnicmp(pszCmdLine, "-default", 8))
  85. {
  86. *ppszUserName = NULL;
  87. fReset = TRUE;
  88. }
  89. else if (0 != strnicmp(pszCmdLine, "-?", 2))
  90. {
  91. *ppszUserName = pszCmdLine;
  92. fReset = TRUE;
  93. }
  94. else
  95. {
  96. fReset = FALSE;
  97. }
  98. break;
  99. }
  100. for (pszCmdLine += 2;isspace((unsigned)(unsigned char)*pszCmdLine); pszCmdLine++);
  101. }
  102. return fReset;
  103. }
  104. /*****************************************************************************
  105. * ResetUser *
  106. *-----------*
  107. *
  108. * Description: Reset a user's AM state.
  109. *
  110. * Return: HRESULT
  111. *
  112. ***************************************************************** cthrash ***/
  113. HRESULT
  114. ResetUser(
  115. char * pszName) // [in] Name; NULL implies the default user
  116. {
  117. HRESULT hr, hrReturn;
  118. CComPtr<ISpResourceManager> cpResMgr;
  119. CComPtr<ISpObjectToken> cpEngineToken;
  120. CComPtr<ISpObjectToken> cpUserToken;
  121. CComPtr<ISpDataKey> cpDataKey;
  122. CComPtr<ISpDataKey> cpSubDataKey;
  123. CSpDynamicString dstrEngineGUID;
  124. CSpDynamicString dstrReport;
  125. hr = cpResMgr.CoCreateInstance(CLSID_SpResourceManager);
  126. if (SUCCEEDED(hr))
  127. {
  128. // Should we provide a mechanism to pick engine? Currently we pick the default.
  129. hr = cpResMgr->GetObjectToken(SPCAT_RECOGNIZERS, &cpEngineToken);
  130. }
  131. if (SUCCEEDED(hr))
  132. {
  133. hr = cpEngineToken->GetID(&dstrEngineGUID);
  134. }
  135. if (SUCCEEDED(hr))
  136. {
  137. const WCHAR * pch = wcsrchr(dstrEngineGUID, L'\\');
  138. if (pch)
  139. {
  140. pch++;
  141. memmove((WCHAR *)dstrEngineGUID, pch, sizeof(WCHAR) * (1 + wcslen(pch)));
  142. }
  143. }
  144. // Get the user token;
  145. if (!pszName)
  146. {
  147. if (SUCCEEDED(hr))
  148. {
  149. hr = cpResMgr->GetObjectToken(SPCAT_SPEECHUSER, &cpUserToken);
  150. }
  151. }
  152. else
  153. {
  154. BOOL fFoundMatch = FALSE;
  155. CComPtr<IEnumSpObjectTokens> cpEnum;
  156. ULONG celtFetched;
  157. CSpDynamicString dstrName = pszName;
  158. if (SUCCEEDED(hr))
  159. {
  160. hr = cpResMgr->EnumTokens(SPCAT_SPEECHUSER, NULL, NULL, &cpEnum);
  161. }
  162. if(hr == S_FALSE)
  163. {
  164. hr = SPERR_NOT_FOUND;
  165. }
  166. if (SUCCEEDED(hr))
  167. {
  168. hr = cpEnum->GetCount(&celtFetched);
  169. }
  170. while (!fFoundMatch && SUCCEEDED(hr))
  171. {
  172. ISpRegistryObjectToken *pRegToken = 0;
  173. hr = cpEnum->Next(1, (ISpObjectToken**)&pRegToken, &celtFetched);
  174. if (hr != S_OK)
  175. {
  176. break;
  177. }
  178. if (SUCCEEDED(hr))
  179. {
  180. CSpDynamicString dstrNameT;
  181. hr = SpGetDescription(pRegToken, &dstrNameT);
  182. fFoundMatch = 0 == wcsicmp(dstrName, dstrNameT);
  183. }
  184. if (fFoundMatch)
  185. {
  186. cpUserToken = pRegToken;
  187. }
  188. if (pRegToken)
  189. {
  190. pRegToken->Release();
  191. }
  192. }
  193. }
  194. hrReturn = hr;
  195. if (SUCCEEDED(hr))
  196. {
  197. hr = cpUserToken->OpenKey(dstrEngineGUID, &cpDataKey);
  198. hrReturn = (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) ? S_OK : hr;
  199. }
  200. if (SUCCEEDED(hr))
  201. {
  202. hr = cpDataKey->OpenKey(L"files", &cpSubDataKey);
  203. hrReturn = (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) ? S_OK : hr;
  204. }
  205. // Nuke all the files first.
  206. if (SUCCEEDED(hr))
  207. {
  208. ULONG iKey;
  209. for (iKey = 0; hr == S_OK; iKey++)
  210. {
  211. CSpDynamicString dstrFileType;
  212. CSpDynamicString dstrFilePath;
  213. hr = cpSubDataKey->EnumValues(iKey, &dstrFileType);
  214. if (SUCCEEDED(hr))
  215. {
  216. hr = cpSubDataKey->GetStringValue(dstrFileType, &dstrFilePath);
  217. }
  218. if (SUCCEEDED(hr))
  219. {
  220. USES_CONVERSION;
  221. hr = DeleteFile(W2T(dstrFilePath)) ? S_OK : HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  222. if (g_fVerbose)
  223. {
  224. dstrReport.Append(L"Deleting ");
  225. dstrReport.Append2(dstrFilePath, SUCCEEDED(hr) ? L" -- Success\n" : L" -- Fail\n");
  226. }
  227. }
  228. }
  229. hrReturn = hr = (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr) ? S_OK : hr;
  230. }
  231. // Nuke the files key
  232. if (SUCCEEDED(hr))
  233. {
  234. cpSubDataKey.Release();
  235. hr = cpDataKey->DeleteKey(L"files");
  236. if (g_fVerbose)
  237. {
  238. CSpDynamicString dstrID;
  239. cpUserToken->GetID(&dstrID);
  240. dstrReport.Append2(L"Deleting Key ", dstrID);
  241. dstrReport.Append2(L"\\", dstrEngineGUID);
  242. dstrReport.Append2(L"\\Files", SUCCEEDED(hr) ? L" -- Success\n" : L" -- Fail\n");
  243. }
  244. hrReturn = hr;
  245. }
  246. if (FAILED(hrReturn))
  247. {
  248. //Report("DataCouldn't find an appropriate user", E_INVALIDARG);
  249. }
  250. else if (g_fVerbose && dstrReport)
  251. {
  252. USES_CONVERSION;
  253. Report(W2A(dstrReport), hr);
  254. }
  255. return hrReturn;
  256. }
  257. /**********************************************************************
  258. * Report *
  259. *--------*
  260. *
  261. * Description:
  262. *
  263. * Show a message box, possibly indicating an error.
  264. *
  265. * Return:
  266. *
  267. * The HRESULT passed in is returned, for the convenience of
  268. * the caller.
  269. *
  270. ************************************************************* cthrash */
  271. HRESULT Report(char * lpMsg, HRESULT hr)
  272. {
  273. if (hr != S_OK || g_fVerbose)
  274. {
  275. const UINT uType = MB_OK | (FAILED(hr) ? MB_ICONERROR : MB_ICONINFORMATION);
  276. MessageBox(HWND_DESKTOP, lpMsg, "resetusr.exe", uType);
  277. }
  278. return hr;
  279. }