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.
 
 
 
 
 
 

332 lines
7.5 KiB

/****************************************************************************
*
* resetusr.cpp
*
* Dev applet to change the default speech user
*
* Owner: cthrash
* Copyright (c) 1999 Microsoft Corporation All Rights Reserved.
*
*****************************************************************************/
#include "stdafx.h"
#include "resetusr.h"
/**********************************************************************
* main *
*------*
*
* Description:
*
* Main entry point.
*
* Return:
*
* S_OK, E_INVALIDARG
*
************************************************************* cthrash */
BOOL g_fVerbose = FALSE;
int APIENTRY
WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
char * pszUserName;
BOOL fReset = ParseCmdLine(lpCmdLine, &pszUserName);
HRESULT hr;
if (fReset)
{
hr = CoInitialize(NULL);
if (SUCCEEDED(hr))
{
hr = ResetUser(pszUserName);
CoUninitialize();
}
}
else
{
hr = Report("Usage:\tresetusr [-v] [user-name]\n"
"\tresetusr [-v] -default\n"
"\tresetusr -?\n",
E_INVALIDARG);
}
return (int)hr;
}
/**********************************************************************
* ParseCmdLine *
*--------------*
*
* Description:
*
* Parse the command line. Argument can be a name, or the string
* -default.
*
* Return:
*
* TRUE -- delete the user specified,
* FALSE -- show usage info
*
************************************************************* cthrash */
BOOL
ParseCmdLine(
char * pszCmdLine, // [in] Command line arguments
char ** ppszUserName) // [out]
{
BOOL fReset = FALSE;
while (*pszCmdLine)
{
if (0 == strnicmp(pszCmdLine, "-v", 2))
{
g_fVerbose = TRUE;
}
else
{
if (0 == strnicmp(pszCmdLine, "-default", 8))
{
*ppszUserName = NULL;
fReset = TRUE;
}
else if (0 != strnicmp(pszCmdLine, "-?", 2))
{
*ppszUserName = pszCmdLine;
fReset = TRUE;
}
else
{
fReset = FALSE;
}
break;
}
for (pszCmdLine += 2;isspace((unsigned)(unsigned char)*pszCmdLine); pszCmdLine++);
}
return fReset;
}
/*****************************************************************************
* ResetUser *
*-----------*
*
* Description: Reset a user's AM state.
*
* Return: HRESULT
*
***************************************************************** cthrash ***/
HRESULT
ResetUser(
char * pszName) // [in] Name; NULL implies the default user
{
HRESULT hr, hrReturn;
CComPtr<ISpObjectToken> cpEngineToken;
CComPtr<ISpObjectToken> cpUserToken;
CComPtr<ISpDataKey> cpDataKey;
CComPtr<ISpDataKey> cpSubDataKey;
CSpDynamicString dstrEngineGUID;
CSpDynamicString dstrReport;
// Should we provide a mechanism to pick engine? Currently we pick the default.
hr = SpGetDefaultTokenFromCategoryId(SPCAT_RECOGNIZERS, &cpEngineToken);
if (SUCCEEDED(hr))
{
hr = cpEngineToken->GetId(&dstrEngineGUID);
}
if (SUCCEEDED(hr))
{
const WCHAR * pch = wcsrchr(dstrEngineGUID, L'\\');
if (pch)
{
pch++;
memmove((WCHAR *)dstrEngineGUID, pch, sizeof(WCHAR) * (1 + wcslen(pch)));
}
}
// Get the user token;
if (!pszName)
{
if (SUCCEEDED(hr))
{
hr = SpGetDefaultTokenFromCategoryId(SPCAT_SPEECHUSER, &cpUserToken);
}
}
else
{
BOOL fFoundMatch = FALSE;
CComPtr<IEnumSpObjectTokens> cpEnum;
ULONG celtFetched;
CSpDynamicString dstrName = pszName;
if (SUCCEEDED(hr))
{
hr = SpEnumTokens(SPCAT_SPEECHUSER, NULL, NULL, &cpEnum);
}
if(hr == S_FALSE)
{
hr = SPERR_NOT_FOUND;
}
if (SUCCEEDED(hr))
{
hr = cpEnum->GetCount(&celtFetched);
}
while (!fFoundMatch && SUCCEEDED(hr))
{
ISpRegistryObjectToken *pRegToken = 0;
hr = cpEnum->Next(1, (ISpObjectToken**)&pRegToken, &celtFetched);
if (hr != S_OK)
{
break;
}
if (SUCCEEDED(hr))
{
CSpDynamicString dstrNameT;
hr = SpGetDescription(pRegToken, &dstrNameT);
fFoundMatch = 0 == wcsicmp(dstrName, dstrNameT);
}
if (fFoundMatch)
{
cpUserToken = pRegToken;
}
if (pRegToken)
{
pRegToken->Release();
}
}
}
hrReturn = hr;
if (SUCCEEDED(hr))
{
hr = cpUserToken->OpenKey(dstrEngineGUID, &cpDataKey);
hrReturn = (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) ? S_OK : hr;
}
if (SUCCEEDED(hr))
{
hr = cpDataKey->OpenKey(L"files", &cpSubDataKey);
hrReturn = (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) ? S_OK : hr;
}
// Nuke all the files first.
if (SUCCEEDED(hr))
{
ULONG iKey;
for (iKey = 0; hr == S_OK; iKey++)
{
CSpDynamicString dstrFileType;
CSpDynamicString dstrFilePath;
hr = cpSubDataKey->EnumValues(iKey, &dstrFileType);
if (SUCCEEDED(hr))
{
hr = cpSubDataKey->GetStringValue(dstrFileType, &dstrFilePath);
}
if (SUCCEEDED(hr))
{
USES_CONVERSION;
hr = DeleteFile(W2T(dstrFilePath)) ? S_OK : HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
if (g_fVerbose)
{
dstrReport.Append(L"Deleting ");
dstrReport.Append2(dstrFilePath, SUCCEEDED(hr) ? L" -- Success\n" : L" -- Fail\n");
}
}
}
hrReturn = hr = (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr) ? S_OK : hr;
}
// Nuke the files key
if (SUCCEEDED(hr))
{
cpSubDataKey.Release();
hr = cpDataKey->DeleteKey(L"files");
if (g_fVerbose)
{
CSpDynamicString dstrID;
cpUserToken->GetID(&dstrID);
dstrReport.Append2(L"Deleting Key ", dstrID);
dstrReport.Append2(L"\\", dstrEngineGUID);
dstrReport.Append2(L"\\Files", SUCCEEDED(hr) ? L" -- Success\n" : L" -- Fail\n");
}
hrReturn = hr;
}
if (FAILED(hrReturn))
{
//Report("DataCouldn't find an appropriate user", E_INVALIDARG);
}
else if (g_fVerbose && dstrReport)
{
USES_CONVERSION;
Report(W2A(dstrReport), hr);
}
return hrReturn;
}
/**********************************************************************
* Report *
*--------*
*
* Description:
*
* Show a message box, possibly indicating an error.
*
* Return:
*
* The HRESULT passed in is returned, for the convenience of
* the caller.
*
************************************************************* cthrash */
HRESULT Report(char * lpMsg, HRESULT hr)
{
if (hr != S_OK || g_fVerbose)
{
const UINT uType = MB_OK | (FAILED(hr) ? MB_ICONERROR : MB_ICONINFORMATION);
MessageBox(HWND_DESKTOP, lpMsg, "resetusr.exe", uType);
}
return hr;
}