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 | ||