void log_COMError(int line, HRESULT hr) { if (FAILED(hr)) { // int Sev=(hr>>30)&3; int C=(hr>>29)&1; int R=(hr>>28)&1; int Facility=(hr>>16)&4095; int Code=hr&65535; // CString buf; // CString strSev; switch(Sev) { case 0: strSev="SUCCESS"; break; case 1: strSev="INFORMATIONAL"; break; case 2: strSev="WARNING"; break; case 3: strSev="ERROR"; break; }; CString strFacility; switch(Facility) { case FACILITY_WINDOWS: strFacility="WINDOWS"; break; //8 case FACILITY_URT: strFacility="URT"; break; //19 case FACILITY_STORAGE: strFacility="STORAGE"; break; //3 //case FACILITY_SSPI: strFacility="SSPI"; break; //9 case FACILITY_SCARD: strFacility="SCARD"; break; //16 case FACILITY_SETUPAPI: strFacility="SETUPAPI"; break; //15 case FACILITY_SECURITY: strFacility="SECURITY"; break; //9 case FACILITY_RPC: strFacility="RPC"; break; //1 case FACILITY_WIN32: strFacility="WIN32"; break; //7 case FACILITY_CONTROL: strFacility="CONTROL"; break; // 10 case FACILITY_NULL: strFacility="NULL"; break; //0 case FACILITY_MSMQ: strFacility="MSMQ"; break; //14 case FACILITY_MEDIASERVER: strFacility="MEDIASERVER"; break; //13 case FACILITY_INTERNET: strFacility="INTERNET"; break; //12 case FACILITY_ITF: strFacility="ITF"; break; //4 case FACILITY_DISPATCH: strFacility="DISPATCH"; break; //2 case FACILITY_COMPLUS: strFacility="COMPLUS"; break; //17 case FACILITY_CERT: strFacility="CERT"; break; //11 case FACILITY_ACS: strFacility="ACS"; break; //20 case FACILITY_AAF: strFacility="AAF"; break; //18 default: strFacility="UNKNOWN"; }; // buf.Format("ADSI Error 0x%x(%d) (Severity=%u %s Customer=%u Reserve=%u Facility=%u %s Code=0x%X(%d)) ", hr, hr, Sev, strSev, C, R, Facility, strFacility, Code, Code ); log_Error(__LINE__,buf); //if facility is Win32, get the Win32 error if (HRESULT_FACILITY(hr)==FACILITY_WIN32) { DWORD dwLastError; WCHAR szErrorBuf[MAX_ERRTEXT]; WCHAR szNameBuf[MAX_ERRTEXT]; //Get extended error value. HRESULT hr_return = S_OK; hr_return = ADsGetLastError( &dwLastError, szErrorBuf, MAX_ERRTEXT-2, szNameBuf, MAX_ERRTEXT-2); if (SUCCEEDED(hr_return)) { buf.Format("LastError=0x%x(%d) Text=%ws Provider=%ws ", dwLastError,dwLastError, szErrorBuf, szNameBuf); } if(dwLastError==0) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, Code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, MAX_ERRTEXT-2, NULL ); buf.Format(" %s ", lpMsgBuf); LocalFree( lpMsgBuf ); } log_Error(__LINE__,buf); } log_appendline(line); } }
static int smpd_build_spn_list() { HRESULT hr; IDirectoryObject *pSCP = NULL; ADS_ATTR_INFO *pPropEntries = NULL; IDirectorySearch *pSearch = NULL; ADS_SEARCH_HANDLE hSearch = NULL; LPWSTR pszDN; /* distinguished name of SCP. */ LPWSTR pszServiceDNSName; /* service DNS name. */ LPWSTR pszClass; /* name of service class. */ USHORT usPort; /* service port. */ WCHAR pszSearchString[SMPD_MAX_NAME_LENGTH]; char temp_str[SMPD_MAX_NAME_LENGTH]; char temp_str2[SMPD_MAX_NAME_LENGTH]; smpd_host_spn_node_t *iter; /* double t1, t2; */ static int initialized = 0; if (initialized) { return SMPD_SUCCESS; } initialized = 1; /* t1 = PMPI_Wtime(); */ CoInitialize(NULL); /* Get an IDirectorySearch pointer for the Global Catalog. */ hr = GetGCSearch(&pSearch); if (FAILED(hr) || pSearch == NULL) { smpd_err_printf("GetGC failed 0x%x\n", hr); goto Cleanup; } /* Set up a deep search. Thousands of objects are not expected in this example, therefore query for 1000 rows per page.*/ ADS_SEARCHPREF_INFO SearchPref[2]; DWORD dwPref = sizeof(SearchPref)/sizeof(ADS_SEARCHPREF_INFO); SearchPref[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE; SearchPref[0].vValue.dwType = ADSTYPE_INTEGER; SearchPref[0].vValue.Integer = ADS_SCOPE_SUBTREE; SearchPref[1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE; SearchPref[1].vValue.dwType = ADSTYPE_INTEGER; SearchPref[1].vValue.Integer = 1000; hr = pSearch->SetSearchPreference(SearchPref, dwPref); if (FAILED(hr)) { smpd_err_printf("Failed to set search prefs: hr:0x%x\n", hr); goto Cleanup; } /* Execute the search. From the GC get the distinguished name of the SCP. Use the DN to bind to the SCP and get the other properties. */ LPWSTR rgszDN[] = {L"distinguishedName"}; /* Search for a match of the product GUID. */ swprintf(pszSearchString, L"keywords=%s", SMPD_SERVICE_VENDOR_GUIDW); hr = pSearch->ExecuteSearch(pszSearchString, rgszDN, 1, &hSearch); /*hr = pSearch->ExecuteSearch(L"keywords=5722fe5f-cf46-4594-af7c-0997ca2e9d72", rgszDN, 1, &hSearch);*/ if (FAILED(hr)) { smpd_err_printf("ExecuteSearch failed: hr:0x%x\n", hr); goto Cleanup; } /* Loop through the results. Each row should be an instance of the service identified by the product GUID. Add logic to select from multiple service instances. */ while (SUCCEEDED(hr = pSearch->GetNextRow(hSearch))) { if (hr == S_ADS_NOMORE_ROWS) { DWORD dwError = ERROR_SUCCESS; WCHAR szError[512]; WCHAR szProvider[512]; ADsGetLastError(&dwError, szError, 512, szProvider, 512); if (ERROR_MORE_DATA == dwError) { continue; } goto Cleanup; } ADS_SEARCH_COLUMN Col; hr = pSearch->GetColumn(hSearch, L"distinguishedName", &Col); pszDN = AllocADsStr(Col.pADsValues->CaseIgnoreString); pSearch->FreeColumn(&Col); /* Bind to the DN to get the other properties. */ LPWSTR lpszLDAPPrefix = L"LDAP://"; DWORD dwSCPPathLength = (DWORD)(wcslen(lpszLDAPPrefix) + wcslen(pszDN) + 1); LPWSTR pwszSCPPath = (LPWSTR)malloc(sizeof(WCHAR) * dwSCPPathLength); if (pwszSCPPath) { wcscpy(pwszSCPPath, lpszLDAPPrefix); wcscat(pwszSCPPath, pszDN); } else { smpd_err_printf("Failed to allocate a buffer\n"); goto Cleanup; } /*wprintf(L"pszDN = %s\n", pszDN);*/ /*FreeADsStr(pszDN);*/ hr = ADsGetObject(pwszSCPPath, IID_IDirectoryObject, (void**)&pSCP); free(pwszSCPPath); if (SUCCEEDED(hr)) { /* Properties to retrieve from the SCP object. */ LPWSTR rgszAttribs[]= { {L"serviceClassName"}, {L"serviceDNSName"}, /*{L"serviceDNSNameType"},*/ {L"serviceBindingInformation"} }; DWORD dwAttrs = sizeof(rgszAttribs)/sizeof(LPWSTR); DWORD dwNumAttrGot; hr = pSCP->GetObjectAttributes(rgszAttribs, dwAttrs, &pPropEntries, &dwNumAttrGot); if (FAILED(hr)) { smpd_err_printf("GetObjectAttributes Failed. hr:0x%x\n", hr); goto Cleanup; } pszServiceDNSName = NULL; pszClass = NULL; iter = (smpd_host_spn_node_t*)malloc(sizeof(smpd_host_spn_node_t)); if (iter == NULL) { smpd_err_printf("Unable to allocate memory to store an SPN entry.\n"); goto Cleanup; } iter->next = NULL; iter->host[0] = '\0'; iter->spn[0] = '\0'; iter->dnshost[0] = '\0'; /* Loop through the entries returned by GetObjectAttributes and save the values in the appropriate buffers. */ for (int i = 0; i < (LONG)dwAttrs; i++) { if ((wcscmp(L"serviceDNSName", pPropEntries[i].pszAttrName) == 0) && (pPropEntries[i].dwADsType == ADSTYPE_CASE_IGNORE_STRING)) { pszServiceDNSName = AllocADsStr(pPropEntries[i].pADsValues->CaseIgnoreString); /*wprintf(L"pszServiceDNSName = %s\n", pszServiceDNSName);*/ } /* if ((wcscmp(L"serviceDNSNameType", pPropEntries[i].pszAttrName) == 0) && (pPropEntries[i].dwADsType == ADSTYPE_CASE_IGNORE_STRING)) { pszServiceDNSNameType = AllocADsStr(pPropEntries[i].pADsValues->CaseIgnoreString); wprintf(L"pszServiceDNSNameType = %s\n", pszServiceDNSNameType); } */ if ((wcscmp(L"serviceClassName", pPropEntries[i].pszAttrName) == 0) && (pPropEntries[i].dwADsType == ADSTYPE_CASE_IGNORE_STRING)) { pszClass = AllocADsStr(pPropEntries[i].pADsValues->CaseIgnoreString); /*wprintf(L"pszClass = %s\n", pszClass);*/ } if ((wcscmp(L"serviceBindingInformation", pPropEntries[i].pszAttrName) == 0) && (pPropEntries[i].dwADsType == ADSTYPE_CASE_IGNORE_STRING)) { usPort=(USHORT)_wtoi(pPropEntries[i].pADsValues->CaseIgnoreString); /*wprintf(L"usPort = %d\n", usPort);*/ } } wcstombs(iter->dnshost, pszServiceDNSName, SMPD_MAX_NAME_LENGTH); wcstombs(temp_str, pszClass, SMPD_MAX_NAME_LENGTH); /*MPIU_Snprintf(iter->spn, SMPD_MAX_NAME_LENGTH, "%s/%s:%d", temp_str, iter->dnshost, usPort);*/ wcstombs(temp_str2, pszDN, SMPD_MAX_NAME_LENGTH); MPIU_Snprintf(iter->spn, SMPD_MAX_NAME_LENGTH, "%s/%s/%s", temp_str, iter->dnshost, temp_str2); MPIU_Strncpy(iter->host, iter->dnshost, SMPD_MAX_NAME_LENGTH); strtok(iter->host, "."); iter->next = spn_list; spn_list = iter; if (pszServiceDNSName != NULL) { FreeADsStr(pszServiceDNSName); } if (pszClass != NULL) { FreeADsStr(pszClass); } } FreeADsStr(pszDN); } Cleanup: /* iter = spn_list; while (iter != NULL) { printf("host : %s\n", iter->host); printf("dnshost: %s\n", iter->dnshost); printf("spn : %s\n", iter->spn); iter = iter->next; } fflush(stdout); */ if (pSCP) { pSCP->Release(); pSCP = NULL; } if (pPropEntries) { FreeADsMem(pPropEntries); pPropEntries = NULL; } if (pSearch) { if (hSearch) { pSearch->CloseSearchHandle(hSearch); hSearch = NULL; } pSearch->Release(); pSearch = NULL; } CoUninitialize(); /* t2 = PMPI_Wtime(); smpd_dbg_printf("build_spn_list took %0.6f seconds\n", t2-t1); */ return SMPD_SUCCESS; }
PyObject *OleSetADSIError(HRESULT hr, IUnknown *pUnk, REFIID iid) { // If the HRESULT is an ADSI one, we do things differently! if (hr & 0x00005000) { WCHAR szErrorBuf[MAX_PATH] = {0}; WCHAR szNameBuf[MAX_PATH] = {0}; DWORD dwErrCode = 0; ADsGetLastError( &dwErrCode, szErrorBuf, MAX_PATH-1, szNameBuf, MAX_PATH-1); if (dwErrCode == 0) dwErrCode = hr; if (!szErrorBuf[0]) GetADSIErrorString( hr, szErrorBuf, MAX_PATH-1); // Trim trailing /r/n WCHAR *szEnd = szErrorBuf + wcslen(szErrorBuf) - 1; while (szEnd > szErrorBuf && (*szEnd == L'\r' || *szEnd == L'\n')) *szEnd-- = L'\0'; // Only do this if we have a useful message - otherwise // let the default handling do the best it can. if (szErrorBuf[0]) { EXCEPINFO info; memset(&info, 0, sizeof(info)); info.scode = dwErrCode; info.bstrSource = SysAllocString(szNameBuf); info.bstrDescription = SysAllocString(szErrorBuf); // Technically, we probably should return DISP_E_EXCEPTION so we // appear to follow COM's rules - however, we really dont // _need_ to (as only Python sees this result), and having the native // HRESULT is preferable. return PyCom_BuildPyExceptionFromEXCEPINFO(dwErrCode, &info); } } if (HRESULT_FACILITY(hr)==FACILITY_WIN32) { //Get extended error value. WCHAR szErrorBuf[MAX_PATH] = {0}; WCHAR szNameBuf[MAX_PATH] = {0}; DWORD dwErrCode = 0; ADsGetLastError( &dwErrCode, szErrorBuf, MAX_PATH-1, szNameBuf, MAX_PATH-1); // Only do this if we have a useful message - otherwise // let the default handling do the best it can. if (dwErrCode == 0) dwErrCode = hr; if (szErrorBuf[0]) { EXCEPINFO info; memset(&info, 0, sizeof(info)); info.scode = dwErrCode; info.bstrSource = SysAllocString(szNameBuf); info.bstrDescription = SysAllocString(szErrorBuf); // Technically, we probably should return DISP_E_EXCEPTION so we // appear to follow COM's rules - however, we really dont // _need_ to (as only Python sees this result), and having the native // HRESULT is preferable. return PyCom_BuildPyExceptionFromEXCEPINFO(dwErrCode, &info); } } // Do the normal thing. return PyCom_BuildPyException(hr, pUnk, iid); }