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.

652 lines
23 KiB

  1. // regsvr.cpp : Program to invoke OLE self-registration on a DLL.
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1995 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12. #include <windows.h>
  13. #include <ole2.h>
  14. #include <tchar.h>
  15. #include <stdio.h>
  16. #include "resource.h"
  17. #define FAIL_ARGS 1
  18. #define FAIL_OLE 2
  19. #define FAIL_LOAD 3
  20. #define FAIL_ENTRY 4
  21. #define FAIL_REG 5
  22. const TCHAR _szAppName[] = _T("RegSvr32");
  23. const char _szDllInstall[] = "DllInstall";
  24. const TCHAR _tszDllInstall[] = TEXT("DllInstall");
  25. TCHAR _szDllPath[_MAX_PATH];
  26. // Leave room for "Ex" to be tacked onto end
  27. char _szDllRegSvr[32] = "DllRegisterServer";
  28. TCHAR _tszDllRegSvr[32] = TEXT("DllRegisterServer");
  29. char _szDllUnregSvr[32] = "DllUnregisterServer";
  30. TCHAR _tszDllUnregSvr[32] = TEXT("DllUnregisterServer");
  31. char _szRegContext[_MAX_PATH];
  32. HINSTANCE _hInstance;
  33. BOOL _bSilent;
  34. #define MAX_DLL_COUNT 255
  35. void
  36. FormatString3(
  37. LPTSTR lpszOut,
  38. LPCTSTR lpszFormat,
  39. LPCTSTR lpsz1,
  40. LPCTSTR lpsz2,
  41. LPCTSTR lpsz3
  42. )
  43. {
  44. LPCTSTR pchSrc = lpszFormat;
  45. LPTSTR pchDest = lpszOut;
  46. LPCTSTR pchTmp;
  47. while (*pchSrc != '\0') {
  48. if (pchSrc[0] == '%' && (pchSrc[1] >= '1' && pchSrc[1] <= '3')) {
  49. if (pchSrc[1] == '1')
  50. pchTmp = lpsz1;
  51. else if (pchSrc[1] == '2')
  52. pchTmp = lpsz2;
  53. else
  54. pchTmp = lpsz3;
  55. if (lstrlen(pchTmp) > MAX_PATH) {
  56. lstrcpyn(pchDest, pchTmp, MAX_PATH/2);
  57. lstrcat(pchDest, TEXT("..."));
  58. lstrcat(pchDest, pchTmp+lstrlen(pchTmp)-(MAX_PATH/2));
  59. } else {
  60. lstrcpy(pchDest, pchTmp);
  61. }
  62. pchDest += lstrlen(pchDest);
  63. pchSrc += 2;
  64. } else {
  65. if (_istlead(*pchSrc))
  66. *pchDest++ = *pchSrc++; // copy first of 2 bytes
  67. *pchDest++ = *pchSrc++;
  68. }
  69. }
  70. *pchDest = '\0';
  71. }
  72. #define MAX_STRING 1024
  73. void
  74. DisplayMessage(
  75. UINT ids,
  76. LPCTSTR pszArg1 = NULL,
  77. LPCTSTR pszArg2 = NULL,
  78. LPCTSTR pszArg3 = NULL,
  79. BOOL bUsage = FALSE,
  80. BOOL bInfo = FALSE
  81. )
  82. {
  83. if (_bSilent)
  84. return;
  85. TCHAR szFmt[MAX_STRING];
  86. LoadString(_hInstance, ids, szFmt, MAX_STRING);
  87. TCHAR szText[MAX_STRING];
  88. FormatString3(szText, szFmt, pszArg1, pszArg2, pszArg3);
  89. if (bUsage) {
  90. int cch = _tcslen(szText);
  91. LoadString(_hInstance, IDS_USAGE, szText + cch, MAX_STRING - cch);
  92. }
  93. if (! _bSilent)
  94. MessageBox(NULL, szText, _szAppName,
  95. MB_TASKMODAL | (bInfo ? MB_ICONINFORMATION : MB_ICONEXCLAMATION));
  96. }
  97. inline void
  98. Usage(
  99. UINT ids,
  100. LPCTSTR pszArg1 = NULL,
  101. LPCTSTR pszArg2 = NULL
  102. )
  103. {
  104. DisplayMessage(ids, pszArg1, pszArg2, NULL, TRUE);
  105. }
  106. inline void
  107. Info(
  108. UINT ids,
  109. LPCTSTR pszArg1 = NULL,
  110. LPCTSTR pszArg2 = NULL
  111. )
  112. {
  113. DisplayMessage(ids, pszArg1, pszArg2, NULL, FALSE, TRUE);
  114. }
  115. #define MAX_APPID 256
  116. BOOL IsContextRegFileType(LPCTSTR *ppszDllName)
  117. {
  118. HKEY hk1, hk2;
  119. LONG lRet;
  120. LONG cch;
  121. TCHAR szExt[_MAX_EXT];
  122. TCHAR szAppID[MAX_APPID];
  123. _tsplitpath(*ppszDllName, NULL, NULL, NULL, szExt);
  124. // Find [HKEY_CLASSES_ROOT\.foo]
  125. if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, szExt, 0, KEY_QUERY_VALUE, &hk1))
  126. return FALSE;
  127. // Read [HKEY_CLASSES_ROOT\.foo\"foo_auto_file"]
  128. cch = sizeof(szAppID);
  129. lRet = RegQueryValue(hk1, NULL, szAppID, &cch);
  130. RegCloseKey(hk1);
  131. if (ERROR_SUCCESS != lRet)
  132. return FALSE;
  133. // Find [HKEY_CLASSES_ROOT\foo_auto_file]
  134. if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, szAppID, 0, KEY_QUERY_VALUE, &hk1))
  135. return FALSE;
  136. // Find [HKEY_CLASSES_ROOT\foo_auto_file\AutoRegister]
  137. if (ERROR_SUCCESS != RegOpenKeyEx(hk1, TEXT("AutoRegister"), 0, KEY_QUERY_VALUE, &hk2))
  138. {
  139. RegCloseKey(hk1);
  140. return FALSE;
  141. }
  142. // Read [HKEY_CLASSES_ROOT\foo_auto_file\AutoRegister\"d:\...\fooreg.dll"]
  143. cch = MAX_PATH;
  144. lRet = RegQueryValue(hk2, NULL, _szDllPath, &cch);
  145. RegCloseKey(hk1);
  146. RegCloseKey(hk2);
  147. if (ERROR_SUCCESS != lRet)
  148. return FALSE;
  149. _szDllPath[cch] = TEXT('\0');
  150. *ppszDllName = _szDllPath;
  151. return TRUE;
  152. }
  153. int PASCAL
  154. _tWinMain(
  155. HINSTANCE hInstance,
  156. HINSTANCE,
  157. LPSTR,
  158. int
  159. )
  160. {
  161. int iReturn = 0;
  162. HRESULT (STDAPICALLTYPE * lpDllEntryPointReg)(void);
  163. HRESULT (STDAPICALLTYPE * lpDllEntryPointRegEx)(LPCSTR);
  164. HRESULT (STDAPICALLTYPE * lpDllEntryPointRegExW)(LPCWSTR);
  165. HRESULT (STDAPICALLTYPE * lpDllEntryPointInstall)(BOOL, LPWSTR);
  166. HRESULT rc;
  167. BOOL bVisualC = FALSE;
  168. BOOL bUnregister = FALSE;
  169. BOOL bCallDllInstall = FALSE;
  170. BOOL bCallDllRegisterServer = TRUE;
  171. BOOL bErrorsOnly = FALSE;
  172. BOOL bContextReg = FALSE;
  173. BOOL bUnicodeContextReg = FALSE;
  174. LPSTR pszDllEntryPoint = _szDllRegSvr;
  175. LPTSTR ptszDllEntryPoint = _tszDllRegSvr;
  176. LPTSTR pszTok;
  177. LPCTSTR pszDllName;
  178. LPSTR pszContext;
  179. LPCTSTR pszContextW;
  180. TCHAR pszDllInstallCmdLine[MAX_PATH+1];
  181. #ifdef UNICODE
  182. PWCHAR pwszDllInstallCmdLine = pszDllInstallCmdLine;
  183. #else
  184. WCHAR pwszDllInstallCmdLine[MAX_PATH+1];
  185. #endif
  186. int iNumDllsToRegister = 0;
  187. int iCount;
  188. LPCTSTR ppszDllNames[MAX_DLL_COUNT];
  189. TCHAR szError[1024];
  190. _hInstance = hInstance;
  191. // Parse command line arguments.
  192. int iTok;
  193. for (iTok = 1; iTok < __argc; iTok++) {
  194. pszTok = __targv[iTok];
  195. if ((pszTok[0] == TEXT('-')) || (pszTok[0] == TEXT('/'))) {
  196. switch (pszTok[1]) {
  197. case TEXT('e'):
  198. case TEXT('E'):
  199. bErrorsOnly = TRUE;
  200. break;
  201. case TEXT('i'):
  202. case TEXT('I'):
  203. bCallDllInstall = TRUE;
  204. if (pszTok[2] == TEXT(':'))
  205. {
  206. if (pszTok[3] == TEXT('"')) {
  207. // handle quoted InstallCmdLine (
  208. // (e.g. /i:"c:\my dll dir\mydll.dll")
  209. LPTSTR pszEndQuote = &pszTok[4];
  210. int iLength = lstrlen(pszEndQuote);
  211. if (iLength > MAX_PATH) {
  212. if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
  213. ERROR_FILENAME_EXCED_RANGE, 0, szError, sizeof(szError)/sizeof(szError[0]), NULL)) {
  214. DisplayMessage(IDS_LOADLIBFAILED, pszEndQuote, szError);
  215. }
  216. return FAIL_ARGS;
  217. }
  218. if ((iLength > 0) && pszEndQuote[iLength - 1] == TEXT('"')) {
  219. // they quoted the string but it wasent really necessary
  220. // (e.g. /i:"shell32.dll")
  221. pszEndQuote[iLength - 1] = TEXT('\0');
  222. lstrcpy(pszDllInstallCmdLine, pszEndQuote);
  223. } else {
  224. // we have a quoted string that spans multiple tokens
  225. lstrcpy(pszDllInstallCmdLine, pszEndQuote);
  226. for (iTok++; iTok < __argc; iTok++) {
  227. // grab the next token
  228. pszEndQuote = __targv[iTok];
  229. iLength = lstrlen(pszEndQuote);
  230. if (lstrlen(pszDllInstallCmdLine) + iLength + 1 > MAX_PATH) {
  231. if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
  232. ERROR_FILENAME_EXCED_RANGE, 0, szError, sizeof(szError)/sizeof(szError[0]), NULL)) {
  233. DisplayMessage(IDS_LOADLIBFAILED, pszDllInstallCmdLine, szError);
  234. }
  235. return FAIL_ARGS;
  236. }
  237. if ((iLength > 0) && (pszEndQuote[iLength - 1] == '"')) {
  238. pszEndQuote[iLength - 1] = TEXT('\0');
  239. lstrcat(pszDllInstallCmdLine, TEXT(" "));
  240. lstrcat(pszDllInstallCmdLine, pszEndQuote);
  241. break;
  242. }
  243. lstrcat(pszDllInstallCmdLine, TEXT(" "));
  244. lstrcat(pszDllInstallCmdLine, pszEndQuote);
  245. }
  246. }
  247. } else {
  248. if (lstrlen(&pszTok[3]) > MAX_PATH) {
  249. if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
  250. ERROR_FILENAME_EXCED_RANGE, 0, szError, sizeof(szError)/sizeof(szError[0]), NULL)) {
  251. DisplayMessage(IDS_LOADLIBFAILED, &pszTok[3], szError);
  252. }
  253. return FAIL_ARGS;
  254. }
  255. // cmd line is NOT quoted
  256. lstrcpy(pszDllInstallCmdLine, &pszTok[3]);
  257. }
  258. #ifndef UNICODE
  259. if (!MultiByteToWideChar(CP_ACP,
  260. 0,
  261. (LPCTSTR)pszDllInstallCmdLine,
  262. -1,
  263. pwszDllInstallCmdLine,
  264. MAX_PATH))
  265. {
  266. Usage(IDS_UNRECOGNIZEDFLAG, pszTok);
  267. return FAIL_ARGS;
  268. }
  269. #endif
  270. }
  271. else
  272. {
  273. lstrcpyW((LPWSTR)pwszDllInstallCmdLine, L"");
  274. }
  275. break;
  276. case TEXT('n'):
  277. case TEXT('N'):
  278. bCallDllRegisterServer = FALSE;
  279. break;
  280. case TEXT('s'):
  281. case TEXT('S'):
  282. _bSilent = TRUE;
  283. break;
  284. case TEXT('u'):
  285. case TEXT('U'):
  286. bUnregister = TRUE;
  287. pszDllEntryPoint = _szDllUnregSvr;
  288. ptszDllEntryPoint = _tszDllUnregSvr;
  289. break;
  290. case TEXT('v'):
  291. case TEXT('V'):
  292. bVisualC = TRUE;
  293. break;
  294. case TEXT('c'):
  295. case TEXT('C'):
  296. // Ignore this
  297. break;
  298. default:
  299. Usage(IDS_UNRECOGNIZEDFLAG, pszTok);
  300. return FAIL_ARGS;
  301. }
  302. } else {
  303. if (pszTok[0] == TEXT('"')) {
  304. // handle quoted DllName
  305. TCHAR szTemp[MAX_PATH+1];
  306. LPTSTR pszQuotedDllName;
  307. int iLength;
  308. iLength = lstrlen(&pszTok[1]);
  309. if (iLength > MAX_PATH) {
  310. if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
  311. ERROR_FILENAME_EXCED_RANGE, 0, szError, sizeof(szError)/sizeof(szError[0]), NULL)) {
  312. DisplayMessage(IDS_LOADLIBFAILED, &pszTok[3], szError);
  313. }
  314. return FAIL_ARGS;
  315. }
  316. lstrcpy(szTemp, &pszTok[1]);
  317. if ((iLength > 0) && szTemp[iLength - 1] != TEXT('"')) {
  318. // handle quoted dll name that spans multiple tokens
  319. for (iTok++; iTok < __argc; iTok++) {
  320. iLength = lstrlen(__targv[iTok]);
  321. if (lstrlen(szTemp) + iLength + 1 > MAX_PATH) {
  322. if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
  323. ERROR_FILENAME_EXCED_RANGE, 0, szError, sizeof(szError)/sizeof(szError[0]), NULL)) {
  324. DisplayMessage(IDS_LOADLIBFAILED, szTemp, szError);
  325. }
  326. return FAIL_ARGS;
  327. }
  328. lstrcat(szTemp, TEXT(" "));
  329. lstrcat(szTemp, __targv[iTok]);
  330. if ((iLength > 0) && __targv[iTok][iLength - 1] == TEXT('"')) {
  331. // this token has the end quote, so stop here
  332. break;
  333. }
  334. }
  335. }
  336. iLength = lstrlen(szTemp);
  337. // remove the trailing " if one exists
  338. if ( (iLength > 0) && (szTemp[iLength - 1] == TEXT('"')) ) {
  339. szTemp[iLength - 1] = TEXT('\0');
  340. }
  341. pszQuotedDllName = (LPTSTR) LocalAlloc(LPTR, (iLength + 1) * sizeof(TCHAR));
  342. if (pszQuotedDllName)
  343. {
  344. if (iNumDllsToRegister == MAX_DLL_COUNT) {
  345. Usage(IDS_UNRECOGNIZEDFLAG, TEXT("Excessive # of DLL's on cmdline"));
  346. return FAIL_ARGS;
  347. }
  348. lstrcpy(pszQuotedDllName, szTemp);
  349. ppszDllNames[iNumDllsToRegister] = pszQuotedDllName;
  350. iNumDllsToRegister++;
  351. }
  352. } else {
  353. // no leading " so assume that this token is one of the dll names
  354. if (iNumDllsToRegister == MAX_DLL_COUNT) {
  355. Usage(IDS_UNRECOGNIZEDFLAG, TEXT("Excessive # of DLL's on cmdline"));
  356. return FAIL_ARGS;
  357. }
  358. if (lstrlen(pszTok) > MAX_PATH) {
  359. if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
  360. ERROR_FILENAME_EXCED_RANGE, 0, szError, sizeof(szError)/sizeof(szError[0]), NULL)) {
  361. DisplayMessage(IDS_LOADLIBFAILED, pszTok, szError);
  362. }
  363. return FAIL_ARGS;
  364. }
  365. ppszDllNames[iNumDllsToRegister] = pszTok;
  366. iNumDllsToRegister++;
  367. }
  368. }
  369. }
  370. // check to see if we were passed a '-n' but no '-i'
  371. if (!bCallDllRegisterServer && !bCallDllInstall) {
  372. Usage(IDS_UNRECOGNIZEDFLAG, TEXT("/n must be used with the /i switch"));
  373. return FAIL_ARGS;
  374. }
  375. if (iNumDllsToRegister == 0) {
  376. if (bVisualC)
  377. DisplayMessage(IDS_NOPROJECT);
  378. else
  379. Usage(IDS_NODLLNAME);
  380. return FAIL_ARGS;
  381. }
  382. // Initialize OLE.
  383. __try {
  384. rc = OleInitialize(NULL);
  385. } __except (EXCEPTION_EXECUTE_HANDLER) {
  386. rc = (HRESULT) GetExceptionCode();
  387. }
  388. if (FAILED(rc)) {
  389. DisplayMessage(IDS_OLEINITFAILED);
  390. return FAIL_OLE;
  391. }
  392. if (_bSilent) {
  393. SetErrorMode(SEM_FAILCRITICALERRORS); // Make sure LoadLib fail in silent mode (no popups).
  394. }
  395. for (iCount = 0; iCount < iNumDllsToRegister; iCount++) {
  396. pszDllName = ppszDllNames[iCount];
  397. /*
  398. * See if this is a non-executable file that requires special handling. If so,
  399. * bContextReg will be set to TRUE and pszDllName (which original pointed to
  400. * the path to the special file) will be set to the path to the executable that
  401. * is responsible for doing the actual registration. The path to the special
  402. * file will be passed in as context info in the call Dll[Un]RegisterServerEx.
  403. */
  404. pszContextW = pszDllName;
  405. pszContext = (LPSTR)pszContextW;
  406. bContextReg = IsContextRegFileType(&pszDllName);
  407. if (TRUE == bContextReg) {
  408. lstrcatA(pszDllEntryPoint, "Ex");
  409. lstrcat(ptszDllEntryPoint, TEXT("Ex"));
  410. // Convert pszContext to a real char *
  411. #ifdef UNICODE
  412. if (!WideCharToMultiByte(CP_ACP,
  413. 0,
  414. (LPCWSTR)pszContext,
  415. lstrlenW((LPCWSTR)pszContext),
  416. _szRegContext,
  417. sizeof(_szRegContext),
  418. 0,
  419. NULL))
  420. {
  421. Usage(IDS_UNRECOGNIZEDFLAG, pszTok);
  422. return FAIL_ARGS;
  423. } else {
  424. pszContext = _szRegContext;
  425. }
  426. #endif
  427. }
  428. // Load the library -- fail silently if problems
  429. UINT errMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  430. HINSTANCE hLib = LoadLibraryEx(pszDllName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
  431. SetErrorMode(errMode);
  432. if (hLib < (HINSTANCE)HINSTANCE_ERROR) {
  433. DWORD dwErr = GetLastError();
  434. if (ERROR_BAD_EXE_FORMAT == dwErr) {
  435. DisplayMessage(IDS_NOTEXEORHELPER, pszDllName);
  436. } else {
  437. if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
  438. dwErr, 0, szError, sizeof(szError)/sizeof(szError[0]), NULL)) {
  439. DisplayMessage(IDS_LOADLIBFAILED, pszDllName, szError);
  440. }
  441. }
  442. iReturn = FAIL_LOAD;
  443. goto CleanupOle;
  444. }
  445. // during unregister we need to call DllInstall first, and then DllUnregisterServer
  446. if (bUnregister)
  447. goto DllInstall;
  448. DllRegisterServer:
  449. // Call the entry point for DllRegisterServer/DllUnregisterServer
  450. if (bCallDllRegisterServer) {
  451. if (bContextReg) {
  452. (FARPROC&)lpDllEntryPointRegEx = GetProcAddress(hLib, "DllRegisterServerExW");
  453. if (lpDllEntryPointRegEx) {
  454. (FARPROC&)lpDllEntryPointRegExW = (FARPROC&)lpDllEntryPointRegEx;
  455. bUnicodeContextReg = TRUE;
  456. } else {
  457. (FARPROC&)lpDllEntryPointRegEx = GetProcAddress(hLib, "DllRegisterServerEx");
  458. }
  459. (FARPROC&)lpDllEntryPointReg = (FARPROC&)lpDllEntryPointRegEx;
  460. } else {
  461. (FARPROC&)lpDllEntryPointReg = (FARPROC&)lpDllEntryPointRegEx = GetProcAddress(hLib, pszDllEntryPoint);
  462. }
  463. if (lpDllEntryPointReg == NULL) {
  464. TCHAR szExt[_MAX_EXT];
  465. _tsplitpath(pszDllName, NULL, NULL, NULL, szExt);
  466. if (FALSE == bContextReg && (lstrcmp(szExt, TEXT(".dll")) != 0) && (lstrcmp(szExt, TEXT(".ocx")) != 0))
  467. DisplayMessage(IDS_NOTDLLOROCX, pszDllName, ptszDllEntryPoint);
  468. else
  469. DisplayMessage(IDS_NOENTRYPOINT, pszDllName, ptszDllEntryPoint);
  470. iReturn = FAIL_ENTRY;
  471. goto CleanupLibrary;
  472. }
  473. // try calling DllRegisterServer[Ex]() / DllUnregisterServer[Ex]()
  474. __try {
  475. if (bUnicodeContextReg) {
  476. rc = (*lpDllEntryPointRegExW)(pszContextW);
  477. } else {
  478. if (bContextReg) {
  479. rc = (*lpDllEntryPointRegEx)(pszContext);
  480. } else {
  481. rc = (*lpDllEntryPointReg)();
  482. }
  483. }
  484. } __except(EXCEPTION_EXECUTE_HANDLER) {
  485. rc = (HRESULT) GetExceptionCode();
  486. }
  487. if (FAILED(rc)) {
  488. wsprintf(szError, _T("0x%08lx"), rc);
  489. DisplayMessage(IDS_CALLFAILED, ptszDllEntryPoint, pszDllName, szError);
  490. iReturn = FAIL_REG;
  491. goto CleanupLibrary;
  492. }
  493. }
  494. // during unregister we need to call DllInstall first, then DllRegisterServer,
  495. // since we already called DllInstall and then jumped back up to DllRegisterServer:
  496. // skip over it and goto CheckErrors:
  497. if (bUnregister)
  498. goto CheckErrors;
  499. DllInstall:
  500. // Call the entry point for DllInstall
  501. if (bCallDllInstall) {
  502. (FARPROC&)lpDllEntryPointInstall = GetProcAddress(hLib, _szDllInstall);
  503. if (lpDllEntryPointInstall == NULL) {
  504. TCHAR szExt[_MAX_EXT];
  505. _tsplitpath(pszDllName, NULL, NULL, NULL, szExt);
  506. if ((lstrcmp(szExt, TEXT(".dll")) != 0) && (lstrcmp(szExt, TEXT(".ocx")) != 0))
  507. DisplayMessage(IDS_NOTDLLOROCX, pszDllName, _tszDllInstall);
  508. else
  509. DisplayMessage(IDS_NOENTRYPOINT, pszDllName, _tszDllInstall);
  510. iReturn = FAIL_ENTRY;
  511. goto CleanupLibrary;
  512. }
  513. // try calling DllInstall(BOOL bRegister, LPWSTR lpwszCmdLine) here...
  514. // NOTE: the lpwszCmdLine string must be UNICODE!
  515. __try {
  516. rc = (*lpDllEntryPointInstall)(!bUnregister, pwszDllInstallCmdLine);
  517. } __except(EXCEPTION_EXECUTE_HANDLER) {
  518. rc = (HRESULT) GetExceptionCode();
  519. }
  520. if (FAILED(rc)) {
  521. wsprintf(szError, _T("0x%08lx"), rc);
  522. DisplayMessage(IDS_CALLFAILED, _tszDllInstall, pszDllName, szError);
  523. iReturn = FAIL_REG;
  524. goto CleanupLibrary;
  525. }
  526. }
  527. // during unregister we now need to call DllUnregisterServer
  528. if (bUnregister)
  529. goto DllRegisterServer;
  530. CheckErrors:
  531. if (!bErrorsOnly) {
  532. TCHAR szMessage[MAX_PATH];
  533. // set up the success message text
  534. if (bCallDllRegisterServer)
  535. {
  536. lstrcpy(szMessage, ptszDllEntryPoint);
  537. if (bCallDllInstall)
  538. {
  539. lstrcat(szMessage, TEXT(" and "));
  540. lstrcat(szMessage, _tszDllInstall);
  541. }
  542. }
  543. else if (bCallDllInstall)
  544. {
  545. lstrcpy(szMessage, _tszDllInstall);
  546. }
  547. Info(IDS_CALLSUCCEEDED, szMessage, pszDllName);
  548. }
  549. CleanupLibrary:
  550. FreeLibrary(hLib);
  551. }
  552. CleanupOle:
  553. __try {
  554. OleUninitialize();
  555. } __except (EXCEPTION_EXECUTE_HANDLER) {
  556. DisplayMessage(IDS_OLEUNINITFAILED);
  557. }
  558. return iReturn;
  559. }