Ekstensi Kelas Pembantu NDF
Contoh ini menggambarkan cara menerapkan fungsi diagnosis dan perbaikan NDF. Dalam contoh ini, file konfigurasi penting harus ada agar sistem tetap sehat. Oleh karena itu, masalahnya adalah menentukan apakah file ada. Jika tidak, sistem tidak sehat dan masalahnya didiagnosis oleh NDF. Perbaikannya adalah membuat ulang file yang hilang.
Untuk mendiagnosis dan memperbaiki masalah yang diperlukan menggunakan empat metode INetDiagHelper: Inisialisasi, lowHealth, GetRepairInfo, dan Repair.
Menginisialisasi Kelas Pembantu
Inisialisasi dan ambil nama file yang akan ditemukan. Nama file ini diteruskan selama diagnosis sebagai atribut pembantu yang disebut "nama file".
#include <windows.h>
//utility function to simplify string allocation and copies, user throughout example
HRESULT
StringCchCopyWithAlloc (
PWSTR* Dest,
size_t cchMaxLen,
in PCWSTR Src)
{
if (NULL == Dest || NULL == Src || cchMaxLen > USHRT_MAX)
{
return E_INVALIDARG;
}
size_t cchSize = 0;
HRESULT hr = StringCchLength(Src, cchMaxLen - 1, &cchSize);
if (FAILED(hr))
{
return hr;
}
size_t cbSize = (cchSize + 1)*sizeof(WCHAR);
*Dest = (PWSTR) CoTaskMemAlloc(cbSize);
if (NULL == *Dest)
{
return E_OUTOFMEMORY;
}
SecureZeroMemory(*Dest, cbSize);
return StringCchCopy((STRSAFE_LPWSTR)*Dest, cchSize + 1, Src);
}
HRESULT SimpleFileHelperClass::Initialize(
/* [in] */ ULONG celt,
/* [size_is][in] */ HELPER_ATTRIBUTE rgAttributes[ ])
{
if(celt < 1)
{
return E_INVALIDARG;
}
if(rgAttributes == NULL)
{
return E_INVALIDARG;
}
else
{
//verify the attribute is named as expected
if (wcscmp(rgAttributes[0].pwszName, L"filename")==0)
{
//copy the attribute to member variable
return StringCchCopyWithAlloc(&m_pwszTestFile, MAX_PATH,
rgAttributes[0].PWStr);
} else {
//the attribute isn't named as expected
return E_INVALIDARG;
}
}
}
Memeriksa Keberadaan File
Metode LowHealth digunakan untuk memeriksa keberadaan file. Jika file ada, status diagnosis diatur ke DS_REJECTED, menunjukkan tidak ada yang salah. Jika file tidak dapat ditemukan, status diagnosis diatur ke DS_CONFIRMED.
#include <windows.h>
HRESULT SimpleFileHelperClass::LowHealth(
/* [unique][string][in] */ LPCWSTR pwszInstanceDescription,
/* [string][out] */ LPWSTR *ppwszDescription,
/* [out] */ long *pDeferredTime,
/* [out] */ DIAGNOSIS_STATUS *pStatus)
{
HANDLE hFile = NULL;
LPWSTR pwszDiagString=NULL;
// does the file already exist?
hFile = CreateFile(
m_pwszTestFile,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(INVALID_HANDLE_VALUE == hFile)
{
// alloc and set the diagnosis description and status
HRESULT hr = StringCchCopyWithAlloc(&pwszDiagString, MAX_PATH,
L"The file was deleted.");
if (FAILED(hr))
{
return hr;
}
*ppwszDescription = pwszDiagString;
*pStatus = DS_CONFIRMED;
return S_OK;
}
CloseHandle(hFile);
//the file exists
*pStatus = DS_REJECTED;
return S_OK;
}
Menentukan Tindakan Perbaikan
Jika LowHealth mengembalikan DS_CONFIRMED, GetRepairInfo diimplementasikan untuk menentukan tindakan perbaikan yang sesuai. Dalam contoh ini, itu berarti membuat ulang file.
#include <windows.h>
HRESULT
SimpleFileHelperClass::GetRepairInfo(
/* [in] */ PROBLEM_TYPE problem,
/* [out] */ ULONG *pcelt,
/* [size_is][size_is][out] */ RepairInfo **ppInfo)
{
HRESULT hr=S_OK;
RepairInfo* pRepair = (RepairInfo *)CoTaskMemAlloc(sizeof(RepairInfo));
if (pRepair == NULL) {
return E_OUTOFMEMORY;
}
SecureZeroMemory(pRepair,sizeof(RepairInfo));
// set the repair description and class name
hr = StringCchCopyWithAlloc(&pRepair->pwszClassName, MAX_PATH,
L"SimpleFileHelperClass");
if (FAILED(hr))
{
goto Error;
}
hr = StringCchCopyWithAlloc(&pRepair->pwszDescription, MAX_PATH,
L"Low Health Repair");
if (FAILED(hr))
{
goto Error;
}
// set the resolution GUID and cost
pRepair->guid = ID_LowHealthRepair;
pRepair->cost = 0;
// set repair status flags
pRepair->sidType = WinWorldSid;
pRepair->scope = RS_SYSTEM;
pRepair->risk = RR_NORISK;
pRepair->flags |= DF_IMPERSONATION; //impersonate the user when repairing
pRepair->UiInfo.type = UIT_NONE;
//pass back the repair
*ppInfo = pRepair;
*pcelt = 1; //number of repairs
return S_OK;
Error:
if(pRepair){
if(pRepair->pwszClassName){
CoTaskMemFree(pRepair->pwszClassName);
}
if(pRepair->pwszDescription){
CoTaskMemFree(pRepair->pwszDescription);
}
}
return hr;
}
Memperbaiki Masalah
Pengguna disajikan dengan opsi perbaikan yang dikembalikan oleh GetRepairInfo, kecuali hanya ada satu opsi perbaikan, dalam hal ini secara otomatis dijalankan. MetodePerbaikandipanggil dengan strukturRepairInfoyang berlaku sehingga file konfigurasi dapat dipulihkan.
#include <windows.h>
HRESULT
SimpleFileHelperClass::Repair(
/* [in] */ RepairInfo *pInfo,
/* [out] */ long *pDeferredTime,
/* [out] */ REPAIR_STATUS *pStatus)
{
//verify expected repair was requested
if(IsEqualGUID(ID_LowHealthRepair, pInfo->guid)){
HANDLE hFile = NULL;
hFile = CreateFile(m_pwszTestFile,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(INVALID_HANDLE_VALUE == hFile)
{
// repair failed
*pStatus = RS_UNREPAIRED;
return HRESULT_FROM_WIN32(GetLastError());
}
CloseHandle(hFile);
// repair succeeded
*pStatus = RS_REPAIRED;
} else {
return E_INVALIDARG; //unkown repair passed in
}
return S_OK;
}