diff options
| author | Rob Mensching <rob@firegiant.com> | 2021-04-08 14:06:21 -0700 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2021-04-12 12:29:11 -0700 |
| commit | b2c4600453f926fbfdc63219126930ad39601f25 (patch) | |
| tree | b7c8429ffcfe4f1f8b98f9e43b00d671b2d3a1d6 /src | |
| parent | 0c2b4cf3a439eda3e19d20fadfc65ddc7d0394c0 (diff) | |
| download | wix-b2c4600453f926fbfdc63219126930ad39601f25.tar.gz wix-b2c4600453f926fbfdc63219126930ad39601f25.tar.bz2 wix-b2c4600453f926fbfdc63219126930ad39601f25.zip | |
Port missing WiX v3 changes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dutil/dirutil.cpp | 31 | ||||
| -rw-r--r-- | src/dutil/inc/dirutil.h | 5 | ||||
| -rw-r--r-- | src/dutil/inc/locutil.h | 12 | ||||
| -rw-r--r-- | src/dutil/inc/pathutil.h | 8 | ||||
| -rw-r--r-- | src/dutil/locutil.cpp | 29 | ||||
| -rw-r--r-- | src/dutil/pathutil.cpp | 33 | ||||
| -rw-r--r-- | src/dutil/sqlutil.cpp | 171 |
7 files changed, 254 insertions, 35 deletions
diff --git a/src/dutil/dirutil.cpp b/src/dutil/dirutil.cpp index 81130a8d..b10e71f3 100644 --- a/src/dutil/dirutil.cpp +++ b/src/dutil/dirutil.cpp | |||
| @@ -353,6 +353,37 @@ LExit: | |||
| 353 | 353 | ||
| 354 | 354 | ||
| 355 | /******************************************************************* | 355 | /******************************************************************* |
| 356 | DirDeleteEmptyDirectoriesToRoot - removes an empty directory and as many | ||
| 357 | of its parents as possible. | ||
| 358 | |||
| 359 | Returns: count of directories deleted. | ||
| 360 | *******************************************************************/ | ||
| 361 | extern "C" DWORD DAPI DirDeleteEmptyDirectoriesToRoot( | ||
| 362 | __in_z LPCWSTR wzPath, | ||
| 363 | __in DWORD /*dwFlags*/ | ||
| 364 | ) | ||
| 365 | { | ||
| 366 | DWORD cDeletedDirs = 0; | ||
| 367 | LPWSTR sczPath = NULL; | ||
| 368 | |||
| 369 | while (wzPath && *wzPath && ::RemoveDirectoryW(wzPath)) | ||
| 370 | { | ||
| 371 | ++cDeletedDirs; | ||
| 372 | |||
| 373 | HRESULT hr = PathGetParentPath(wzPath, &sczPath); | ||
| 374 | DirExitOnFailure(hr, "Failed to get parent directory for path: %ls", wzPath); | ||
| 375 | |||
| 376 | wzPath = sczPath; | ||
| 377 | } | ||
| 378 | |||
| 379 | LExit: | ||
| 380 | ReleaseStr(sczPath); | ||
| 381 | |||
| 382 | return cDeletedDirs; | ||
| 383 | } | ||
| 384 | |||
| 385 | |||
| 386 | /******************************************************************* | ||
| 356 | DirGetCurrent - gets the current directory. | 387 | DirGetCurrent - gets the current directory. |
| 357 | 388 | ||
| 358 | *******************************************************************/ | 389 | *******************************************************************/ |
diff --git a/src/dutil/inc/dirutil.h b/src/dutil/inc/dirutil.h index 0a19a9c0..539b3a73 100644 --- a/src/dutil/inc/dirutil.h +++ b/src/dutil/inc/dirutil.h | |||
| @@ -40,6 +40,11 @@ HRESULT DAPI DirEnsureDeleteEx( | |||
| 40 | __in DWORD dwFlags | 40 | __in DWORD dwFlags |
| 41 | ); | 41 | ); |
| 42 | 42 | ||
| 43 | DWORD DAPI DirDeleteEmptyDirectoriesToRoot( | ||
| 44 | __in_z LPCWSTR wzPath, | ||
| 45 | __in DWORD dwFlags | ||
| 46 | ); | ||
| 47 | |||
| 43 | HRESULT DAPI DirGetCurrent( | 48 | HRESULT DAPI DirGetCurrent( |
| 44 | __deref_out_z LPWSTR* psczCurrentDirectory | 49 | __deref_out_z LPWSTR* psczCurrentDirectory |
| 45 | ); | 50 | ); |
diff --git a/src/dutil/inc/locutil.h b/src/dutil/inc/locutil.h index 38ddda20..626cb59e 100644 --- a/src/dutil/inc/locutil.h +++ b/src/dutil/inc/locutil.h | |||
| @@ -50,6 +50,18 @@ HRESULT DAPI LocProbeForFile( | |||
| 50 | ); | 50 | ); |
| 51 | 51 | ||
| 52 | /******************************************************************** | 52 | /******************************************************************** |
| 53 | LocProbeForFileEx - Searches for a localization file on disk. | ||
| 54 | useUILanguage should be set to TRUE. | ||
| 55 | *******************************************************************/ | ||
| 56 | HRESULT DAPI LocProbeForFileEx( | ||
| 57 | __in_z LPCWSTR wzBasePath, | ||
| 58 | __in_z LPCWSTR wzLocFileName, | ||
| 59 | __in_z_opt LPCWSTR wzLanguage, | ||
| 60 | __inout LPWSTR* psczPath, | ||
| 61 | __in BOOL fUseUILanguage | ||
| 62 | ); | ||
| 63 | |||
| 64 | /******************************************************************** | ||
| 53 | LocLoadFromFile - Loads a localization file | 65 | LocLoadFromFile - Loads a localization file |
| 54 | 66 | ||
| 55 | *******************************************************************/ | 67 | *******************************************************************/ |
diff --git a/src/dutil/inc/pathutil.h b/src/dutil/inc/pathutil.h index f4f4e59c..719ee7d8 100644 --- a/src/dutil/inc/pathutil.h +++ b/src/dutil/inc/pathutil.h | |||
| @@ -47,6 +47,14 @@ DAPI_(HRESULT) PathGetDirectory( | |||
| 47 | ); | 47 | ); |
| 48 | 48 | ||
| 49 | /******************************************************************* | 49 | /******************************************************************* |
| 50 | PathGetParentPath - extracts the parent directory from a full path. | ||
| 51 | ********************************************************************/ | ||
| 52 | DAPI_(HRESULT) PathGetParentPath( | ||
| 53 | __in_z LPCWSTR wzPath, | ||
| 54 | __out_z LPWSTR *psczDirectory | ||
| 55 | ); | ||
| 56 | |||
| 57 | /******************************************************************* | ||
| 50 | PathExpand - gets the full path to a file resolving environment | 58 | PathExpand - gets the full path to a file resolving environment |
| 51 | variables along the way. | 59 | variables along the way. |
| 52 | ********************************************************************/ | 60 | ********************************************************************/ |
diff --git a/src/dutil/locutil.cpp b/src/dutil/locutil.cpp index c4567c03..43e1bb5b 100644 --- a/src/dutil/locutil.cpp +++ b/src/dutil/locutil.cpp | |||
| @@ -51,7 +51,7 @@ static HRESULT ParseWxlControl( | |||
| 51 | #ifndef MUI_MERGE_SYSTEM_FALLBACK | 51 | #ifndef MUI_MERGE_SYSTEM_FALLBACK |
| 52 | #define MUI_MERGE_SYSTEM_FALLBACK 0x10 // GetThreadPreferredUILanguages merges in parent and base languages | 52 | #define MUI_MERGE_SYSTEM_FALLBACK 0x10 // GetThreadPreferredUILanguages merges in parent and base languages |
| 53 | #endif | 53 | #endif |
| 54 | typedef WINBASEAPI BOOL (WINAPI *GET_THREAD_PREFERRED_UI_LANGUAGES) ( | 54 | typedef WINBASEAPI BOOL (WINAPI *PFN_GET_THREAD_PREFERRED_UI_LANGUAGES) ( |
| 55 | __in DWORD dwFlags, | 55 | __in DWORD dwFlags, |
| 56 | __out PULONG pulNumLanguages, | 56 | __out PULONG pulNumLanguages, |
| 57 | __out_ecount_opt(*pcchLanguagesBuffer) PZZWSTR pwszLanguagesBuffer, | 57 | __out_ecount_opt(*pcchLanguagesBuffer) PZZWSTR pwszLanguagesBuffer, |
| @@ -65,14 +65,25 @@ extern "C" HRESULT DAPI LocProbeForFile( | |||
| 65 | __inout LPWSTR* psczPath | 65 | __inout LPWSTR* psczPath |
| 66 | ) | 66 | ) |
| 67 | { | 67 | { |
| 68 | return LocProbeForFileEx(wzBasePath, wzLocFileName, wzLanguage, psczPath, FALSE); | ||
| 69 | } | ||
| 70 | |||
| 71 | extern "C" HRESULT DAPI LocProbeForFileEx( | ||
| 72 | __in_z LPCWSTR wzBasePath, | ||
| 73 | __in_z LPCWSTR wzLocFileName, | ||
| 74 | __in_z_opt LPCWSTR wzLanguage, | ||
| 75 | __inout LPWSTR* psczPath, | ||
| 76 | __in BOOL fUseUILanguage | ||
| 77 | ) | ||
| 78 | { | ||
| 68 | HRESULT hr = S_OK; | 79 | HRESULT hr = S_OK; |
| 69 | LPWSTR sczProbePath = NULL; | 80 | LPWSTR sczProbePath = NULL; |
| 70 | LANGID langid = 0; | 81 | LANGID langid = 0; |
| 71 | LPWSTR sczLangIdFile = NULL; | 82 | LPWSTR sczLangIdFile = NULL; |
| 72 | LPWSTR sczLangsBuff = NULL; | 83 | LPWSTR sczLangsBuff = NULL; |
| 73 | GET_THREAD_PREFERRED_UI_LANGUAGES pvfnGetThreadPreferredUILanguages = | 84 | PFN_GET_THREAD_PREFERRED_UI_LANGUAGES pfnGetThreadPreferredUILanguages = |
| 74 | reinterpret_cast<GET_THREAD_PREFERRED_UI_LANGUAGES>( | 85 | reinterpret_cast<PFN_GET_THREAD_PREFERRED_UI_LANGUAGES>( |
| 75 | GetProcAddress(GetModuleHandle("Kernel32.dll"), "GetThreadPreferredUILanguages")); | 86 | ::GetProcAddress(::GetModuleHandle("Kernel32.dll"), "GetThreadPreferredUILanguages")); |
| 76 | 87 | ||
| 77 | // If a language was specified, look for a loc file in that as a directory. | 88 | // If a language was specified, look for a loc file in that as a directory. |
| 78 | if (wzLanguage && *wzLanguage) | 89 | if (wzLanguage && *wzLanguage) |
| @@ -89,12 +100,12 @@ extern "C" HRESULT DAPI LocProbeForFile( | |||
| 89 | } | 100 | } |
| 90 | } | 101 | } |
| 91 | 102 | ||
| 92 | if (pvfnGetThreadPreferredUILanguages) | 103 | if (fUseUILanguage && pfnGetThreadPreferredUILanguages) |
| 93 | { | 104 | { |
| 94 | ULONG nLangs; | 105 | ULONG nLangs = 0; |
| 95 | ULONG cchLangs = 0; | 106 | ULONG cchLangs = 0; |
| 96 | DWORD dwFlags = MUI_LANGUAGE_ID | MUI_MERGE_USER_FALLBACK | MUI_MERGE_SYSTEM_FALLBACK; | 107 | DWORD dwFlags = MUI_LANGUAGE_ID | MUI_MERGE_USER_FALLBACK | MUI_MERGE_SYSTEM_FALLBACK; |
| 97 | if (!(*pvfnGetThreadPreferredUILanguages)(dwFlags, &nLangs, NULL, &cchLangs)) | 108 | if (!(*pfnGetThreadPreferredUILanguages)(dwFlags, &nLangs, NULL, &cchLangs)) |
| 98 | { | 109 | { |
| 99 | LocExitWithLastError(hr, "GetThreadPreferredUILanguages failed to return buffer size."); | 110 | LocExitWithLastError(hr, "GetThreadPreferredUILanguages failed to return buffer size."); |
| 100 | } | 111 | } |
| @@ -103,7 +114,7 @@ extern "C" HRESULT DAPI LocProbeForFile( | |||
| 103 | LocExitOnFailure(hr, "Failed to allocate buffer for languages"); | 114 | LocExitOnFailure(hr, "Failed to allocate buffer for languages"); |
| 104 | 115 | ||
| 105 | nLangs = 0; | 116 | nLangs = 0; |
| 106 | if (!(*pvfnGetThreadPreferredUILanguages)(dwFlags, &nLangs, sczLangsBuff, &cchLangs)) | 117 | if (!(*pfnGetThreadPreferredUILanguages)(dwFlags, &nLangs, sczLangsBuff, &cchLangs)) |
| 107 | { | 118 | { |
| 108 | LocExitWithLastError(hr, "GetThreadPreferredUILanguages failed to return language list."); | 119 | LocExitWithLastError(hr, "GetThreadPreferredUILanguages failed to return language list."); |
| 109 | } | 120 | } |
| @@ -129,7 +140,7 @@ extern "C" HRESULT DAPI LocProbeForFile( | |||
| 129 | } | 140 | } |
| 130 | } | 141 | } |
| 131 | 142 | ||
| 132 | langid = ::GetUserDefaultUILanguage(); | 143 | langid = fUseUILanguage ? ::GetUserDefaultUILanguage() : ::GetUserDefaultLangID(); |
| 133 | 144 | ||
| 134 | hr = StrAllocFormatted(&sczLangIdFile, L"%u\\%ls", langid, wzLocFileName); | 145 | hr = StrAllocFormatted(&sczLangIdFile, L"%u\\%ls", langid, wzLocFileName); |
| 135 | LocExitOnFailure(hr, "Failed to format user langid."); | 146 | LocExitOnFailure(hr, "Failed to format user langid."); |
diff --git a/src/dutil/pathutil.cpp b/src/dutil/pathutil.cpp index ec338f71..183849ac 100644 --- a/src/dutil/pathutil.cpp +++ b/src/dutil/pathutil.cpp | |||
| @@ -215,6 +215,39 @@ LExit: | |||
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | 217 | ||
| 218 | DAPI_(HRESULT) PathGetParentPath( | ||
| 219 | __in_z LPCWSTR wzPath, | ||
| 220 | __out_z LPWSTR *psczParent | ||
| 221 | ) | ||
| 222 | { | ||
| 223 | HRESULT hr = S_OK; | ||
| 224 | LPCWSTR wzParent = NULL; | ||
| 225 | |||
| 226 | for (LPCWSTR wz = wzPath; *wz; ++wz) | ||
| 227 | { | ||
| 228 | if (wz[1] && (L'\\' == *wz || L'/' == *wz)) | ||
| 229 | { | ||
| 230 | wzParent = wz; | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | if (wzParent) | ||
| 235 | { | ||
| 236 | DWORD cchPath = static_cast<DWORD>(wzParent - wzPath) + 1; | ||
| 237 | |||
| 238 | hr = StrAllocString(psczParent, wzPath, cchPath); | ||
| 239 | PathExitOnFailure(hr, "Failed to copy directory."); | ||
| 240 | } | ||
| 241 | else | ||
| 242 | { | ||
| 243 | ReleaseNullStr(psczParent); | ||
| 244 | } | ||
| 245 | |||
| 246 | LExit: | ||
| 247 | return hr; | ||
| 248 | } | ||
| 249 | |||
| 250 | |||
| 218 | DAPI_(HRESULT) PathExpand( | 251 | DAPI_(HRESULT) PathExpand( |
| 219 | __out LPWSTR *psczFullPath, | 252 | __out LPWSTR *psczFullPath, |
| 220 | __in_z LPCWSTR wzRelativePath, | 253 | __in_z LPCWSTR wzRelativePath, |
diff --git a/src/dutil/sqlutil.cpp b/src/dutil/sqlutil.cpp index 63ee80ac..782c7088 100644 --- a/src/dutil/sqlutil.cpp +++ b/src/dutil/sqlutil.cpp | |||
| @@ -10,7 +10,22 @@ | |||
| 10 | #include "sqlutil.h" | 10 | #include "sqlutil.h" |
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | //Please note that only SQL native client 11 has TLS1.2 support | ||
| 14 | #define _SQLNCLI_OLEDB_DEPRECATE_WARNING | ||
| 15 | |||
| 16 | #if !defined(SQLNCLI_VER) | ||
| 17 | #define SQLNCLI_VER 1100 | ||
| 18 | #endif | ||
| 19 | |||
| 20 | #if SQLNCLI_VER >= 1100 | ||
| 21 | #if defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_) | ||
| 22 | #define SQLNCLI_CLSID CLSID_SQLNCLI11 | ||
| 23 | #endif // defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_) | ||
| 24 | extern const GUID OLEDBDECLSPEC _SQLNCLI_OLEDB_DEPRECATE_WARNING CLSID_SQLNCLI11 = { 0x397C2819L,0x8272,0x4532,{ 0xAD,0x3A,0xFB,0x5E,0x43,0xBE,0xAA,0x39 } }; | ||
| 25 | #endif // SQLNCLI_VER >= 1100 | ||
| 26 | |||
| 13 | // Exit macros | 27 | // Exit macros |
| 28 | #define SqlExitTrace(x, s, ...) ExitTraceSource(DUTIL_SOURCE_SQLUTIL, x, s, __VA_ARGS__) | ||
| 14 | #define SqlExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_SQLUTIL, x, s, __VA_ARGS__) | 29 | #define SqlExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_SQLUTIL, x, s, __VA_ARGS__) |
| 15 | #define SqlExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_SQLUTIL, x, s, __VA_ARGS__) | 30 | #define SqlExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_SQLUTIL, x, s, __VA_ARGS__) |
| 16 | #define SqlExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_SQLUTIL, x, s, __VA_ARGS__) | 31 | #define SqlExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_SQLUTIL, x, s, __VA_ARGS__) |
| @@ -25,11 +40,18 @@ | |||
| 25 | #define SqlExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_SQLUTIL, g, x, s, __VA_ARGS__) | 40 | #define SqlExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_SQLUTIL, g, x, s, __VA_ARGS__) |
| 26 | 41 | ||
| 27 | // private prototypes | 42 | // private prototypes |
| 43 | static HRESULT InitializeDatabaseConnection( | ||
| 44 | __in REFCLSID rclsid, | ||
| 45 | __in_z LPCSTR szFriendlyClsidName, | ||
| 46 | __in DBPROPSET rgdbpsetInit[], | ||
| 47 | __in_ecount(rgdbpsetInit) DWORD cdbpsetInit, | ||
| 48 | __out IDBCreateSession** ppidbSession | ||
| 49 | ); | ||
| 50 | HRESULT DumpErrorRecords(); | ||
| 28 | static HRESULT FileSpecToString( | 51 | static HRESULT FileSpecToString( |
| 29 | __in const SQL_FILESPEC* psf, | 52 | __in const SQL_FILESPEC* psf, |
| 30 | __out LPWSTR* ppwz | 53 | __out LPWSTR* ppwz |
| 31 | ); | 54 | ); |
| 32 | |||
| 33 | static HRESULT EscapeSqlIdentifier( | 55 | static HRESULT EscapeSqlIdentifier( |
| 34 | __in_z LPCWSTR wzDatabase, | 56 | __in_z LPCWSTR wzDatabase, |
| 35 | __deref_out_z LPWSTR* ppwz | 57 | __deref_out_z LPWSTR* ppwz |
| @@ -55,22 +77,11 @@ extern "C" HRESULT DAPI SqlConnectDatabase( | |||
| 55 | Assert(wzServer && wzDatabase && *wzDatabase && ppidbSession); | 77 | Assert(wzServer && wzDatabase && *wzDatabase && ppidbSession); |
| 56 | 78 | ||
| 57 | HRESULT hr = S_OK; | 79 | HRESULT hr = S_OK; |
| 58 | IDBInitialize* pidbInitialize = NULL; | ||
| 59 | IDBProperties* pidbProperties = NULL; | ||
| 60 | |||
| 61 | LPWSTR pwzServerInstance = NULL; | 80 | LPWSTR pwzServerInstance = NULL; |
| 62 | DBPROP rgdbpInit[4]; | 81 | DBPROP rgdbpInit[4] = { }; |
| 63 | DBPROPSET rgdbpsetInit[1]; | 82 | DBPROPSET rgdbpsetInit[1] = { }; |
| 64 | ULONG cProperties = 0; | 83 | ULONG cProperties = 0; |
| 65 | 84 | ||
| 66 | memset(rgdbpInit, 0, sizeof(rgdbpInit)); | ||
| 67 | memset(rgdbpsetInit, 0, sizeof(rgdbpsetInit)); | ||
| 68 | |||
| 69 | //obtain access to the SQLOLEDB provider | ||
| 70 | hr = ::CoCreateInstance(CLSID_SQLOLEDB, NULL, CLSCTX_INPROC_SERVER, | ||
| 71 | IID_IDBInitialize, (LPVOID*)&pidbInitialize); | ||
| 72 | SqlExitOnFailure(hr, "failed to create IID_IDBInitialize object"); | ||
| 73 | |||
| 74 | // if there is an instance | 85 | // if there is an instance |
| 75 | if (wzInstance && *wzInstance) | 86 | if (wzInstance && *wzInstance) |
| 76 | { | 87 | { |
| @@ -137,17 +148,23 @@ extern "C" HRESULT DAPI SqlConnectDatabase( | |||
| 137 | rgdbpsetInit[0].rgProperties = rgdbpInit; | 148 | rgdbpsetInit[0].rgProperties = rgdbpInit; |
| 138 | rgdbpsetInit[0].cProperties = cProperties; | 149 | rgdbpsetInit[0].cProperties = cProperties; |
| 139 | 150 | ||
| 140 | // create and set the property set | 151 | // obtain access to the SQL Native Client provider |
| 141 | hr = pidbInitialize->QueryInterface(IID_IDBProperties, (LPVOID*)&pidbProperties); | 152 | hr = InitializeDatabaseConnection(SQLNCLI_CLSID, "SQL Native Client", rgdbpsetInit, countof(rgdbpsetInit), ppidbSession); |
| 142 | SqlExitOnFailure(hr, "failed to get IID_IDBProperties object"); | 153 | if (FAILED(hr)) |
| 143 | hr = pidbProperties->SetProperties(1, rgdbpsetInit); | 154 | { |
| 144 | SqlExitOnFailure(hr, "failed to set properties"); | 155 | SqlExitTrace(hr, "Could not initialize SQL Native Client, falling back to SQL OLE DB..."); |
| 145 | |||
| 146 | //initialize connection to datasource | ||
| 147 | hr = pidbInitialize->Initialize(); | ||
| 148 | SqlExitOnFailure(hr, "failed to initialize connection to database: %ls", wzDatabase); | ||
| 149 | 156 | ||
| 150 | hr = pidbInitialize->QueryInterface(IID_IDBCreateSession, (LPVOID*)ppidbSession); | 157 | // try OLE DB but if that fails return original error failure |
| 158 | HRESULT hr2 = InitializeDatabaseConnection(CLSID_SQLOLEDB, "SQL OLE DB", rgdbpsetInit, countof(rgdbpsetInit), ppidbSession); | ||
| 159 | if (FAILED(hr2)) | ||
| 160 | { | ||
| 161 | SqlExitTrace(hr2, "Could not initialize SQL OLE DB either, giving up."); | ||
| 162 | } | ||
| 163 | else | ||
| 164 | { | ||
| 165 | hr = S_OK; | ||
| 166 | } | ||
| 167 | } | ||
| 151 | 168 | ||
| 152 | LExit: | 169 | LExit: |
| 153 | for (; 0 < cProperties; cProperties--) | 170 | for (; 0 < cProperties; cProperties--) |
| @@ -155,8 +172,6 @@ LExit: | |||
| 155 | ::VariantClear(&rgdbpInit[cProperties - 1].vValue); | 172 | ::VariantClear(&rgdbpInit[cProperties - 1].vValue); |
| 156 | } | 173 | } |
| 157 | 174 | ||
| 158 | ReleaseObject(pidbProperties); | ||
| 159 | ReleaseObject(pidbInitialize); | ||
| 160 | ReleaseStr(pwzServerInstance); | 175 | ReleaseStr(pwzServerInstance); |
| 161 | 176 | ||
| 162 | return hr; | 177 | return hr; |
| @@ -787,6 +802,110 @@ LExit: | |||
| 787 | // private | 802 | // private |
| 788 | // | 803 | // |
| 789 | 804 | ||
| 805 | static HRESULT InitializeDatabaseConnection( | ||
| 806 | __in REFCLSID rclsid, | ||
| 807 | __in_z LPCSTR szFriendlyClsidName, | ||
| 808 | __in DBPROPSET rgdbpsetInit[], | ||
| 809 | __in_ecount(rgdbpsetInit) DWORD cdbpsetInit, | ||
| 810 | __out IDBCreateSession** ppidbSession | ||
| 811 | ) | ||
| 812 | { | ||
| 813 | Unused(szFriendlyClsidName); // only used in DEBUG builds | ||
| 814 | |||
| 815 | HRESULT hr = S_OK; | ||
| 816 | IDBInitialize* pidbInitialize = NULL; | ||
| 817 | IDBProperties* pidbProperties = NULL; | ||
| 818 | |||
| 819 | hr = ::CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (LPVOID*)&pidbInitialize); | ||
| 820 | SqlExitOnFailure(hr, "failed to initialize %s", szFriendlyClsidName); | ||
| 821 | |||
| 822 | // create and set the property set | ||
| 823 | hr = pidbInitialize->QueryInterface(IID_IDBProperties, (LPVOID*)&pidbProperties); | ||
| 824 | SqlExitOnFailure(hr, "failed to get IID_IDBProperties for %s", szFriendlyClsidName); | ||
| 825 | |||
| 826 | hr = pidbProperties->SetProperties(cdbpsetInit, rgdbpsetInit); | ||
| 827 | SqlExitOnFailure(hr, "failed to set properties for %s", szFriendlyClsidName); | ||
| 828 | |||
| 829 | // initialize connection to datasource | ||
| 830 | hr = pidbInitialize->Initialize(); | ||
| 831 | if (FAILED(hr)) | ||
| 832 | { | ||
| 833 | DumpErrorRecords(); | ||
| 834 | } | ||
| 835 | SqlExitOnFailure(hr, "failed to initialize connection for %s", szFriendlyClsidName); | ||
| 836 | |||
| 837 | hr = pidbInitialize->QueryInterface(IID_IDBCreateSession, (LPVOID*)ppidbSession); | ||
| 838 | SqlExitOnFailure(hr, "failed to query for connection session for %s", szFriendlyClsidName); | ||
| 839 | |||
| 840 | LExit: | ||
| 841 | ReleaseObject(pidbProperties); | ||
| 842 | ReleaseObject(pidbInitialize); | ||
| 843 | |||
| 844 | return hr; | ||
| 845 | } | ||
| 846 | |||
| 847 | HRESULT DumpErrorRecords() | ||
| 848 | { | ||
| 849 | HRESULT hr = S_OK; | ||
| 850 | IErrorInfo* pIErrorInfo = NULL; | ||
| 851 | IErrorRecords* pIErrorRecords = NULL; | ||
| 852 | IErrorInfo* pIErrorInfoRecord = NULL; | ||
| 853 | BSTR bstrDescription = NULL; | ||
| 854 | ULONG i = 0; | ||
| 855 | ULONG cRecords = 0; | ||
| 856 | ERRORINFO ErrorInfo = { }; | ||
| 857 | |||
| 858 | // Get IErrorInfo pointer from OLE. | ||
| 859 | hr = ::GetErrorInfo(0, &pIErrorInfo); | ||
| 860 | if (FAILED(hr)) | ||
| 861 | { | ||
| 862 | ExitFunction(); | ||
| 863 | } | ||
| 864 | |||
| 865 | // QI for IID_IErrorRecords. | ||
| 866 | hr = pIErrorInfo->QueryInterface(IID_IErrorRecords, (void**)&pIErrorRecords); | ||
| 867 | if (FAILED(hr)) | ||
| 868 | { | ||
| 869 | ExitFunction(); | ||
| 870 | } | ||
| 871 | |||
| 872 | // Get error record count. | ||
| 873 | hr = pIErrorRecords->GetRecordCount(&cRecords); | ||
| 874 | if (FAILED(hr)) | ||
| 875 | { | ||
| 876 | ExitFunction(); | ||
| 877 | } | ||
| 878 | |||
| 879 | // Loop through the error records. | ||
| 880 | for (i = 0; i < cRecords; i++) | ||
| 881 | { | ||
| 882 | // Get pIErrorInfo from pIErrorRecords. | ||
| 883 | hr = pIErrorRecords->GetErrorInfo(i, 1033, &pIErrorInfoRecord); | ||
| 884 | |||
| 885 | if (SUCCEEDED(hr)) | ||
| 886 | { | ||
| 887 | // Get error description and source. | ||
| 888 | hr = pIErrorInfoRecord->GetDescription(&bstrDescription); | ||
| 889 | |||
| 890 | // Retrieve the ErrorInfo structures. | ||
| 891 | hr = pIErrorRecords->GetBasicErrorInfo(i, &ErrorInfo); | ||
| 892 | |||
| 893 | SqlExitTrace(ErrorInfo.hrError, "SQL error %lu/%lu: %ls", i + 1, cRecords, bstrDescription); | ||
| 894 | |||
| 895 | ReleaseNullObject(pIErrorInfoRecord); | ||
| 896 | ReleaseNullBSTR(bstrDescription); | ||
| 897 | } | ||
| 898 | } | ||
| 899 | |||
| 900 | LExit: | ||
| 901 | ReleaseNullBSTR(bstrDescription); | ||
| 902 | ReleaseObject(pIErrorInfoRecord); | ||
| 903 | ReleaseObject(pIErrorRecords); | ||
| 904 | ReleaseObject(pIErrorInfo); | ||
| 905 | |||
| 906 | return hr; | ||
| 907 | } | ||
| 908 | |||
| 790 | /******************************************************************** | 909 | /******************************************************************** |
| 791 | FileSpecToString | 910 | FileSpecToString |
| 792 | 911 | ||
