|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1999
//
// File: reg.cpp
//
//--------------------------------------------------------------------------
#include <pch.cpp>
#pragma hdrstop
#include <xenroll.h>
#include "polreg.h"
#include "certtype.h"
#define __dwFILE__ __dwFILE_CERTUTIL_REG_CPP__
// add two WCHAR L'\0's after the registry value, in case of a poorly
// formed REG_MULTI_SZ. Add another to handle possible odd sizes.
#define cbVALUEZEROPAD (3 * sizeof(WCHAR))
typedef struct _DUMPFLAGS { DWORD Mask; DWORD Value; WCHAR const *pwszDescription; } DUMPFLAGS;
#define _DFBIT(def) { (def), (def), L#def }
#define _DFBIT2(mask, def) { (mask), (def), L#def }
DUMPFLAGS g_adfEditFlags[] = { _DFBIT(EDITF_ENABLEREQUESTEXTENSIONS), _DFBIT(EDITF_REQUESTEXTENSIONLIST), _DFBIT(EDITF_DISABLEEXTENSIONLIST), _DFBIT(EDITF_ADDOLDKEYUSAGE), _DFBIT(EDITF_ADDOLDCERTTYPE), _DFBIT(EDITF_ATTRIBUTEENDDATE), _DFBIT(EDITF_BASICCONSTRAINTSCRITICAL), _DFBIT(EDITF_BASICCONSTRAINTSCA), _DFBIT(EDITF_ENABLEAKIKEYID), _DFBIT(EDITF_ATTRIBUTECA), _DFBIT(EDITF_IGNOREREQUESTERGROUP), _DFBIT(EDITF_ENABLEAKIISSUERNAME), _DFBIT(EDITF_ENABLEAKIISSUERSERIAL), _DFBIT(EDITF_ENABLEAKICRITICAL), _DFBIT(EDITF_SERVERUPGRADED), _DFBIT(EDITF_ATTRIBUTEEKU), _DFBIT(EDITF_ENABLEDEFAULTSMIME), _DFBIT(EDITF_EMAILOPTIONAL), _DFBIT(EDITF_ATTRIBUTESUBJECTALTNAME2), _DFBIT(EDITF_ENABLELDAPREFERRALS), _DFBIT(EDITF_ENABLECHASECLIENTDC), { 0, 0, NULL } };
DUMPFLAGS g_adfCRLFlags[] = { _DFBIT(CRLF_DELTA_USE_OLDEST_UNEXPIRED_BASE), _DFBIT(CRLF_DELETE_EXPIRED_CRLS), _DFBIT(CRLF_CRLNUMBER_CRITICAL), _DFBIT(CRLF_REVCHECK_IGNORE_OFFLINE), _DFBIT(CRLF_IGNORE_INVALID_POLICIES), _DFBIT(CRLF_REBUILD_MODIFIED_SUBJECT_ONLY), _DFBIT(CRLF_SAVE_FAILED_CERTS), _DFBIT(CRLF_IGNORE_UNKNOWN_CMC_ATTRIBUTES), _DFBIT(CRLF_IGNORE_CROSS_CERT_TRUST_ERROR), _DFBIT(CRLF_PUBLISH_EXPIRED_CERT_CRLS), _DFBIT(CRLF_ENFORCE_ENROLLMENT_AGENT), _DFBIT(CRLF_DISABLE_RDN_REORDER), _DFBIT(CRLF_DISABLE_ROOT_CROSS_CERTS), _DFBIT(CRLF_LOG_FULL_RESPONSE), _DFBIT(CRLF_USE_XCHG_CERT_TEMPLATE), _DFBIT(CRLF_USE_CROSS_CERT_TEMPLATE), _DFBIT(CRLF_ALLOW_REQUEST_ATTRIBUTE_SUBJECT), _DFBIT(CRLF_REVCHECK_IGNORE_NOREVCHECK), _DFBIT(CRLF_PRESERVE_EXPIRED_CA_CERTS), _DFBIT(CRLF_PRESERVE_REVOKED_CA_CERTS), { 0, 0, NULL } };
DUMPFLAGS g_adfInterfaceFlags[] = { _DFBIT(IF_LOCKICERTREQUEST), _DFBIT(IF_NOREMOTEICERTREQUEST), _DFBIT(IF_NOLOCALICERTREQUEST), _DFBIT(IF_NORPCICERTREQUEST), _DFBIT(IF_NOREMOTEICERTADMIN), _DFBIT(IF_NOLOCALICERTADMIN), _DFBIT(IF_NOREMOTEICERTADMINBACKUP), _DFBIT(IF_NOLOCALICERTADMINBACKUP), _DFBIT(IF_NOSNAPSHOTBACKUP), _DFBIT(IF_ENFORCEENCRYPTICERTREQUEST), _DFBIT(IF_ENFORCEENCRYPTICERTADMIN), { 0, 0, NULL } };
DUMPFLAGS g_adfKRAFlags[] = { _DFBIT(KRAF_ENABLEFOREIGN), _DFBIT(KRAF_SAVEBADREQUESTKEY), _DFBIT(KRAF_ENABLEARCHIVEALL), { 0, 0, NULL } };
DUMPFLAGS g_adfDBFlags[] = { _DFBIT(DBFLAGS_READONLY), _DFBIT(DBFLAGS_CREATEIFNEEDED), _DFBIT(DBFLAGS_CIRCULARLOGGING), _DFBIT(DBFLAGS_LAZYFLUSH), _DFBIT(DBFLAGS_MAXCACHESIZEX100), _DFBIT(DBFLAGS_CHECKPOINTDEPTH60MB), _DFBIT(DBFLAGS_LOGBUFFERSLARGE), _DFBIT(DBFLAGS_LOGBUFFERSHUGE), _DFBIT(DBFLAGS_LOGFILESIZE16MB), _DFBIT(DBFLAGS_MULTITHREADTRANSACTIONS), { 0, 0, NULL } };
DUMPFLAGS g_adfLDAPFlags[] = { _DFBIT(LDAPF_SSLENABLE), _DFBIT(LDAPF_SIGNDISABLE), { 0, 0, NULL } };
#define ISSCERT_LDAPURL ISSCERT_LDAPURL_OLD
#define ISSCERT_HTTPURL ISSCERT_HTTPURL_OLD
#define ISSCERT_FTPURL ISSCERT_FTPURL_OLD
#define ISSCERT_FILEURL ISSCERT_FILEURL_OLD
DUMPFLAGS g_adfIssuercertFlags[] = { _DFBIT(ISSCERT_LDAPURL), _DFBIT(ISSCERT_HTTPURL), _DFBIT(ISSCERT_FTPURL), _DFBIT(ISSCERT_FILEURL), _DFBIT(ISSCERT_ENABLE), { 0, 0, NULL } };
DUMPFLAGS g_adfRequestDispositionFlags[] = { _DFBIT2(REQDISP_MASK, REQDISP_PENDING), _DFBIT2(REQDISP_MASK, REQDISP_ISSUE), _DFBIT2(REQDISP_MASK, REQDISP_DENY), _DFBIT2(REQDISP_MASK, REQDISP_USEREQUESTATTRIBUTE), _DFBIT(REQDISP_PENDINGFIRST), { 0, 0, NULL } };
#define REVEXT_CDPLDAPURL REVEXT_CDPLDAPURL_OLD
#define REVEXT_CDPHTTPURL REVEXT_CDPHTTPURL_OLD
#define REVEXT_CDPFTPURL REVEXT_CDPFTPURL_OLD
#define REVEXT_CDPFILEURL REVEXT_CDPFILEURL_OLD
DUMPFLAGS g_adfRevocationTypeFlags[] = { _DFBIT(REVEXT_CDPLDAPURL), _DFBIT(REVEXT_CDPHTTPURL), _DFBIT(REVEXT_CDPFTPURL), _DFBIT(REVEXT_CDPFILEURL), _DFBIT(REVEXT_CDPENABLE), _DFBIT(REVEXT_ASPENABLE), { 0, 0, NULL } };
DUMPFLAGS g_adfSetupStatus[] = { _DFBIT(SETUP_SERVER_FLAG), _DFBIT(SETUP_CLIENT_FLAG), _DFBIT(SETUP_SUSPEND_FLAG), _DFBIT(SETUP_REQUEST_FLAG), _DFBIT(SETUP_ONLINE_FLAG), _DFBIT(SETUP_DENIED_FLAG), _DFBIT(SETUP_CREATEDB_FLAG), _DFBIT(SETUP_ATTEMPT_VROOT_CREATE), _DFBIT(SETUP_FORCECRL_FLAG), _DFBIT(SETUP_UPDATE_CAOBJECT_SVRTYPE), _DFBIT(SETUP_SERVER_UPGRADED_FLAG), _DFBIT(SETUP_SECURITY_CHANGED), _DFBIT(SETUP_W2K_SECURITY_NOT_UPGRADED_FLAG), { 0, 0, NULL } };
DUMPFLAGS g_adfCertPublishFlags[] = { _DFBIT(EXITPUB_FILE), _DFBIT(EXITPUB_ACTIVEDIRECTORY), { 0, 0, NULL } };
DUMPFLAGS g_adfCAType[] = { _DFBIT2(MAXDWORD, ENUM_ENTERPRISE_ROOTCA), _DFBIT2(MAXDWORD, ENUM_ENTERPRISE_SUBCA), _DFBIT2(MAXDWORD, ENUM_STANDALONE_ROOTCA), _DFBIT2(MAXDWORD, ENUM_STANDALONE_SUBCA), _DFBIT2(MAXDWORD, ENUM_UNKNOWN_CA), { 0, 0, NULL } };
DUMPFLAGS g_adfForceTeletex[] = { _DFBIT2(ENUM_TELETEX_MASK, ENUM_TELETEX_OFF), _DFBIT2(ENUM_TELETEX_MASK, ENUM_TELETEX_ON), _DFBIT2(ENUM_TELETEX_MASK, ENUM_TELETEX_AUTO), _DFBIT2(ENUM_TELETEX_UTF8, ENUM_TELETEX_UTF8), { 0, 0, NULL } };
DUMPFLAGS g_adfCSURL[] = { _DFBIT(CSURL_SERVERPUBLISH), _DFBIT(CSURL_ADDTOCERTCDP), _DFBIT(CSURL_ADDTOFRESHESTCRL), _DFBIT(CSURL_ADDTOCRLCDP), _DFBIT(CSURL_PUBLISHRETRY), _DFBIT(CSURL_ADDTOCERTOCSP), _DFBIT(CSURL_SERVERPUBLISHDELTA), { 0, 0, NULL } };
// Enrollment Flags:
DUMPFLAGS g_adfTemplateEnroll[] = { _DFBIT(CT_FLAG_INCLUDE_SYMMETRIC_ALGORITHMS), _DFBIT(CT_FLAG_PEND_ALL_REQUESTS), _DFBIT(CT_FLAG_PUBLISH_TO_KRA_CONTAINER), _DFBIT(CT_FLAG_PUBLISH_TO_DS), _DFBIT(CT_FLAG_AUTO_ENROLLMENT_CHECK_USER_DS_CERTIFICATE), _DFBIT(CT_FLAG_AUTO_ENROLLMENT), _DFBIT(CT_FLAG_PREVIOUS_APPROVAL_VALIDATE_REENROLLMENT), _DFBIT(CT_FLAG_DOMAIN_AUTHENTICATION_NOT_REQUIRED), _DFBIT(CT_FLAG_USER_INTERACTION_REQUIRED), _DFBIT(CT_FLAG_ADD_TEMPLATE_NAME), _DFBIT(CT_FLAG_REMOVE_INVALID_CERTIFICATE_FROM_PERSONAL_STORE), _DFBIT(CT_FLAG_ALLOW_ENROLL_ON_BEHALF_OF), { 0, 0, NULL } };
// Certificate Subject Name Flags:
DUMPFLAGS g_adfTemplateName[] = { _DFBIT(CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT), _DFBIT(CT_FLAG_ADD_EMAIL), _DFBIT(CT_FLAG_ADD_OBJ_GUID), _DFBIT(CT_FLAG_ADD_DIRECTORY_PATH), _DFBIT(CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT_ALT_NAME), _DFBIT(CT_FLAG_SUBJECT_ALT_REQUIRE_SPN), _DFBIT(CT_FLAG_SUBJECT_ALT_REQUIRE_DIRECTORY_GUID), _DFBIT(CT_FLAG_SUBJECT_ALT_REQUIRE_UPN), _DFBIT(CT_FLAG_SUBJECT_ALT_REQUIRE_EMAIL), _DFBIT(CT_FLAG_SUBJECT_ALT_REQUIRE_DNS), _DFBIT(CT_FLAG_SUBJECT_REQUIRE_DNS_AS_CN), _DFBIT(CT_FLAG_SUBJECT_REQUIRE_EMAIL), _DFBIT(CT_FLAG_SUBJECT_REQUIRE_COMMON_NAME), _DFBIT(CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATH), { 0, 0, NULL } };
DUMPFLAGS g_adfTemplatePrivateKey[] = { // Private Key Flags:
_DFBIT(CT_FLAG_REQUIRE_PRIVATE_KEY_ARCHIVAL), _DFBIT(CT_FLAG_EXPORTABLE_KEY), _DFBIT(CT_FLAG_STRONG_KEY_PROTECTION_REQUIRED), { 0, 0, NULL } };
// Old V1 template flags definitions:
//efine CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT 0x00000001
//efine CT_FLAG_ADD_EMAIL 0x00000002
//efine CT_FLAG_ADD_OBJ_GUID 0x00000004
//efine CT_FLAG_PUBLISH_TO_DS 0x00000008
//efine CT_FLAG_EXPORTABLE_KEY 0x00000010
//efine CT_FLAG_AUTO_ENROLLMENT 0x00000020
//efine CT_FLAG_MACHINE_TYPE 0x00000040
//efine CT_FLAG_IS_CA 0x00000080
//efine CT_FLAG_ADD_DIRECTORY_PATH 0x00000100
//efine CT_FLAG_ADD_TEMPLATE_NAME 0x00000200
#define CT_FLAG_ADD_SUBJECT_DIRECTORY_PATH 0x00000400
//efine CT_FLAG_IS_CROSS_CA 0x00000800
//efine CT_FLAG_IS_DEFAULT 0x00010000
//efine CT_FLAG_IS_MODIFIED 0x00020000
#define CT_FLAG_IS_DELETED 0x00040000
#define CT_FLAG_POLICY_MISMATCH 0x00080000
// General Flags
DUMPFLAGS g_adfTemplateGeneral[] = { _DFBIT(CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT), _DFBIT(CT_FLAG_ADD_EMAIL), _DFBIT(CT_FLAG_ADD_OBJ_GUID), _DFBIT(CT_FLAG_PUBLISH_TO_DS), _DFBIT(CT_FLAG_EXPORTABLE_KEY), _DFBIT(CT_FLAG_AUTO_ENROLLMENT), _DFBIT(CT_FLAG_MACHINE_TYPE), _DFBIT(CT_FLAG_IS_CA), _DFBIT(CT_FLAG_ADD_DIRECTORY_PATH), _DFBIT(CT_FLAG_ADD_TEMPLATE_NAME), _DFBIT(CT_FLAG_ADD_SUBJECT_DIRECTORY_PATH), _DFBIT(CT_FLAG_IS_CROSS_CA), _DFBIT(CT_FLAG_IS_DEFAULT), _DFBIT(CT_FLAG_IS_MODIFIED), _DFBIT(CT_FLAG_IS_DELETED), _DFBIT(CT_FLAG_POLICY_MISMATCH), { 0, 0, NULL } };
DUMPFLAGS g_adfKMSCertStatus[] = { _DFBIT(CERTFLAGS_REVOKED), _DFBIT(CERTFLAGS_NOT_EXPIRED), _DFBIT(CERTFLAGS_SIGNING), _DFBIT(CERTFLAGS_SEALING), _DFBIT(CERTFLAGS_CURRENT), _DFBIT(CERTFLAGS_IMPORTED), _DFBIT2(CERTFLAGS_VERSION_3, CERTFLAGS_VERSION_1), _DFBIT2(CERTFLAGS_VERSION_3, CERTFLAGS_VERSION_3), { 0, 0, NULL } };
DUMPFLAGS g_adfCRLPublishFlags[] = { _DFBIT(CPF_BASE), _DFBIT(CPF_DELTA), _DFBIT(CPF_COMPLETE), _DFBIT(CPF_SHADOW), _DFBIT(CPF_CASTORE_ERROR), _DFBIT(CPF_BADURL_ERROR), _DFBIT(CPF_MANUAL), _DFBIT(CPF_SIGNATURE_ERROR), _DFBIT(CPF_LDAP_ERROR), _DFBIT(CPF_FILE_ERROR), _DFBIT(CPF_FTP_ERROR), _DFBIT(CPF_HTTP_ERROR), { 0, 0, NULL } };
DUMPFLAGS g_adfCAFlags[] = { _DFBIT(CA_FLAG_NO_TEMPLATE_SUPPORT), _DFBIT(CA_FLAG_SUPPORTS_NT_AUTHENTICATION), _DFBIT(CA_FLAG_CA_SUPPORTS_MANUAL_AUTHENTICATION), _DFBIT(CA_FLAG_CA_SERVERTYPE_ADVANCED), { 0, 0, NULL } };
DUMPFLAGS g_adfOIDFlags[] = { _DFBIT2(MAXDWORD, CERT_OID_TYPE_TEMPLATE), _DFBIT2(MAXDWORD, CERT_OID_TYPE_ISSUER_POLICY), _DFBIT2(MAXDWORD, CERT_OID_TYPE_APPLICATION_POLICY), { 0, 0, NULL } };
DUMPFLAGS g_adfRequestClientId[] = { _DFBIT2(MAXDWORD, XECI_DISABLE), _DFBIT2(MAXDWORD, XECI_XENROLL), _DFBIT2(MAXDWORD, XECI_AUTOENROLL), _DFBIT2(MAXDWORD, XECI_REQWIZARD), _DFBIT2(MAXDWORD, XECI_CERTREQ), { 0, 0, NULL } };
DUMPFLAGS g_adfSMTPEventFilter[] = { #ifndef EXITEVENT_CERTUNREVOKED
#define EXITEVENT_CERTUNREVOKED 0x100
#endif
_DFBIT(EXITEVENT_CERTISSUED), _DFBIT(EXITEVENT_CERTPENDING), _DFBIT(EXITEVENT_CERTDENIED), _DFBIT(EXITEVENT_CERTREVOKED), _DFBIT(EXITEVENT_CERTRETRIEVEPENDING), _DFBIT(EXITEVENT_CRLISSUED), _DFBIT(EXITEVENT_SHUTDOWN), _DFBIT(EXITEVENT_STARTUP), _DFBIT(EXITEVENT_CERTUNREVOKED), { 0, 0, NULL } };
typedef struct _DUMPFLAGSREGMAP { WCHAR const *pwszRegName; DUMPFLAGS const *adf; } DUMPFLAGSREGMAP;
DUMPFLAGSREGMAP g_adfrm[] = { { wszREGEDITFLAGS, g_adfEditFlags }, { wszREGISSUERCERTURLFLAGS, g_adfIssuercertFlags }, { wszREGREQUESTDISPOSITION, g_adfRequestDispositionFlags }, { wszREGREVOCATIONTYPE, g_adfRevocationTypeFlags }, { wszREGSETUPSTATUS, g_adfSetupStatus }, { wszREGCERTPUBLISHFLAGS, g_adfCertPublishFlags }, { wszREGCRLEDITFLAGS, g_adfEditFlags }, { wszREGCRLFLAGS, g_adfCRLFlags }, { wszREGKRAFLAGS, g_adfKRAFlags }, { wszREGINTERFACEFLAGS, g_adfInterfaceFlags }, { wszREGLDAPFLAGS, g_adfLDAPFlags }, { wszREGDBFLAGS, g_adfDBFlags }, { wszREGCATYPE, g_adfCAType}, { wszREGWEBCLIENTCATYPE, g_adfCAType}, { wszREGFORCETELETEX, g_adfForceTeletex}, { CERTTYPE_RPOP_ENROLLMENT_FLAG, g_adfTemplateEnroll }, { CERTTYPE_PROP_NAME_FLAG, g_adfTemplateName }, { CERTTYPE_PROP_PRIVATE_KEY_FLAG, g_adfTemplatePrivateKey }, //{ CERTTYPE_PROP_FLAGS, g_adfTemplateGeneral },
{ wszCUREGDSTEMPLATEFLAGS, g_adfTemplateGeneral }, { wszCUREGDSCAFLAGS, g_adfCAFlags }, //{ OID_PROP_TYPE, g_adfOIDFlags },
{ wszCUREGDSOIDFLAGS, g_adfOIDFlags }, { wszPROPCERTIFICATEENROLLMENTFLAGS, g_adfTemplateEnroll }, { wszPROPCERTIFICATEGENERALFLAGS, g_adfTemplateGeneral }, { wszKMSCERTSTATUS, g_adfKMSCertStatus }, { wszPROPCRLPUBLISHFLAGS, g_adfCRLPublishFlags }, { wszREQUESTCLIENTID, g_adfRequestClientId }, { wszREGCRLPUBLICATIONURLS, g_adfCSURL }, { wszREGCACERTPUBLICATIONURLS, g_adfCSURL }, { wszREGEXITSMTPEVENTFILTER, g_adfSMTPEventFilter }, { NULL, NULL } };
VOID cuPrintFlags( IN DWORD Flags, IN DUMPFLAGS const *pdf) { DWORD ExtraFlags = Flags; for ( ; NULL != pdf->pwszDescription; pdf++) { BOOL fSet = (Flags & pdf->Mask) == pdf->Value;
if (fSet || g_fVerbose) { wprintf( L" %ws%ws -- %x", fSet? g_wszEmpty : L" " wszLPAREN, pdf->pwszDescription, pdf->Value); if (9 < pdf->Value) { wprintf(L" (%d)", pdf->Value); } if (!fSet) { wprintf(wszRPAREN); } wprintf(wszNewLine); } ExtraFlags &= ~pdf->Mask; } if (0 != ExtraFlags) { wprintf(L" 0x%x (%u)\n", ExtraFlags, ExtraFlags); } }
WCHAR const * regTail( IN WCHAR const *pwszRegName) { WCHAR const *pwsz = wcsrchr(pwszRegName, L'\\');
if (NULL != pwsz) { pwsz++; } else { pwsz = pwszRegName; } return(pwsz); }
HRESULT cuLookupRegFlags( IN WCHAR const *pwszRegName, OUT DUMPFLAGS const **ppdf) { HRESULT hr = E_INVALIDARG; DUMPFLAGSREGMAP const *pdfrm;
*ppdf = NULL; pwszRegName = regTail(pwszRegName); for (pdfrm = g_adfrm; NULL != pdfrm->pwszRegName; pdfrm++) { if (0 == mylstrcmpiS(pwszRegName, pdfrm->pwszRegName)) { *ppdf = pdfrm->adf; hr = S_OK; break; } } return(hr); }
VOID cuPrintRegDWord( IN DWORD Value, IN WCHAR const *pwszRegName) { HRESULT hr;
pwszRegName = regTail(pwszRegName); if (0 == LSTRCMPIS(pwszRegName, wszREGVERSION)) { wprintf(L" -- %u.%u", Value >> 16, Value & ((1 << 16) - 1)); } }
BOOL cuPrintRegFlags( IN BOOL fNewLine, IN DWORD Flags, IN WCHAR const *pwszRegName) { HRESULT hr; DUMPFLAGS const *pdf;
pwszRegName = regTail(pwszRegName); if (0 == LSTRCMPIS(pwszRegName, wszHASHALGORITHM) || 0 == LSTRCMPIS(pwszRegName, wszENCRYPTIONALGORITHM)) { cuDumpAlgid(Flags); hr = S_OK; } else { hr = cuLookupRegFlags(pwszRegName, &pdf); _JumpIfError2(hr, error, "cuLookupRegFlags", hr);
if (fNewLine) { wprintf(wszNewLine); } cuPrintFlags(Flags, pdf); }
error: return(S_OK == hr); }
HRESULT cuMapRegFlags( IN WCHAR const *pwszRegName, IN WCHAR const *pwszRegValue, IN BOOL fClearField, IN OUT DWORD *pFlags) { HRESULT hr; WCHAR const *pwsz; DUMPFLAGS const *pdf;
hr = cuLookupRegFlags(pwszRegName, &pdf); _JumpIfErrorStr2(hr, error, "cuLookupRegFlags", pwszRegName, hr);
for ( ; NULL != pdf->pwszDescription; pdf++) { if (0 == mylstrcmpiS(pwszRegValue, pdf->pwszDescription)) { break; } pwsz = wcschr(pdf->pwszDescription, L'_'); if (NULL == pwsz) { continue; } if (0 == mylstrcmpiS(pwszRegValue, &pwsz[1])) { break; } } if (NULL == pdf->pwszDescription) { hr = E_INVALIDARG; _JumpErrorStr2(hr, error, "no match", pwszRegValue, hr); }
*pFlags &= ~pdf->Mask; if (!fClearField) { *pFlags |= pdf->Value; } hr = S_OK;
error: return(hr); }
HRESULT OpenSubKey( IN HKEY hkey, IN WCHAR const *pwszName, IN BOOL fCreateSubKey, OUT HKEY *phkeySub, OUT WCHAR **ppwszSubKeyName, OUT WCHAR **ppwszValueName) { HRESULT hr; HKEY hkeySub = NULL; WCHAR *pwszSubKeyName = NULL; WCHAR *pwszT; DWORD cwcSkip; DWORD i; WCHAR awc[MAX_PATH]; *phkeySub = NULL; hr = myDupString(pwszName, &pwszSubKeyName); _JumpIfError(hr, error, "myDupString");
cwcSkip = wcslen(pwszName);
hr = RegOpenKeyEx( hkey, pwszSubKeyName, 0, KEY_ALL_ACCESS, &hkeySub); if (S_OK != hr) { //_PrintErrorStr(hr, "RegOpenKeyEx", pwszName);
hkeySub = NULL; pwszT = wcsrchr(pwszSubKeyName, L'\\'); if (NULL != pwszT) { *pwszT = L'\0'; cwcSkip = SAFE_SUBTRACT_POINTERS(pwszT, pwszSubKeyName) + 1;
hr = RegOpenKeyEx( hkey, pwszSubKeyName, 0, KEY_ALL_ACCESS, &hkeySub); if ((HRESULT) ERROR_FILE_NOT_FOUND == hr && fCreateSubKey) { hr = RegCreateKey(hkey, pwszSubKeyName, &hkeySub); _JumpIfErrorStr(hr, error, "RegCreateKey", pwszSubKeyName); } _JumpIfErrorStr(hr, error, "RegOpenKeyEx", pwszSubKeyName); } }
if (NULL != hkeySub) { pwszName += cwcSkip;
if (L'\0' != *pwszName) { // Look for case-ignore registry value name, & use the value's
// correct upper/lower case spelling if an existing registry value:
for (i = 0; ; i++) { DWORD cwc = ARRAYSIZE(awc); hr = RegEnumValue(hkeySub, i, awc, &cwc, NULL, NULL, NULL, NULL); if (S_OK != hr) { hr = S_OK; break; } if (0 == mylstrcmpiL(awc, pwszName)) { pwszName = awc; break; } } } }
hr = myDupString(pwszName, ppwszValueName); _JumpIfError(hr, error, "myDupString");
if (NULL != hkeySub) { *phkeySub = hkeySub; hkeySub = NULL; } *ppwszSubKeyName = pwszSubKeyName; pwszSubKeyName = NULL;
error: if (NULL != pwszSubKeyName) { LocalFree(pwszSubKeyName); } if (NULL != hkeySub) { RegCloseKey(hkeySub); } return(myHError(hr)); }
VOID PrintRegStringValue( IN WCHAR const *pwszLookupName, IN WCHAR const *pwszValue) { DWORD Flags; WCHAR *pwszDup = NULL; wprintf(L"%ws", pwszValue); if (iswdigit(*pwszValue)) { BOOL fParmValid = FALSE; DWORD dwParm; WCHAR const *pwszObjId = pwszValue; WCHAR *pwszParm = wcschr(pwszValue, L',');
if (NULL != pwszParm) { HRESULT hr;
hr = myDupString(pwszValue, &pwszDup); _PrintIfError(hr, "myDupString");
pwszParm = wcschr(pwszDup, L','); if (NULL != pwszParm) { *pwszParm++ = L'\0'; dwParm = myWtoI(pwszParm, &fParmValid); pwszObjId = fParmValid? pwszDup : NULL; } } if (NULL != pwszObjId) { cuPrintPossibleObjectIdName(pwszObjId); if (fParmValid) { wprintf(L" %x", dwParm); if (9 < dwParm) { wprintf(L" (%d)", dwParm); } } } } cuPrintRegFlags(TRUE, _wtoi(pwszValue), pwszLookupName); if (NULL != pwszDup) { LocalFree(pwszDup); } }
VOID PrintRegValue( IN WCHAR const *pwszLookupName, IN WCHAR const *pwszDisplayName, IN DWORD dwType, IN BOOL fPrintDwordNameAndValue, IN BOOL fPrintType, IN DWORD cwcSeparator, IN DWORD cbValue, OPTIONAL IN BYTE const *pbValue, OPTIONAL OUT BOOL *pfLongValue) { HRESULT hr; DWORD i; WCHAR const *pwsz; BOOL fLongValue = FALSE; char const *pszEqual = NULL != pbValue? " =" : ""; if (0 == cwcSeparator && fPrintType) { cwcSeparator = 1; } if (fPrintDwordNameAndValue) { wprintf(L" %ws%*ws", pwszDisplayName, cwcSeparator, L""); } switch (dwType) { case REG_DWORD: if (fPrintDwordNameAndValue) { wprintf( L"%ws%hs", fPrintType? L"REG_DWORD" : L"", pszEqual); } if (NULL != pbValue) { CSASSERT(sizeof(DWORD) == cbValue); if (fPrintDwordNameAndValue) { wprintf(L" %x", *(DWORD *) pbValue); if (9 < *(DWORD *) pbValue) { wprintf(L" (%d)", *(DWORD *) pbValue); } cuPrintRegDWord(*(DWORD *) pbValue, pwszLookupName); wprintf(wszNewLine); } if (cuPrintRegFlags(FALSE, *(DWORD *) pbValue, pwszLookupName)) { fLongValue = TRUE; } } else { if (fPrintDwordNameAndValue) { wprintf(wszNewLine); } } break;
case REG_SZ: if (fPrintType) { wprintf(L"REG_SZ"); } if (NULL != pbValue && 0 != cbValue) { CSASSERT((wcslen((WCHAR const *) pbValue) + 1) * sizeof(WCHAR) == cbValue); wprintf(L" = "); PrintRegStringValue(pwszLookupName, (WCHAR const *) pbValue); if (44 < wcslen((WCHAR const *) pbValue)) { fLongValue = TRUE; } } wprintf(wszNewLine); break;
case REG_MULTI_SZ: wprintf( L"%ws%hs", fPrintType? L"REG_MULTI_SZ" : L"", pszEqual); if (NULL != pbValue && 0 != cbValue) { pwsz = (WCHAR const *) pbValue; if (L'\0' == *pwsz) { // empty value
} else if (!fPrintType && L'\0' == pwsz[wcslen(pwsz) + 1]) { // single value
wprintf(L" "); PrintRegStringValue(pwszLookupName, (WCHAR const *) pbValue); pwsz += wcslen(pwsz) + 1; } else { wprintf(wszNewLine); i = 0; for ( ; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1) { wprintf(L" %u: ", i); PrintRegStringValue(pwszLookupName, pwsz); wprintf(wszNewLine); i++; } fLongValue = TRUE; } CSASSERT( (pwsz == (WCHAR *) pbValue && 2 * sizeof(WCHAR) == cbValue) || (SAFE_SUBTRACT_POINTERS((BYTE *) pwsz, pbValue) + sizeof(WCHAR) == cbValue)); } if (!fLongValue) { wprintf(wszNewLine); } break;
default: case REG_BINARY: if (fPrintType) { if (REG_BINARY == dwType) { wprintf(L"REG_BINARY"); } else { wprintf(L"???=%x%", dwType); } } wprintf(L"%hs", pszEqual); if (NULL != pbValue && 0 != cbValue) { BOOL fDump = TRUE; WCHAR const *pwszNL = wszNewLine; if (REG_BINARY == dwType && sizeof(FILETIME) == cbValue) { hr = cuDumpFileTimeOrPeriod( 0, NULL, (FILETIME const *) pbValue); if (S_OK == hr) { if (g_fVerbose) { pwszNL = NULL; } else { fDump = FALSE; } } } if (fDump) { if (NULL != pwszNL) { wprintf(pwszNL); } DumpHex(0, pbValue, cbValue); fLongValue = TRUE; } } break; } if (NULL != pfLongValue) { *pfLongValue = fLongValue; } }
BOOL cuRegPrintDwordValue( IN BOOL fPrintNameAndValue, IN WCHAR const *pwszLookupName, IN WCHAR const *pwszDisplayName, IN DWORD dwValue) { BOOL fDisplayed = FALSE;
PrintRegValue( pwszLookupName, pwszDisplayName, REG_DWORD, fPrintNameAndValue, FALSE, 0, // cwcSeparator
sizeof(dwValue), (BYTE const *) &dwValue, &fDisplayed); return(fDisplayed); }
VOID cuRegPrintAwszValue( IN WCHAR const *pwszName, OPTIONAL IN WCHAR const * const *prgpwszValues) { WCHAR *pwszzValues = NULL; WCHAR *pwsz; DWORD cwcAlloc; DWORD i;
cwcAlloc = 1; if (NULL == prgpwszValues || NULL == prgpwszValues[0]) { cwcAlloc++; } else { for (i = 0; NULL != prgpwszValues[i]; i++) { cwcAlloc += wcslen(prgpwszValues[i]) + 1; } } pwszzValues = (WCHAR *) LocalAlloc(LMEM_FIXED, cwcAlloc * sizeof(WCHAR)); if (NULL == pwszzValues) { _JumpError(E_OUTOFMEMORY, error, "LocalAlloc"); } pwsz = pwszzValues; if (NULL == prgpwszValues || NULL == prgpwszValues[0]) { *pwsz++ = L'\0'; } else { for (i = 0; NULL != prgpwszValues[i]; i++) { wcscpy(pwsz, prgpwszValues[i]); pwsz += wcslen(pwsz) + 1; } } *pwsz = L'\0'; CSASSERT(SAFE_SUBTRACT_POINTERS(pwsz, pwszzValues) + 1 == cwcAlloc); PrintRegValue( pwszName, pwszName, REG_MULTI_SZ, TRUE, FALSE, 0, // cwcSeparator
cwcAlloc * sizeof(WCHAR), (BYTE const *) pwszzValues, NULL); // pfLongValue
error: if (NULL != pwszzValues) { LocalFree(pwszzValues); } }
#define REGOP_NONE 0
#define REGOP_SET 1
#define REGOP_CLEAR 2
BOOL IsInList( IN WCHAR const *pwsz, OPTIONAL IN WCHAR const *pwszzList) { BOOL fFound = FALSE; WCHAR *pwszT; if (NULL != pwszzList) { for ( ; L'\0' != *pwszzList; pwszzList += wcslen(pwszzList) + 1) { if (0 == mylstrcmpiL(pwszzList, pwsz)) { fFound = TRUE; break; } } } return(fFound); }
HRESULT CombineMultiSzRegValues( IN DWORD RegOp, IN WCHAR const *pwszRegValue, IN DWORD dwTypeOld, IN DWORD cbValueOld, OPTIONAL IN BYTE const *pbValueOld, OUT BYTE **ppbValue, OUT DWORD *pcbValue) { HRESULT hr; WCHAR *pwszDst; WCHAR const *pwsz; DWORD cpwsz; WCHAR const **apwsz = NULL; DWORD cOld = 0; DWORD cNew = 0; DWORD cCombined; WCHAR *pwszzNew = NULL; DWORD cwc; DWORD i; if (REGOP_NONE != RegOp) { pwsz = (WCHAR *) pbValueOld; if (NULL != pwsz && 0 != cbValueOld) { for ( ; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1) { cOld++; } } }
// Convert backslash-n sequences to L'\0' and move data up.
cwc = wcslen(pwszRegValue) + 1 + 1; pwszzNew = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR)); if (NULL == pwszzNew) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } pwszDst = pwszzNew; pwsz = pwszRegValue;
if (L'\0' != *pwsz && REGOP_CLEAR != RegOp) { cNew++; } while (L'\0' != *pwsz) { WCHAR wc;
wc = *pwsz++; if (L'\\' == wc && L'n' == *pwsz) { if (0 != cNew) { cNew++; } wc = L'\0'; pwsz++; while (L'\\' == pwsz[0] && L'n' == pwsz[1]) { pwsz += 2; } } *pwszDst++ = wc; } *pwszDst++ = L'\0'; *pwszDst = L'\0';
apwsz = (WCHAR const **) LocalAlloc(LMEM_FIXED, (cOld + cNew) * sizeof(apwsz[0])); if (NULL == apwsz) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); }
cCombined = 0; if (cOld) { for (pwsz = (WCHAR *) pbValueOld; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1) { if (REGOP_SET == RegOp || !IsInList(pwsz, pwszzNew)) { apwsz[cCombined++] = pwsz; } } } if (cNew) { for (pwsz = pwszzNew; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1) { if (REGOP_NONE == RegOp || !IsInList(pwsz, (WCHAR *) pbValueOld)) { apwsz[cCombined++] = pwsz; } } } CSASSERT(cOld + cNew >= cCombined);
cwc = 1; for (i = 0; i < cCombined; i++) { cwc += wcslen(apwsz[i]) + 1; } if (0 == cCombined) { cwc++; }
*pcbValue = cwc * sizeof(WCHAR); *ppbValue = (BYTE *) LocalAlloc(LMEM_FIXED, *pcbValue); if (NULL == *ppbValue) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); }
pwszDst = (WCHAR *) *ppbValue; for (i = 0; i < cCombined; i++) { wcscpy(pwszDst, apwsz[i]); pwszDst += wcslen(pwszDst) + 1; } if (0 == cCombined) { *pwszDst++ = L'\0'; } *pwszDst = L'\0';
CSASSERT(SAFE_SUBTRACT_POINTERS(pwszDst, (WCHAR *) *ppbValue) + 1 == cwc); hr = S_OK;
error: if (NULL != apwsz) { LocalFree(apwsz); } if (NULL != pwszzNew) { LocalFree(pwszzNew); } return(hr); }
HRESULT ParseRegValue( IN WCHAR const *pwszRegName, IN DWORD cbValueOld, IN BYTE const *pbValueOld, IN OUT DWORD *pdwType, IN WCHAR const *pwszRegValue, OUT DWORD *pcbValue, OUT BYTE **ppbValue) { HRESULT hr; WCHAR const *pwsz; DWORD cb; DWORD dw; DWORD dwValue; DWORD dwType; DWORD cNewLine; DWORD RegOp; BOOL fNumber;
// A leading '-' or '+' character is used as a REGOP_* operator.
// To include it as part of the string, add leading whitespace,
// or separate the operator from the string by one or more spaces.
//
// "-foo" -- remove "foo" from registry value
// "- foo" -- remove "foo" from registry value
// " -foo" -- overwrite registry value with "-foo"
// "--foo" -- remove "-foo" from registry value
// "- -foo" -- remove "-foo" from registry value
dwValue = 0; cNewLine = 0; if (REG_DWORD == *pdwType) { CSASSERT(sizeof(dw) == cbValueOld); dwValue = *(DWORD *) pbValueOld; } if (L'+' == *pwszRegValue) { RegOp = REGOP_SET; // set bits in existing value
pwszRegValue++; } else if (myIsMinusSign(*pwszRegValue)) { RegOp = REGOP_CLEAR; // clear bits in existing value
pwszRegValue++; } else { RegOp = REGOP_NONE; // overwrite value
dwValue = 0; } while (L' ' == *pwszRegValue || L'\t' == *pwszRegValue) { pwszRegValue++; }
cb = sizeof(dwValue); // assume REG_DWORD
dwType = REG_DWORD;
fNumber = FALSE; if (L'+' == *pwszRegValue || myIsMinusSign(*pwszRegValue) || iswdigit(*pwszRegValue)) { hr = myGetSignedLong(pwszRegValue, (LONG *) &dw); if (S_OK == hr) { fNumber = TRUE; switch (RegOp) { default: case REGOP_NONE: dwValue = dw; break;
case REGOP_SET: dwValue |= dw; break;
case REGOP_CLEAR: dwValue &= ~dw; break; } } } if (!fNumber) { hr = cuMapRegFlags( pwszRegName, pwszRegValue, REGOP_CLEAR == RegOp, &dwValue); if (S_OK != hr) { pwsz = pwszRegValue; while (TRUE) { pwsz = wcschr(pwsz, L'\\'); if (NULL == pwsz) { break; } if (L'n' == *++pwsz) { cNewLine++; } } if (REGOP_SET == RegOp || 0 != cNewLine) { dwType = REG_MULTI_SZ; } else { dwType = REG_SZ; } cb = (wcslen(pwszRegValue) + 1) * sizeof(WCHAR); } }
if (REG_NONE != *pdwType && dwType != *pdwType) { if (REG_SZ == dwType && REG_MULTI_SZ == *pdwType) { dwType = REG_MULTI_SZ; if (0 == cNewLine) { cb += sizeof(WCHAR); } } else if (REG_MULTI_SZ != dwType || REG_SZ != *pdwType) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); _JumpError(hr, error, "bad registry value type"); } }
if (REG_MULTI_SZ == dwType) { hr = CombineMultiSzRegValues( RegOp, pwszRegValue, *pdwType, cbValueOld, pbValueOld, ppbValue, pcbValue); _JumpIfError(hr, error, "CombineMultiSzRegValues"); } else { *ppbValue = (BYTE *) LocalAlloc(LMEM_FIXED, cb); if (NULL == *ppbValue) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } *pcbValue = cb;
if (REG_DWORD == dwType) { CSASSERT(sizeof(dwValue) == cb); CopyMemory(*ppbValue, &dwValue, sizeof(dwValue)); } else { if (REGOP_NONE != RegOp) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); _JumpErrorStr(hr, error, "bad registry value string", pwszRegValue); } CSASSERT((wcslen(pwszRegValue) + 1) * sizeof(WCHAR) <= cb); wcscpy((WCHAR *) *ppbValue, pwszRegValue); } } *pdwType = dwType; if (g_fVerbose) { DumpHex(0, *ppbValue, *pcbValue); } hr = S_OK;
error: return(hr); }
HRESULT WriteRegValue( IN HKEY hkey, IN WCHAR const *pwszName, IN DWORD dwType, IN DWORD cbValue, IN BYTE const *pbValue) { HRESULT hr;
hr = RegSetValueEx(hkey, pwszName, 0, dwType, pbValue, cbValue); _JumpIfErrorStr(hr, error, "RegSetValueEx", pwszName);
error: return(myHError(hr)); }
HRESULT ReadRegValue( IN HKEY hkey, IN WCHAR const *pwszName, OUT DWORD *pdwType, OUT DWORD *pcbValue, OUT BYTE **ppbValue) { HRESULT hr; DWORD cb;
*ppbValue = NULL; cb = 0; hr = RegQueryValueEx( hkey, pwszName, NULL, pdwType, NULL, &cb); _JumpIfErrorStr2(hr, error, "RegQueryValueEx", pwszName, ERROR_FILE_NOT_FOUND);
// add two WCHAR L'\0's after the registry value, in case of a poorly
// formed REG_MULTI_SZ. Add another to handle possible odd sizes.
*ppbValue = (BYTE *) LocalAlloc(LMEM_FIXED, cb + cbVALUEZEROPAD); if (NULL == *ppbValue) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); }
hr = RegQueryValueEx( hkey, pwszName, NULL, pdwType, *ppbValue, &cb); _JumpIfErrorStr(hr, error, "RegQueryValueEx", pwszName);
if (REG_SZ == *pdwType || REG_MULTI_SZ == *pdwType) { WCHAR *pwszStart; WCHAR *pwsz; DWORD cbT;
CSASSERT(0 == ((sizeof(WCHAR) - 1) & cb)); pwszStart = (WCHAR *) *ppbValue; cbT = ~(sizeof(WCHAR) - 1) & cb; pwsz = &pwszStart[cbT / sizeof(WCHAR)];
ZeroMemory(pwsz, cbVALUEZEROPAD); pwsz = pwszStart; while (L'\0' != pwsz[0] || L'\0' != pwsz[1]) { pwsz++; } cbT = (SAFE_SUBTRACT_POINTERS(pwsz, pwszStart) + (REG_SZ == *pdwType? 1 : 2)) * sizeof(WCHAR); CSASSERT(cb == cbT); cb = cbT; } *pcbValue = cb;
error: if (S_OK != hr) { if (NULL != *ppbValue) { LocalFree(*ppbValue); *ppbValue = NULL; } } return(myHError(hr)); }
#define cwcVALUENAME 25 // Nominal registry value name length
HRESULT DumpRegKeysAndValues( IN HKEY hkey, OPTIONAL WCHAR *pwszValueNamePrefix) { HRESULT hr; DWORD i; DWORD j; DWORD cwc; DWORD dwType; WCHAR awc[MAX_PATH + 1]; DWORD cb; BYTE *pb; BYTE ab[8 + cbVALUEZEROPAD]; // enough for small registry values
DWORD cbAlloc; BYTE *pbAlloc = ab; BOOL fLongValue; WCHAR *pwszPrefix = NULL; DWORD cwcPrefix;
if (NULL != pwszValueNamePrefix) { cwcPrefix = wcslen(pwszValueNamePrefix); pwszPrefix = (WCHAR *) LocalAlloc( LMEM_FIXED, (cwcPrefix + 1) * sizeof(WCHAR)); if (NULL == pwszPrefix) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } } for (i = j = 0; ; i++) { cwc = ARRAYSIZE(awc); hr = RegEnumKey(hkey, i, awc, cwc); if (S_OK != hr) { if ((HRESULT) ERROR_NO_MORE_ITEMS != hr) { _PrintError(hr, "RegEnumKey"); } break; } if (NULL != pwszPrefix) { wcsncpy(pwszPrefix, awc, cwcPrefix); pwszPrefix[cwcPrefix] = L'\0'; if (0 != mylstrcmpiL(pwszValueNamePrefix, pwszPrefix)) { continue; } }
if (0 == j) { wprintf(wszNewLine); wprintf(myLoadResourceString(IDS_KEYS)); // "Keys:"
wprintf(wszNewLine); } else if (0 == (j % 5)) { wprintf(wszNewLine); } wprintf(L" %ws\n", awc); j++; }
cbAlloc = sizeof(ab) - cbVALUEZEROPAD; fLongValue = FALSE; for (i = j = 0; ; i++) { DWORD cwcSep;
cwc = ARRAYSIZE(awc); cb = cbAlloc; pb = pbAlloc; hr = RegEnumValue(hkey, i, awc, &cwc, NULL, &dwType, pb, &cb); if (S_OK != hr) { if ((HRESULT) ERROR_MORE_DATA != hr) { if ((HRESULT) ERROR_NO_MORE_ITEMS != hr) { _PrintError(hr, "RegEnumValue"); } break; } CSASSERT(NULL != pb); pb = (BYTE *) LocalAlloc(LMEM_FIXED, cb + cbVALUEZEROPAD); if (NULL == pb) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } if (ab != pbAlloc) { LocalFree(pbAlloc); } pbAlloc = pb; cbAlloc = cb; cwc = ARRAYSIZE(awc); hr = RegEnumValue(hkey, i, awc, &cwc, NULL, &dwType, pb, &cb); _JumpIfError(hr, error, "RegEnumValue"); } if (NULL != pb) { ZeroMemory(&pb[cb], cbVALUEZEROPAD); } if (NULL != pwszPrefix) { wcsncpy(pwszPrefix, awc, cwcPrefix); pwszPrefix[cwcPrefix] = L'\0'; if (0 != mylstrcmpiL(pwszValueNamePrefix, pwszPrefix)) { continue; } } if (0 == j) { wprintf(wszNewLine); wprintf(myLoadResourceString(IDS_VALUES)); // "Values:"
wprintf(wszNewLine); } else if (fLongValue || 0 == (j % 5)) { wprintf(wszNewLine); } cwcSep = wcslen(awc); cwcSep = cwcVALUENAME < cwcSep? 0 : cwcVALUENAME - cwcSep; PrintRegValue(awc, awc, dwType, TRUE, TRUE, cwcSep, cb, pb, &fLongValue); j++; } hr = S_OK;
error: if (NULL != pbAlloc && ab != pbAlloc) { LocalFree(pbAlloc); } if (NULL != pwszPrefix) { LocalFree(pwszPrefix); } return(myHError(hr)); }
WCHAR const * wszHKEY( IN WCHAR const *pwszPath) { WCHAR const *pwszKey = L"HKEY_LOCAL_MACHINE\\";
if (g_fUserRegistry && 0 == _wcsnicmp( pwszPath, wszCERTTYPECACHE, WSZARRAYSIZE(wszCERTTYPECACHE))) { pwszKey = L"HKEY_CURRENT_USER\\"; } return(pwszKey); }
HRESULT verbGetReg( IN WCHAR const *pwszOption, OPTIONAL IN WCHAR const *pwszRegName, IN WCHAR const *pwszArg2, IN WCHAR const *pwszArg3, IN WCHAR const *pwszArg4) { HRESULT hr; WCHAR *pwszPath = NULL; WCHAR *pwszName = NULL; WCHAR *pwszValueName = NULL; WCHAR *pwszSubKeyName = NULL; DWORD dwType; DWORD cbValue; BYTE *pbValue = NULL; HKEY hkey = NULL; HKEY hkeySub = NULL; HKEY hkeyT;
if (NULL == pwszRegName) { pwszRegName = L""; } hr = myRegOpenRelativeKey( g_pwszConfig, pwszRegName, RORKF_FULLPATH | (g_fUserRegistry? RORKF_USERKEY : 0), &pwszPath, &pwszName, &hkey); _JumpIfErrorStr(hr, error, "myRegOpenRelativeKey", pwszRegName);
hr = OpenSubKey( hkey, pwszName, FALSE, &hkeySub, &pwszSubKeyName, &pwszValueName); _JumpIfError(hr, error, "OpenSubKey");
hkeyT = NULL != hkeySub? hkeySub : hkey; wprintf( L"%ws%ws%ws%ws:\n", wszHKEY(pwszPath), L'\0' != *pwszPath? pwszPath : wszREGKEYCONFIG, L'\0' != *pwszSubKeyName? L"\\" : L"", pwszSubKeyName);
if (NULL == pwszValueName || L'\0' == *pwszValueName || NULL != wcschr(pwszValueName, L'*')) { if (NULL != pwszValueName) { WCHAR *pwsz = wcschr(pwszValueName, L'*');
if (NULL != pwsz) { *pwsz = L'\0'; } }
hr = DumpRegKeysAndValues(hkeyT, pwszValueName); _JumpIfError(hr, error, "DumpRegKeysAndValues"); } else { hr = ReadRegValue(hkeyT, pwszValueName, &dwType, &cbValue, &pbValue); _JumpIfErrorStr(hr, error, "ReadRegValue", pwszValueName);
wprintf(wszNewLine); PrintRegValue( pwszValueName, pwszValueName, dwType, TRUE, TRUE, 0, cbValue, pbValue, NULL); }
error: if (NULL != hkey) { RegCloseKey(hkey); } if (NULL != hkeySub) { RegCloseKey(hkeySub); } if (NULL != pwszPath) { LocalFree(pwszPath); } if (NULL != pwszName) { LocalFree(pwszName); } if (NULL != pwszSubKeyName) { LocalFree(pwszSubKeyName); } if (NULL != pwszValueName) { LocalFree(pwszValueName); } if (NULL != pbValue) { LocalFree(pbValue); } return(hr); }
HRESULT verbSetReg( IN WCHAR const *pwszOption, IN WCHAR const *pwszRegName, IN WCHAR const *pwszRegValue, IN WCHAR const *pwszArg3, IN WCHAR const *pwszArg4) { HRESULT hr; WCHAR *pwszPath = NULL; WCHAR *pwszName = NULL; WCHAR *pwszValueName = NULL; WCHAR *pwszSubKeyName = NULL; DWORD dwType; DWORD cbValue; DWORD cbValueArg; BYTE *pbValueOld = NULL; BYTE *pbValueNew = NULL; BYTE *pbValueArg = NULL; HKEY hkey = NULL; HKEY hkeySub = NULL; HKEY hkeyT; DWORD dw;
hr = myRegOpenRelativeKey( g_pwszConfig, pwszRegName, RORKF_FULLPATH | RORKF_CREATESUBKEYS | (g_fUserRegistry? RORKF_USERKEY : 0) | (g_fForce? RORKF_CREATEKEY : 0), &pwszPath, &pwszName, &hkey); _JumpIfErrorStr(hr, error, "myRegOpenRelativeKey", pwszRegName);
hr = OpenSubKey( hkey, pwszName, g_fForce, &hkeySub, &pwszSubKeyName, &pwszValueName); _JumpIfError(hr, error, "OpenSubKey");
hkeyT = NULL != hkeySub? hkeySub : hkey; wprintf( L"%ws%ws%ws%ws:\n", g_fVerbose? wszHKEY(pwszPath) : L"", L'\0' != *pwszPath? pwszPath : wszREGKEYCONFIG, L'\0' != *pwszSubKeyName? L"\\" : L"", pwszSubKeyName);
hr = ReadRegValue(hkeyT, pwszValueName, &dwType, &cbValue, &pbValueOld); if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr) { _JumpIfErrorStr(hr, error, "ReadRegValue", pwszValueName); }
if (NULL != pbValueOld) { wprintf(wszNewLine); wprintf(myLoadResourceString(IDS_OLD_REG_VALUE)); // "Old Value:"
wprintf(wszNewLine); PrintRegValue( pwszValueName, pwszValueName, dwType, TRUE, TRUE, 0, cbValue, pbValueOld, NULL); } else { dwType = REG_NONE; }
hr = ParseRegValue( pwszRegName, cbValue, pbValueOld, &dwType, pwszRegValue, &cbValueArg, &pbValueArg); _JumpIfErrorStr(hr, error, "ParseRegValue", pwszRegValue);
hr = WriteRegValue(hkeyT, pwszValueName, dwType, cbValueArg, pbValueArg); _JumpIfErrorStr(hr, error, "WriteRegValue", pwszValueName);
hr = ReadRegValue(hkeyT, pwszValueName, &dwType, &cbValue, &pbValueNew); _JumpIfErrorStr(hr, error, "ReadRegValue", pwszValueName);
wprintf(wszNewLine); wprintf(myLoadResourceString(IDS_NEW_REG_VALUE)); // "New Value:"
wprintf(wszNewLine); PrintRegValue( pwszValueName, pwszValueName, dwType, TRUE, TRUE, 0, cbValue, pbValueNew, NULL);
error: if (NULL != hkey) { RegCloseKey(hkey); } if (NULL != hkeySub) { RegCloseKey(hkeySub); } if (NULL != pwszPath) { LocalFree(pwszPath); } if (NULL != pwszName) { LocalFree(pwszName); } if (NULL != pwszSubKeyName) { LocalFree(pwszSubKeyName); } if (NULL != pwszValueName) { LocalFree(pwszValueName); } if (NULL != pbValueOld) { LocalFree(pbValueOld); } if (NULL != pbValueArg) { LocalFree(pbValueArg); } if (NULL != pbValueNew) { LocalFree(pbValueNew); } return(hr); }
HRESULT verbDelReg( IN WCHAR const *pwszOption, IN WCHAR const *pwszRegName, IN WCHAR const *pwszArg2, IN WCHAR const *pwszArg3, IN WCHAR const *pwszArg4) { HRESULT hr; WCHAR *pwszPath = NULL; WCHAR *pwszName = NULL; WCHAR *pwszValueName = NULL; WCHAR *pwszSubKeyName = NULL; DWORD dwType; DWORD cbValue; BYTE *pbValueOld = NULL; HKEY hkey = NULL; HKEY hkeySub = NULL; HKEY hkeyT; DWORD dw;
hr = myRegOpenRelativeKey( g_pwszConfig, pwszRegName, RORKF_FULLPATH | RORKF_CREATESUBKEYS | (g_fUserRegistry? RORKF_USERKEY : 0), &pwszPath, &pwszName, &hkey); _JumpIfErrorStr(hr, error, "myRegOpenRelativeKey", pwszRegName);
hr = OpenSubKey( hkey, pwszName, FALSE, &hkeySub, &pwszSubKeyName, &pwszValueName); _JumpIfError(hr, error, "OpenSubKey");
hkeyT = NULL != hkeySub? hkeySub : hkey; wprintf( L"%ws%ws%ws%ws:\n", wszHKEY(pwszPath), L'\0' != *pwszPath? pwszPath : wszREGKEYCONFIG, L'\0' != *pwszSubKeyName? L"\\" : L"", pwszSubKeyName);
hr = ReadRegValue(hkeyT, pwszValueName, &dwType, &cbValue, &pbValueOld); if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr) { _JumpIfErrorStr(hr, error, "ReadRegValue", pwszValueName); }
if (NULL != pbValueOld) { wprintf(wszNewLine); wprintf(myLoadResourceString(IDS_OLD_REG_VALUE)); // "Old Value:"
wprintf(wszNewLine); PrintRegValue( pwszValueName, pwszValueName, dwType, TRUE, TRUE, 0, cbValue, pbValueOld, NULL); } if (NULL == pwszValueName || L'\0' == *pwszValueName) { if (!g_fForce) { hr = E_ACCESSDENIED; _JumpErrorStr(hr, error, "use -f", pwszSubKeyName); } if (NULL != hkeySub) { RegCloseKey(hkeySub); hkeySub = NULL; } hr = RegDeleteKey(hkey, pwszSubKeyName); if (S_OK != hr) { hr = myHError(hr); _JumpErrorStr(hr, error, "RegDeleteKey", pwszSubKeyName); } } else { hr = RegDeleteValue(hkeyT, pwszValueName); if (S_OK != hr) { hr = myHError(hr); _JumpErrorStr(hr, error, "RegDeleteValue", pwszValueName); } } hr = S_OK;
error: if (NULL != hkey) { RegCloseKey(hkey); } if (NULL != hkeySub) { RegCloseKey(hkeySub); } if (NULL != pwszPath) { LocalFree(pwszPath); } if (NULL != pwszName) { LocalFree(pwszName); } if (NULL != pwszSubKeyName) { LocalFree(pwszSubKeyName); } if (NULL != pwszValueName) { LocalFree(pwszValueName); } if (NULL != pbValueOld) { LocalFree(pbValueOld); } return(hr); }
|