windows-nt/Source/XPSP1/NT/admin/pchealth/client/lamebtn/dll/upload.cpp
2020-09-26 16:20:57 +08:00

509 lines
14 KiB
C++

/*
Copyright 1999 Microsoft Corporation
Upload to the EMI database server
Walter Smith (wsmith)
Rajesh Soy (nsoy) - reorganized code and cleaned it up, added comments 06/06/2000
*/
#ifdef THIS_FILE
#undef THIS_FILE
#endif
static char __szTraceSourceFile[] = __FILE__;
#define THIS_FILE __szTraceSourceFile
#include "stdafx.h"
#define NOTRACE
#include "uploadmanager.h"
#include "logging.h"
#include <dbgtrace.h>
#include "UploadmanagerDID.h"
#include "resource.h"
//
// Externs
//
extern CComModule _Module;
//
// PC Health registry stuff
//
const TCHAR szREGKEY_MACHINEINFO[] = _T("Software\\Microsoft\\PCHealth\\MachineInfo");
const TCHAR szREGVALUE_GUID_NONESC[] = _T("CommentPID");
//
// LAMEBTN.DLL registry stuff
//
const TCHAR szREGKEY_ERROR_MESSAGES[] = _T("Software\\Microsoft\\PCHealth\\Clients\\Error Messages");
const TCHAR szREGKEY_DIALOG_COMMENTS[] = _T("Software\\Microsoft\\PCHealth\\Clients\\Dialog Comments");
const TCHAR szREGVALUE_UPLOAD_SERVER[] = _T("Upload URL");
const TCHAR szREGVALUE_UPLOAD_PROVIDER[] = _T("Upload provider");
//
// Routines Defined here:
//
void GetRegValue(HKEY hkRoot, LPCTSTR szKeyName, LPCTSTR szValueName, LPTSTR szValue, DWORD* pcbValue);
LPCTSTR GetUploadRegKey(ENUM_UPLOAD_TYPES type);
void GetMachineSignature(GUIDSTR szGUID);
inline HRESULT ChangeSecurity(IUnknown * pUnknown);
int QueueXMLDocumentUpload(ENUM_UPLOAD_TYPES type, SimpleXMLDocument& doc);
//
// GetRegValue: Get value of required registry entry (throw if not found).
// IN *pcbValue is the size in bytes of szValue
// OUT *pchValue is the size of the retrieved data
//
void
GetRegValue(
HKEY hkRoot,
LPCTSTR szKeyName,
LPCTSTR szValueName,
LPTSTR szValue,
DWORD* pcbValue
)
{
CRegKey rk;
ThrowIfW32Fail( rk.Open(hkRoot, szKeyName, KEY_READ) );
ThrowIfW32Fail( rk.QueryValue(szValue, szValueName, pcbValue) );
rk.Close();
}
//
// GetUploadRegKey: Returns the correct registy key location
//
LPCTSTR
GetUploadRegKey(
ENUM_UPLOAD_TYPES type
)
{
if (type == UPLOAD_MESSAGEBOX)
{
return szREGKEY_ERROR_MESSAGES;
}
else if (type == UPLOAD_LAMEBUTTON)
{
return szREGKEY_DIALOG_COMMENTS;
}
// WTF?!
_ASSERT(false);
throw E_FAIL;
return NULL; // the compiler
}
//
// GetMachineSignature: Obtains the Machine signature. This however, is currently
// not being used at the backend
//
void
GetMachineSignature(
GUIDSTR szGUID // [out] - Machine GUID
)
{
TraceFunctEnter("GetMachineSignature");
CRegKey rk;
DWORD dwSize = 0;
//
// Try to read the Machine GUID from registry
//
if (rk.Open(HKEY_LOCAL_MACHINE, szREGKEY_MACHINEINFO, KEY_READ) == ERROR_SUCCESS)
{
dwSize = sizeof(GUIDSTR);
if (rk.QueryValue(szGUID, szREGVALUE_GUID_NONESC, &dwSize) == ERROR_SUCCESS)
{
rk.Close();
return;
}
}
rk.Close();
//
// If PCHealth's GUID is gone for some reason, We generate a GUID
//
DebugTrace(0, "Generating a new GUID");
lstrcpy(szGUID, _T("{00000000-0000-0000-0000-000000000000}"));
GUID guid;
HRESULT hr;
LPOLESTR lpolestr_guid;
hr = CoCreateGuid(&guid);
if (FAILED(hr))
{
FatalTrace(0, "CoCreateGuid failed. Error: %ld", hr);
goto done;
}
hr = StringFromIID(guid, &lpolestr_guid);
if (FAILED(hr))
{
FatalTrace(0, "StringFromIID failed. Error: %ld", hr);
goto done;
}
lstrcpy(szGUID, lpolestr_guid);
CoTaskMemFree(lpolestr_guid);
//
// We update the generated GUID in the registry
//
DebugTrace(0, "Creating %s", szREGKEY_MACHINEINFO);
if (rk.Create(HKEY_LOCAL_MACHINE, szREGKEY_MACHINEINFO ) == ERROR_SUCCESS)
{
if(rk.SetValue(szGUID, szREGVALUE_GUID_NONESC) != ERROR_SUCCESS)
{
FatalTrace(0, "Failed to set MachineID in registry. Error: %ld", GetLastError());
}
}
done:
rk.Close();
DebugTrace(0, "szGUID: %ls", szGUID);
TraceFunctLeave();
return;
}
//-----------------------------------------------------------------------------
// It's necessary to modify the security settings on a new MPCUpload interface.
//-----------------------------------------------------------------------------
inline HRESULT ChangeSecurity(IUnknown * pUnknown)
{
TraceFunctEnter("ChangeSecurity");
IClientSecurity * pCliSec = NULL;
//
// Query the IClientSecurity interface
//
HRESULT hr = pUnknown->QueryInterface(IID_IClientSecurity, (void **) &pCliSec);
if (FAILED(hr))
{
FatalTrace(0, "pUnknown->QueryInterface failed. hr: %ld", hr);
goto done;
}
DebugTrace(0, "Calling pCliSec->SetBlanket");
//
// Set the correct Security blanket
//
hr = pCliSec->SetBlanket(pUnknown,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CONNECT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_DEFAULT);
pCliSec->Release();
done:
TraceFunctLeave();
return hr;
}
//
// QueueXMLDocumentUpload: This routine schedules the XML blob passed to it for upload to Upload Manager
//
int
QueueXMLDocumentUpload(
ENUM_UPLOAD_TYPES type, // [in] - upload type
SimpleXMLDocument& doc // [in] - XML blob to be uploaded
)
{
TCHAR szTemp[1024];
DWORD dwTemp;
UL_STATUS status;
long errCode;
LPCTSTR szRegKey;
TraceFunctEnter("QueueXMLDocumentUpload");
//
// NTRAID#NTBUG9-154248-2000/08/08-jasonr
// NTRAID#NTBUG9-152439-2000/08/08-jasonr
//
// We used to pop up the "Thank You" message box in the new thread.
// Now we pop it up in the dialog box thread instead to fix these bugs.
// The new thread now returns 0 to indicate success, 1 to indicate
// failure. We only pop up the dialog box on success.
//
int iRet = 1;
//
// Make a temporary filename for the XML blob
//
TCHAR szTempFileName[MAX_PATH];
TCHAR szTempPath[MAX_PATH];
try
{
ThrowIfZero( GetTempPath(ARRAYSIZE(szTempPath), szTempPath) );
ThrowIfZero( GetTempFileName(szTempPath, _T("EMI"), 0, szTempFileName) );
}
catch(...)
{
FatalTrace(0, "Unable to get a tempFile name");
//
// Use a default value
//
_tcscpy(szTempFileName, _T("C:\\upload.xml"));
}
DebugTrace(0, "szTempFileName: %ls", szTempFileName);
try {
//
// Generate the XML to the temp file
//
DebugTrace(0, "Saving: %ls", szTempFileName);
doc.SaveFile(szTempFileName);
//
// Tell the PC Health upload library to upload it
//
CComPtr<IMPCUpload> pUploadMgr;
CComPtr<IMPCUploadJob> pJob;
HRESULT hr = S_OK;
//
// Create an instance of MPCUpload
//
DebugTrace(0, "Creating instance of MPCUpload");
//MessageBox(GetFocus(), L"Creating instance of MPCUpload", L"Debug", 0);
hr = pUploadMgr.CoCreateInstance(__uuidof(MPCUpload));
if(FAILED(hr))
{
_Module.RegisterTypeLib();
hr = pUploadMgr.CoCreateInstance(__uuidof(MPCUpload));
if(FAILED(hr))
{
FatalTrace(0, "pUploadMgr.CoCreateInstance failed. hr=0x%x", hr);
ThrowIfFail(hr);
}
}
//
// Set the appropriate security blanket
//
DebugTrace(0, "Changing Security of pUploadMgr");
hr = ChangeSecurity( pUploadMgr );
if(FAILED(hr))
{
FatalTrace(0, "ChangeSecurity Failed. hr=0x%x", hr);
ThrowIfFail(hr);
}
//
// Create an upload job
//
DebugTrace(0, "Creating Job");
//MessageBox(GetFocus(), L"Creating Job", L"Debug", 0);
hr = pUploadMgr->CreateJob(&pJob);
if(FAILED(hr))
{
FatalTrace(0, "pUploadMgr->CreateJob failed hr=0x%x", hr);
TCHAR szErr[1024];
_stprintf(szErr, L"pUploadMgr->CreateJob failed hr=0x%x", hr);
// MessageBox(GetFocus(), szErr, L"Debug", 0);
ThrowIfFail(hr);
}
_ASSERT(pJob != NULL);
//
// Set the appropriate security blanket
//
DebugTrace(0, "Changing Security of pJob");
hr = ChangeSecurity( pJob );
if(FAILED(hr))
{
FatalTrace(0, "ChangeSecurity Failed. hr=0x%x", hr);
ThrowIfFail(hr);
}
//
// Obtain the Machine GUID
//
//GUIDSTR szSig;
//GetMachineSignature(szSig);
//DebugTrace(0, "Machine signature: %ls", CComBSTR(szSig));
//
// nsoy - we are going to use the uploadm GUID henceforth.
// Set the machine signature in the job
//
DebugTrace(0, "Setting Machine signature");
hr = pJob->put_Sig( NULL );
if(FAILED(hr))
{
FatalTrace(0, "pJob->put_Server failed. hr=%ld", hr);
ThrowIfFail( hr );
}
//
// Obtain the registry key for upload server information
//
szRegKey = GetUploadRegKey(type);
//
// Read the registry key to obtain the upload server information
//
dwTemp = ARRAYSIZE(szTemp);
GetRegValue(HKEY_LOCAL_MACHINE, szRegKey, szREGVALUE_UPLOAD_SERVER, szTemp, &dwTemp);
//
// Set the upload server name in the upload job
//
DebugTrace(0, "Setting Server: %ls", CComBSTR(szTemp));
hr = pJob->put_Server(CComBSTR(szTemp));
if(FAILED(hr))
{
FatalTrace(0, "pJob->put_Server failed. hr=%ld", hr);
ThrowIfFail( hr );
}
//
// Obtain the upload server provider name from registry
//
dwTemp = ARRAYSIZE(szTemp);
GetRegValue(HKEY_LOCAL_MACHINE, szRegKey, szREGVALUE_UPLOAD_PROVIDER, szTemp, &dwTemp);
//
// Set the upload server provider ID
//
DebugTrace(0, "Setting ProviderID: %ls", CComBSTR(szTemp));
hr = pJob->put_ProviderID(CComBSTR(szTemp));
if(FAILED(hr))
{
FatalTrace(0, "pJob->put_Server failed. hr=%ld", hr);
ThrowIfFail( hr );
}
// REVIEW: probably should be UL_HISTORY_NONE when we think it works
DebugTrace(0, "Setting History to UL_HISTORY_LOG");
hr = pJob->put_History(UL_HISTORY_LOG);
if(FAILED(hr))
{
FatalTrace(0, "put_History failed. hr=%ld", hr);
ThrowIfFail( hr );
}
//
// Set the Compression flag
//
DebugTrace(0, "Setting Compressed flag to TRUE");
hr = pJob->put_Compressed(VARIANT_TRUE);
if(FAILED(hr))
{
FatalTrace(0, "put_Compressed failed. hr=%ld", hr);
ThrowIfFail( hr );
}
//
// Set PersitToDisk flag
//
DebugTrace(0, "Setting PersistToDisk flag to TRUE");
hr = pJob->put_PersistToDisk(VARIANT_TRUE);
if(FAILED(hr))
{
FatalTrace(0, "put_PersistToDisk failed. hr=%ld", hr);
ThrowIfFail( hr );
}
//
// Obtain Status & Error code before putting the job to queue
//
pJob->get_Status(&status);
pJob->get_ErrorCode(&errCode);
DebugTrace(0, "upload status: %d (error %ld)\n", status, errCode);
//
// Let the upload job read the data persisted in to the temp file
//
DebugTrace(0, "Calling GetDataFromFile: %ls", CComBSTR(szTempFileName));
hr = pJob->GetDataFromFile(CComBSTR(szTempFileName));
if(FAILED(hr))
{
FatalTrace(0, "GetDataFromFile failed. hr=%ld", hr);
ThrowIfFail( hr );
}
//
// Delete the temp file
//
if (FALSE == DeleteFile(szTempFileName))
{
FatalTrace(0, "DeleteFile failed on %ls. Error: %ld", szTempFileName, GetLastError());
throw;
}
DebugTrace(0, "Calling ActivateAsyn");
hr = pJob->ActivateAsync();
if(FAILED(hr))
{
FatalTrace(0, "ActivateAsync failed. hr=%ld", hr);
ThrowIfFail( hr );
}
pJob->get_Status(&status);
pJob->get_ErrorCode(&errCode);
DebugTrace(0, "upload status: %d (error %ld)\n", status, errCode);
//
// NTRAID#NTBUG9-154248-2000/08/08-jasonr
// NTRAID#NTBUG9-152439-2000/08/08-jasonr
//
// We used to pop up the "Thank You" message box in the new thread.
// Now we pop it up in the dialog box thread instead to fix these bugs.
// The new thread now returns 0 to indicate success, 1 to indicate
// failure. We only pop up the dialog box on success.
//
iRet = 0;
#if 0
//
// Display Thank you dialog
//
TCHAR szThankYouMessage[1024];
TCHAR szThankYouMessageTitle[1024];
LoadString(_Module.GetResourceInstance(),
IDS_COMMENT_THANKYOU,
szThankYouMessage,
ARRAYSIZE(szThankYouMessage));
LoadString(_Module.GetResourceInstance(),
IDS_COMMENT_THANKYOUTITLE,
szThankYouMessageTitle,
ARRAYSIZE(szThankYouMessageTitle));
MessageBox( NULL, szThankYouMessage, szThankYouMessageTitle, MB_OK);
#endif
}
catch (HRESULT hr) {
FatalTrace(0, "Error Code: %lx", hr);
}
catch (...) {
DebugTrace(0, "Upload CRASHED !!!");
throw;
}
return(iRet);
}