Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

584 lines
15 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998
  5. //
  6. // File:
  7. //
  8. // Contents:
  9. //
  10. // History:
  11. //---------------------------------------------------------------------------
  12. #include <windows.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <tchar.h>
  17. #include <odbcinst.h>
  18. #define STRSAFE_NO_DEPRECATE
  19. #include <strsafe.h>
  20. #define szSQLSetConfigMode "SQLSetConfigMode"
  21. //---------------------------------------------------------------------------
  22. // various installation routine we use, can't link with library as it will
  23. // cause
  24. #ifdef UNICODE
  25. #define szSQLInstallDriver "SQLInstallDriverW"
  26. #define szSQLGetInstalledDrivers "SQLGetInstalledDriversW"
  27. #define szSQLConfigDataSource "SQLConfigDataSourceW"
  28. #define szSQLGetPrivateProfileString "SQLGetPrivateProfileStringW"
  29. #define szSQLConfigDriver "SQLConfigDriverW"
  30. #define szSQLInstallerError "SQLInstallerErrorW"
  31. #else
  32. #define szSQLInstallDriver "SQLInstallDriver"
  33. #define szSQLGetInstalledDrivers "SQLGetInstalledDrivers"
  34. #define szSQLConfigDataSource "SQLConfigDataSource"
  35. #define szSQLGetPrivateProfileString "SQLGetPrivateProfileString"
  36. #define szSQLConfigDriver "SQLConfigDriver"
  37. #define szSQLInstallerError "SQLInstallerError"
  38. #endif
  39. //
  40. // ODBC install functions - To prevent system to 'force' odbccp32.dll
  41. // odbccp32 may not present on the system nor it is available at the
  42. // time setup got kick off.
  43. //
  44. typedef BOOL (* SQLCONFIGDATASOURCE)(HWND, WORD, LPCTSTR, LPCTSTR);
  45. typedef SQLRETURN (* SQLINSTALLERERROR)(WORD , DWORD*, LPTSTR, WORD, WORD*);
  46. typedef int (* SQLGETPRIVATEPROFILESTRING)( LPCTSTR lpszSection,
  47. LPCTSTR lpszEntry,
  48. LPCTSTR lpszDefault,
  49. LPTSTR lpszRetBuffer,
  50. int cbRetBuffer,
  51. LPCTSTR lpszFilename);
  52. typedef BOOL (* SQLINSTALLDRIVER)(LPCTSTR lpszInfFile,
  53. LPCTSTR lpszDriver,
  54. LPTSTR lpszPath,
  55. WORD cbPathMax,
  56. WORD* pcbPathOut);
  57. typedef BOOL (* SQLGETINSTALLEDDRIVER)(LPTSTR lpszBuf,
  58. WORD cbBufMax,
  59. WORD* pcbBufOut);
  60. typedef BOOL (* SQLSETCONFIGMODE)(UWORD wConfigMode);
  61. static SQLCONFIGDATASOURCE fpSQLConfigDataSource=NULL;
  62. static SQLINSTALLDRIVER fpSQLInstallDriver=NULL;
  63. static SQLINSTALLERERROR fpSQLInstallerError=NULL;
  64. static SQLGETPRIVATEPROFILESTRING fpSQLGetPrivateProfileString=NULL;
  65. static SQLSETCONFIGMODE fpSQLSetConfigMode=NULL;
  66. static SQLGETINSTALLEDDRIVER fpSQLGetInstalledDriver=NULL;
  67. static HINSTANCE hODBCCP32=NULL;
  68. //------------------------------------------------------------
  69. void
  70. ReportError(
  71. IN HWND hWnd,
  72. IN LPTSTR pszDefaultMsg
  73. )
  74. /*++
  75. Abstract:
  76. Popup a error message.
  77. Parameters:
  78. hWnd - Parent window handle.
  79. pszDefaultMsg - ignore.
  80. Returns:
  81. None.
  82. ++*/
  83. {
  84. #if DBG
  85. DWORD dwErrCode;
  86. TCHAR szErrMsg[2048];
  87. WORD szErrMsgSize=sizeof(szErrMsg)/sizeof(szErrMsg[0]);
  88. WORD cbErrMsg;
  89. fpSQLInstallerError(
  90. 1,
  91. &dwErrCode,
  92. szErrMsg,
  93. szErrMsgSize,
  94. &cbErrMsg
  95. );
  96. MessageBox(hWnd, szErrMsg, _TEXT("Setup Error"), MB_OK);
  97. #else
  98. return;
  99. #endif
  100. }
  101. //------------------------------------------------------------
  102. BOOL
  103. InitODBCSetup()
  104. /*++
  105. ++*/
  106. {
  107. hODBCCP32 = LoadLibrary(_TEXT("odbccp32"));
  108. if(hODBCCP32)
  109. {
  110. fpSQLConfigDataSource=(SQLCONFIGDATASOURCE)GetProcAddress(
  111. hODBCCP32,
  112. szSQLConfigDataSource
  113. );
  114. fpSQLInstallDriver=(SQLINSTALLDRIVER)GetProcAddress(
  115. hODBCCP32,
  116. szSQLInstallDriver
  117. );
  118. fpSQLInstallerError=(SQLINSTALLERERROR)GetProcAddress(
  119. hODBCCP32,
  120. szSQLInstallerError
  121. );
  122. fpSQLGetPrivateProfileString=(SQLGETPRIVATEPROFILESTRING)GetProcAddress(
  123. hODBCCP32,
  124. szSQLGetPrivateProfileString
  125. );
  126. fpSQLSetConfigMode=(SQLSETCONFIGMODE)GetProcAddress(
  127. hODBCCP32,
  128. szSQLSetConfigMode
  129. );
  130. fpSQLGetInstalledDriver=(SQLGETINSTALLEDDRIVER)GetProcAddress(
  131. hODBCCP32,
  132. szSQLGetInstalledDrivers
  133. );
  134. }
  135. if( hODBCCP32 == NULL || fpSQLConfigDataSource == NULL ||
  136. fpSQLInstallDriver == NULL || fpSQLInstallerError == NULL ||
  137. fpSQLGetPrivateProfileString == NULL || fpSQLSetConfigMode == NULL ||
  138. fpSQLGetInstalledDriver == NULL)
  139. {
  140. ReportError(NULL, _TEXT("Can't load odbccp32.dll "));
  141. return FALSE;
  142. }
  143. return TRUE;
  144. }
  145. //------------------------------------------------------------
  146. void
  147. CleanupODBCSetup()
  148. /*++
  149. ++*/
  150. {
  151. if(hODBCCP32)
  152. FreeLibrary(hODBCCP32);
  153. fpSQLConfigDataSource=NULL;
  154. fpSQLInstallDriver=NULL;
  155. fpSQLInstallerError=NULL;
  156. fpSQLGetPrivateProfileString=NULL;
  157. fpSQLSetConfigMode=NULL;
  158. fpSQLGetInstalledDriver=NULL;
  159. hODBCCP32=NULL;
  160. return;
  161. }
  162. //---------------------------------------------------------------------------
  163. //
  164. // Access Driver installation
  165. //
  166. LPTSTR szAccessDriver=_TEXT("Microsoft Access Driver (*.mdb)\0")
  167. _TEXT("Driver=odbcjt32.dll\0")
  168. _TEXT("Setup=odbcjt32.dll\0")
  169. _TEXT("Name=Microsoft Access Driver (*.mdb)\0")
  170. _TEXT("APILevel=1\0")
  171. _TEXT("ConnectFunctions=YYN\0")
  172. _TEXT("DriverODBCVer=02.50\0")
  173. //_TEXT("FileUsage=2\0")
  174. _TEXT("FileExtns=*.mdb\0")
  175. _TEXT("SQLLevel=0\0");
  176. //---------------------------------------------------------------------------
  177. BOOL
  178. IsDriverInstalled(
  179. IN LPTSTR szDriverName
  180. )
  181. /*++
  182. Abstract:
  183. Check if a ODBC driver installed on system.
  184. Parameters:
  185. szDriveName - Name of the drive.
  186. Returns:
  187. TRUE if driver installed, FALSE otherwise.
  188. ++*/
  189. {
  190. TCHAR szBuf[8096]; // this got to be enough
  191. WORD cbBufMax=sizeof(szBuf)/sizeof(szBuf[0]);
  192. WORD cbBufOut;
  193. LPTSTR pszBuf=szBuf;
  194. if(hODBCCP32 == NULL && !InitODBCSetup())
  195. return FALSE;
  196. if(fpSQLGetInstalledDriver(szBuf, cbBufMax, &cbBufOut))
  197. {
  198. ReportError(NULL, _TEXT("SQLGetInstalledDrivers"));
  199. }
  200. else
  201. {
  202. do {
  203. if(_tcsnicmp(szDriverName, pszBuf, min(lstrlen(szDriverName), lstrlen(pszBuf))) == 0)
  204. break;
  205. pszBuf += lstrlen(pszBuf) + 1;
  206. } while(pszBuf[1] != _TEXT('\0'));
  207. }
  208. return (pszBuf[1] != _TEXT('\0'));
  209. }
  210. //---------------------------------------------------------------------------
  211. BOOL
  212. IsDataSourceInstalled(
  213. IN LPTSTR pszDataSource,
  214. IN UWORD wConfigMode,
  215. IN OUT LPTSTR pszDbFile,
  216. IN DWORD cbBufSize
  217. )
  218. /*++
  219. Abstract:
  220. Check if a ODBC datasource are installed.
  221. Parameters:
  222. pszDataSource - name of data source.
  223. wConfigMode - configuration mode, refer to ODBC for detail,
  224. license server uses ODBC_SYSTEM_DSN.
  225. pszDbFile - Pointer to buffer for receving full path to database file
  226. if data source is installed.
  227. cbBufSize - size of buffer in characters.
  228. Returns:
  229. TRUE if datasource is installed, FALSE otherwise.
  230. ++*/
  231. {
  232. BOOL bSuccess = TRUE;
  233. if(hODBCCP32 == NULL && !InitODBCSetup())
  234. {
  235. bSuccess = FALSE;
  236. goto cleanup;
  237. }
  238. if(fpSQLSetConfigMode(wConfigMode) == FALSE)
  239. {
  240. ReportError(NULL, _TEXT("SQLSetConfigMode failed"));
  241. bSuccess = FALSE;
  242. goto cleanup;
  243. }
  244. if(fpSQLGetPrivateProfileString(
  245. pszDataSource,
  246. _TEXT("DBQ"),
  247. _TEXT(""),
  248. pszDbFile,
  249. cbBufSize,
  250. _TEXT("ODBC.INI")
  251. ) == 0)
  252. {
  253. bSuccess = FALSE;
  254. }
  255. cleanup:
  256. return bSuccess;
  257. }
  258. //---------------------------------------------------------------------------
  259. BOOL
  260. ConfigDataSource(
  261. HWND hWnd,
  262. BOOL bInstall, // TRUE to install FALSE to remove
  263. LPTSTR pszDriver, // driver
  264. LPTSTR pszDsn, // DSN
  265. LPTSTR pszUser, // User
  266. LPTSTR pszPwd, // Password
  267. LPTSTR pszMdbFile // MDB file
  268. )
  269. /*++
  270. Abstract:
  271. Routine to add/remove ODBC data source.
  272. Parameters:
  273. hWnd - Parent window handle.
  274. bInstall - TRUE if installing ODBC data source, FALSE otherwise.
  275. pszDrive - Name of the ODBC drive to be used on data source.
  276. pszDsn - ODBC Data Source Name.
  277. pszUser - Login use name.
  278. pszPwd - Login password.
  279. pszMdbFile - Name of the Database file.
  280. Returns:
  281. TRUE if successfule, FALSE otherwise.
  282. ++*/
  283. {
  284. TCHAR szAttributes[MAX_PATH*6+1];
  285. BOOL bConfig=TRUE;
  286. TCHAR *pszAttributesEnd;
  287. HRESULT hr;
  288. size_t cbRemaining;
  289. if(hODBCCP32 == NULL && !InitODBCSetup())
  290. return FALSE;
  291. //
  292. // for attribute string
  293. //
  294. memset(szAttributes, 0, sizeof(szAttributes));
  295. hr = StringCbCopyEx(szAttributes,sizeof(szAttributes),_TEXT("DSN="),&pszAttributesEnd, &cbRemaining,0);
  296. if (FAILED(hr))
  297. {
  298. return FALSE;
  299. }
  300. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,pszDsn,&pszAttributesEnd, &cbRemaining,0);
  301. if (FAILED(hr))
  302. {
  303. return FALSE;
  304. }
  305. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,_TEXT("UID="),&pszAttributesEnd, &cbRemaining,0);
  306. if (FAILED(hr))
  307. {
  308. return FALSE;
  309. }
  310. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,pszUser,&pszAttributesEnd, &cbRemaining,0);
  311. if (FAILED(hr))
  312. {
  313. return FALSE;
  314. }
  315. if(pszPwd)
  316. {
  317. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,_TEXT("PASSWORD="),&pszAttributesEnd, &cbRemaining,0);
  318. if (FAILED(hr))
  319. {
  320. return FALSE;
  321. }
  322. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,pszPwd,&pszAttributesEnd, &cbRemaining,0);
  323. if (FAILED(hr))
  324. {
  325. return FALSE;
  326. }
  327. }
  328. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,_TEXT("DBQ="),&pszAttributesEnd, &cbRemaining,0);
  329. if (FAILED(hr))
  330. {
  331. return FALSE;
  332. }
  333. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,pszMdbFile,&pszAttributesEnd, &cbRemaining,0);
  334. if (FAILED(hr))
  335. {
  336. return FALSE;
  337. }
  338. bConfig=fpSQLConfigDataSource(NULL,
  339. (WORD)((bInstall) ? ODBC_ADD_SYS_DSN : ODBC_REMOVE_SYS_DSN),
  340. pszDriver,
  341. szAttributes);
  342. // ignore error on uninstall
  343. if(!bConfig && bInstall)
  344. {
  345. ReportError(hWnd, _TEXT("Can't config data source"));
  346. }
  347. return bConfig;
  348. }
  349. BOOL
  350. RepairDataSource(
  351. HWND hWnd,
  352. LPTSTR pszDriver,
  353. LPTSTR pszDsn, // DSN
  354. LPTSTR pszUser, // User
  355. LPTSTR pszPwd, // Password
  356. LPTSTR pszMdbFile // MDB file
  357. )
  358. /*++
  359. Abstract:
  360. Routine to Compact/Repair a database file
  361. Parameters:
  362. hWnd - Parent window handle.
  363. pszDsn - ODBC Data Source Name.
  364. pszUser - Login use name.
  365. pszPwd - Login password.
  366. pszMdbFile - Name of the Database file.
  367. Returns:
  368. TRUE if successfule, FALSE otherwise.
  369. ++*/
  370. {
  371. TCHAR szAttributes[MAX_PATH*6+1];
  372. BOOL bConfig=TRUE;
  373. TCHAR* pszAttributesEnd;
  374. size_t cbRemaining;
  375. HRESULT hr;
  376. if(hODBCCP32 == NULL && !InitODBCSetup())
  377. return FALSE;
  378. //
  379. // for attribute string
  380. //
  381. memset(szAttributes, 0, sizeof(szAttributes));
  382. hr = StringCbCopyEx(szAttributes,sizeof(szAttributes),_TEXT("DSN="),&pszAttributesEnd, &cbRemaining,0);
  383. if (FAILED(hr))
  384. {
  385. return FALSE;
  386. }
  387. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,pszDsn,&pszAttributesEnd, &cbRemaining,0);
  388. if (FAILED(hr))
  389. {
  390. return FALSE;
  391. }
  392. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,_TEXT("UID="),&pszAttributesEnd, &cbRemaining,0);
  393. if (FAILED(hr))
  394. {
  395. return FALSE;
  396. }
  397. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,pszUser,&pszAttributesEnd, &cbRemaining,0);
  398. if (FAILED(hr))
  399. {
  400. return FALSE;
  401. }
  402. if(pszPwd)
  403. {
  404. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,_TEXT("PASSWORD="),&pszAttributesEnd, &cbRemaining,0);
  405. if (FAILED(hr))
  406. {
  407. return FALSE;
  408. }
  409. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,pszPwd,&pszAttributesEnd, &cbRemaining,0);
  410. if (FAILED(hr))
  411. {
  412. return FALSE;
  413. }
  414. }
  415. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,_TEXT("DBQ="),&pszAttributesEnd, &cbRemaining,0);
  416. if (FAILED(hr))
  417. {
  418. return FALSE;
  419. }
  420. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,pszMdbFile,&pszAttributesEnd, &cbRemaining,0);
  421. if (FAILED(hr))
  422. {
  423. return FALSE;
  424. }
  425. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,_TEXT("REPAIR_DB="),&pszAttributesEnd, &cbRemaining,0);
  426. if (FAILED(hr))
  427. {
  428. return FALSE;
  429. }
  430. hr = StringCbCopyEx(pszAttributesEnd,cbRemaining,pszMdbFile,&pszAttributesEnd, &cbRemaining,0);
  431. if (FAILED(hr))
  432. {
  433. return FALSE;
  434. }
  435. bConfig=fpSQLConfigDataSource(
  436. NULL,
  437. (WORD)ODBC_CONFIG_SYS_DSN,
  438. pszDriver,
  439. szAttributes
  440. );
  441. // ignore error on uninstall
  442. if(bConfig == FALSE)
  443. {
  444. ReportError(hWnd, _TEXT("Can't repair data source"));
  445. }
  446. return bConfig;
  447. }