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.

746 lines
25 KiB

  1. //#pragma title("TFile - Install File class")
  2. /*---------------------------------------------------------------------------
  3. File: TFile.CPP
  4. Comments: This file contains file installation functions.
  5. (c) Copyright 1995-1999, Mission Critical Software, Inc., All Rights Reserved
  6. Proprietary and confidential to Mission Critical Software, Inc.
  7. REVISION LOG ENTRY
  8. Author: Juan Medrano l
  9. Revision By: Christy Boles
  10. Revised on 7/9/97
  11. ---------------------------------------------------------------------------*/
  12. #ifdef USE_STDAFX
  13. #include "stdafx.h"
  14. #else
  15. #include <windows.h>
  16. #endif
  17. #include <tchar.h>
  18. #include "Common.hpp"
  19. #include "UString.hpp"
  20. #include "ErrDct.hpp"
  21. #include "TReg.hpp"
  22. #include "TFile.hpp"
  23. #ifdef _DEBUG
  24. #define new DEBUG_NEW
  25. #undef THIS_FILE
  26. static char THIS_FILE[] = __FILE__;
  27. #endif
  28. extern TErrorDct err;
  29. //----------------------------------------------------------------------------
  30. // TInstallFile::TInstallFile - constructor initializes variables and if
  31. // pszFileDir is specified, it will get file information for the file located
  32. // in that directory.
  33. //----------------------------------------------------------------------------
  34. TInstallFile::TInstallFile(
  35. TCHAR const * pszFileName, // in -file name (not a full path)
  36. TCHAR const * pszFileDir, // in -directory path (without file name)
  37. BOOL silent
  38. )
  39. {
  40. m_bCopyNeeded = FALSE;
  41. m_VersionInfo = NULL;
  42. m_dwLanguageCode = 0;
  43. m_szFileName[0] = 0;
  44. m_szFilePath[0] = 0;
  45. m_szTargetPath[0] = 0;
  46. m_szFileVersion[0] = 0;
  47. m_szFileSize[0] = 0;
  48. m_szFileDateTime[0] = 0;
  49. m_bSilent = silent;
  50. ZeroMemory( &m_FixedFileInfo, sizeof m_FixedFileInfo );
  51. ZeroMemory( &m_FileData, sizeof m_FileData );
  52. if ( pszFileName )
  53. {
  54. safecopy(m_szFileName,pszFileName);
  55. }
  56. if ( pszFileDir )
  57. {
  58. OpenFileInfo( pszFileDir );
  59. }
  60. }
  61. //----------------------------------------------------------------------------
  62. // TInstallFile::OpenFileInfo - gathers file information (file size, mod time,
  63. // version info) and stores it in member variables for later use.
  64. //----------------------------------------------------------------------------
  65. DWORD // ret -last OS return code
  66. TInstallFile::OpenFileInfo(
  67. TCHAR const * pszFileDir // in -directory path (without filename)
  68. )
  69. {
  70. DWORD rc = 0; // OS return code
  71. DWORD dwBytes; // version info structure size
  72. DWORD dwHandle; // version info handle
  73. DWORD * dwVerPointer; // pointer to version language code
  74. UINT uBytes; // version info size
  75. HANDLE hFile; // file handle
  76. VS_FIXEDFILEINFO * lpBuffer; // pointer to version info structure
  77. // construct a full path for the file
  78. safecopy(m_szFilePath,pszFileDir);
  79. UStrCpy(m_szFilePath + UStrLen(m_szFilePath),TEXT("\\"));
  80. UStrCpy(m_szFilePath + UStrLen(m_szFilePath),m_szFileName);
  81. // get file size, mod time info
  82. hFile = FindFirstFile( m_szFilePath, &m_FileData );
  83. if ( hFile == INVALID_HANDLE_VALUE )
  84. {
  85. rc = GetLastError();
  86. if ( ! m_bSilent )
  87. {
  88. err.SysMsgWrite( 0,
  89. rc,
  90. DCT_MSG_OPEN_FILE_INFO_FAILED_SD,
  91. m_szFilePath,
  92. rc );
  93. }
  94. }
  95. else
  96. {
  97. FindClose( hFile );
  98. dwBytes = GetFileVersionInfoSize( m_szFilePath, &dwHandle );
  99. if ( dwBytes <= 0 )
  100. {
  101. //err.MsgWrite( 0,
  102. // "No version resource: %ls",
  103. // m_szFilePath );
  104. }
  105. else
  106. {
  107. delete [] m_VersionInfo;
  108. m_VersionInfo = new WCHAR[dwBytes + 1];
  109. // get version resource info
  110. if ( ! GetFileVersionInfo( m_szFilePath,
  111. 0,
  112. dwBytes,
  113. m_VersionInfo ) )
  114. {
  115. rc = GetLastError();
  116. if ( ! m_bSilent )
  117. {
  118. err.SysMsgWrite( 0,
  119. rc,
  120. DCT_MSG_GET_VERSION_INFO_FAILED_SD,
  121. m_szFilePath,
  122. rc );
  123. }
  124. }
  125. else
  126. {
  127. // get fixed file info
  128. if ( ! VerQueryValue( m_VersionInfo,
  129. TEXT("\\"),
  130. (void **) &lpBuffer,
  131. &uBytes) )
  132. {
  133. if ( ! m_bSilent )
  134. {
  135. err.MsgWrite( 0,
  136. DCT_MSG_VER_QUERY_VALUE_FAILED_SS,
  137. m_szFilePath,
  138. L"\\");
  139. }
  140. }
  141. else
  142. {
  143. m_FixedFileInfo = *lpBuffer;
  144. // get variable file info language code
  145. if ( ! VerQueryValue( m_VersionInfo,
  146. TEXT("\\VarFileInfo\\Translation"),
  147. (void **) &dwVerPointer,
  148. &uBytes) )
  149. {
  150. if ( ! m_bSilent )
  151. {
  152. err.MsgWrite( 0,
  153. DCT_MSG_VER_QUERY_VALUE_FAILED_SS,
  154. m_szFilePath,
  155. L"\\VarFileInfo\\Translation");
  156. }
  157. }
  158. else
  159. {
  160. m_dwLanguageCode = *dwVerPointer;
  161. }
  162. }
  163. }
  164. }
  165. }
  166. return rc;
  167. }
  168. //----------------------------------------------------------------------------
  169. // TInstallFile::CopyTo - copies the file to a destination path. if it is busy,
  170. // renames the file and tries to copy again.
  171. //----------------------------------------------------------------------------
  172. DWORD // ret -last OS return code
  173. TInstallFile::CopyTo(
  174. TCHAR const * pszDestinationPath // in -destination path (full path)
  175. )
  176. {
  177. DWORD rc = 0; // OS return code
  178. DWORD dwFileAttributes; // file attribute mask
  179. // make sure read-only flag of destination is turned off
  180. dwFileAttributes = ::GetFileAttributes( pszDestinationPath );
  181. if ( dwFileAttributes != 0xFFFFFFFF )
  182. {
  183. // Turn off read-only file attribute
  184. if ( dwFileAttributes & FILE_ATTRIBUTE_READONLY )
  185. {
  186. ::SetFileAttributes( pszDestinationPath,
  187. dwFileAttributes & ~FILE_ATTRIBUTE_READONLY );
  188. }
  189. }
  190. // copy file to destination path
  191. if ( ! ::CopyFile( m_szFilePath, pszDestinationPath, FALSE ) )
  192. {
  193. rc = GetLastError();
  194. err.SysMsgWrite( 0,
  195. rc,
  196. DCT_MSG_COPY_FILE_FAILED_SSD,
  197. m_szFilePath,
  198. pszDestinationPath,
  199. rc );
  200. }
  201. return rc;
  202. }
  203. //----------------------------------------------------------------------------
  204. // TInstallFile::CompareFile - compares the version, date, and size of the
  205. // file object to the given target file object
  206. //----------------------------------------------------------------------------
  207. int // ret -(-1) if source < target
  208. TInstallFile::CompareFile( // ( 0) if source = target
  209. // ( 1) if source > target
  210. TInstallFile * pFileTrg // in -target file object
  211. )
  212. {
  213. int nComp; // comparison result
  214. nComp = CompareFileVersion( pFileTrg );
  215. if ( nComp == 0 )
  216. {
  217. // versions are the same, compare dates
  218. nComp = CompareFileDateTime( pFileTrg );
  219. if ( nComp <= 0 )
  220. {
  221. // source date is less than or equal to target date
  222. // compare file size
  223. nComp = CompareFileSize( pFileTrg );
  224. if ( nComp != 0 )
  225. {
  226. // file sizes are not equal, return (source > target)
  227. nComp = 1;
  228. }
  229. }
  230. }
  231. return nComp;
  232. }
  233. //----------------------------------------------------------------------------
  234. // TInstallFile::CompareFileSize - compares the file size of the this file
  235. // object with the size of the target file object
  236. //----------------------------------------------------------------------------
  237. int // ret -(-1) if source < target
  238. TInstallFile::CompareFileSize( // ( 0) if source = target
  239. // ( 1) if source > target
  240. TInstallFile * pFileTrg // in -target file object
  241. )
  242. {
  243. int nCompResult = 0; // comparison result
  244. DWORD dwSrcFileSize = 0; // source file size
  245. DWORD dwTrgFileSize = 0; // target file size
  246. dwSrcFileSize = m_FileData.nFileSizeLow;
  247. dwTrgFileSize = pFileTrg->m_FileData.nFileSizeLow;
  248. if ( dwSrcFileSize && dwTrgFileSize )
  249. {
  250. if ( dwSrcFileSize < dwTrgFileSize )
  251. {
  252. nCompResult = -1;
  253. }
  254. else if ( dwSrcFileSize > dwTrgFileSize )
  255. {
  256. nCompResult = 1;
  257. }
  258. }
  259. return nCompResult;
  260. }
  261. //----------------------------------------------------------------------------
  262. // TInstallFile::CompareFileDateTime - compares the file modification time of
  263. // this file object with the time of the target file object
  264. //----------------------------------------------------------------------------
  265. int // ret -(-1) if source < target
  266. TInstallFile::CompareFileDateTime( // ( 0) if source = target
  267. // ( 1) if source > target
  268. TInstallFile * pFileTrg // in -target file object
  269. )
  270. {
  271. int nCompResult = 0; // comparison result
  272. __int64 cmp = *(__int64*)&m_FileData.ftLastWriteTime -
  273. *(__int64*)&pFileTrg->m_FileData.ftLastWriteTime;
  274. if ( cmp )
  275. {
  276. // The following lines do a "fuzzy" compare so that file systems that
  277. // store timestamps with different precision levels can be compared for
  278. // equivalence. 20,000,000 represents the number of 100ns intervals in
  279. // a FAT/HPFS twosec file timestamp.
  280. if ( cmp < 0 )
  281. {
  282. cmp = -cmp;
  283. }
  284. if ( cmp >= 20000000 )
  285. {
  286. // the timestamps differ by more than 2 seconds, so we need to
  287. // compare the filetime structures
  288. nCompResult = CompareFileTime( &m_FileData.ftLastWriteTime,
  289. &pFileTrg->m_FileData.ftLastWriteTime );
  290. }
  291. }
  292. return nCompResult;
  293. }
  294. //---------------------------------------------------------------
  295. // TInstallFile::CompareFileVersion - compares the version of this
  296. // file object with the version of the target file object
  297. //---------------------------------------------------------------
  298. int // ret -(-1) if source version < target version
  299. TInstallFile::CompareFileVersion( // ( 0) if source version = target version
  300. // ( 1) if source version > target version
  301. TInstallFile * pFileTrg // in -target file object
  302. )
  303. {
  304. int nCompResult = 0; // comparison result
  305. DWORDLONG dwlSrcVersion = 0; // source version
  306. DWORDLONG dwlTrgVersion = 0; // target version
  307. dwlSrcVersion = ((DWORDLONG)m_FixedFileInfo.dwFileVersionMS << 32) |
  308. (DWORDLONG)m_FixedFileInfo.dwFileVersionLS;
  309. dwlTrgVersion = ((DWORDLONG)pFileTrg->m_FixedFileInfo.dwFileVersionMS << 32) |
  310. (DWORDLONG)pFileTrg->m_FixedFileInfo.dwFileVersionLS;
  311. if ( dwlTrgVersion )
  312. {
  313. if ( dwlSrcVersion < dwlTrgVersion )
  314. {
  315. nCompResult = -1;
  316. }
  317. else if ( dwlSrcVersion > dwlTrgVersion )
  318. {
  319. nCompResult = 1;
  320. }
  321. }
  322. else
  323. {
  324. nCompResult = 1;
  325. }
  326. return nCompResult;
  327. }
  328. //---------------------------------------------------------------
  329. // TInstallFile::GetFileVersion - retrieves the version as separate
  330. // components: Major, Minor, Release, Modification
  331. //---------------------------------------------------------------
  332. void
  333. TInstallFile::GetFileVersion(
  334. UINT * uVerMaj, // out -major version
  335. UINT * uVerMin, // out -minor version
  336. UINT * uVerRel, // out -release version
  337. UINT * uVerMod // out -modification version
  338. )
  339. {
  340. *uVerMaj = HIWORD(m_FixedFileInfo.dwFileVersionMS);
  341. *uVerMin = LOWORD(m_FixedFileInfo.dwFileVersionMS);
  342. *uVerRel = HIWORD(m_FixedFileInfo.dwFileVersionLS);
  343. *uVerMod = LOWORD(m_FixedFileInfo.dwFileVersionLS);
  344. }
  345. //---------------------------------------------------------------
  346. // TInstallFile::GetFileVersionString - retrieves the FileVersion
  347. // string of the version resource
  348. //---------------------------------------------------------------
  349. TCHAR * // ret -version string
  350. TInstallFile::GetFileVersionString()
  351. {
  352. UINT uBytes; // size of version info
  353. TCHAR * szBuffer; // version info buffer
  354. if ( m_VersionInfo && m_szFileVersion[0] == 0 )
  355. {
  356. TCHAR szStrFileInfo[MAX_PATH];
  357. _stprintf(szStrFileInfo,TEXT( "\\StringFileInfo\\%04X%04X\\FileVersion"),
  358. LOWORD(m_dwLanguageCode), HIWORD(m_dwLanguageCode) );
  359. if ( ! VerQueryValue( m_VersionInfo,
  360. szStrFileInfo,
  361. (void **) &szBuffer,
  362. &uBytes) )
  363. {
  364. err.MsgWrite( 0,
  365. DCT_MSG_VER_QUERY_VALUE_FAILED_SS,
  366. m_szFilePath,
  367. szStrFileInfo );
  368. }
  369. else
  370. {
  371. safecopy(m_szFileVersion,szBuffer);
  372. }
  373. }
  374. return m_szFileVersion;
  375. }
  376. //---------------------------------------------------------------
  377. // TInstallFile::GetFileSizeString - retrieves the file size as a string
  378. //---------------------------------------------------------------
  379. TCHAR * // ret -file size string
  380. TInstallFile::GetFileSizeString()
  381. {
  382. _stprintf(m_szFileSize,TEXT("%ld"), m_FileData.nFileSizeLow );
  383. return m_szFileSize;
  384. }
  385. //---------------------------------------------------------------
  386. // TInstallFile::GetFileDateTimeString - retrieves the file modification
  387. // time as a string
  388. //---------------------------------------------------------------
  389. TCHAR * // ret -file mod string
  390. TInstallFile::GetFileDateTimeString(
  391. TCHAR const * szFormatString // in -date/time format string
  392. )
  393. {
  394. //safecopy(m_szFileDateTime,ctime(m_FileData.ftLastWriteTime));
  395. return m_szFileDateTime;
  396. }
  397. //----------------------------------------------------------------------------
  398. // TInstallFile::IsBusy - determines if the file is busy by trying to open it
  399. // for reading and writing.
  400. //----------------------------------------------------------------------------
  401. BOOL // ret -TRUE if the file is busy
  402. TInstallFile::IsBusy() // -FALSE otherwise
  403. {
  404. BOOL bIsBusy = FALSE; // is the file busy?
  405. HANDLE hFile; // file handle
  406. DWORD rc; // OS return code
  407. // try to open file for read and write
  408. hFile = CreateFile( m_szFilePath,
  409. GENERIC_READ | GENERIC_WRITE,
  410. 0,
  411. NULL,
  412. OPEN_EXISTING,
  413. FILE_ATTRIBUTE_NORMAL,
  414. NULL );
  415. if ( hFile == INVALID_HANDLE_VALUE )
  416. {
  417. rc = GetLastError();
  418. if ( rc == ERROR_ACCESS_DENIED || rc == ERROR_SHARING_VIOLATION )
  419. {
  420. err.MsgWrite( 0,
  421. DCT_MSG_FILE_IN_USE_S,
  422. m_szFilePath );
  423. bIsBusy = TRUE;
  424. }
  425. else
  426. {
  427. if ( ! m_bSilent )
  428. err.SysMsgWrite( 0,
  429. rc,
  430. DCT_MSG_CREATE_FILE_FAILED_SD,
  431. m_szFilePath,
  432. rc );
  433. }
  434. }
  435. else
  436. {
  437. CloseHandle( hFile );
  438. }
  439. return bIsBusy;
  440. }
  441. //----------------------------------------------------------------------------
  442. // TDllFile::TDllFile - constructor for DLL file objects.
  443. //----------------------------------------------------------------------------
  444. TDllFile::TDllFile(
  445. TCHAR const * pszFileName, // in -file name (not a full path)
  446. TCHAR const * pszFileDir, // in -directory (without file name)
  447. TCHAR const * pszProgId, // in -Prog ID (for OCX's)
  448. BOOL bSystemFile // in -TRUE if file is a system file
  449. ) : TInstallFile( pszFileName, pszFileDir )
  450. {
  451. m_bSystemFile = bSystemFile;
  452. m_bRegistrationNeeded = FALSE;
  453. m_bRegisterTarget = FALSE;
  454. m_szProgId[0] = 0;
  455. m_szRegPath[0] = 0;
  456. if ( pszProgId )
  457. {
  458. safecopy(m_szProgId,pszProgId);
  459. }
  460. }
  461. //----------------------------------------------------------------------------
  462. // TDllFile::SupportsSelfReg - determines whether the file supports self-registration
  463. //----------------------------------------------------------------------------
  464. BOOL // ret -TRUE if file supports self-reg
  465. TDllFile::SupportsSelfReg() // -FALSE otherwise
  466. {
  467. BOOL bSelfReg = FALSE; // supports self-reg?
  468. UINT uBytes; // size of version info
  469. TCHAR * szBuffer; // version info buffer
  470. if ( m_VersionInfo )
  471. {
  472. TCHAR szStrFileInfo[MAX_PATH];
  473. _stprintf(szStrFileInfo,TEXT("\\StringFileInfo\\%04X%04X\\OLESelfRegister"),
  474. LOWORD(m_dwLanguageCode), HIWORD(m_dwLanguageCode) );
  475. if ( ! VerQueryValue( m_VersionInfo,
  476. szStrFileInfo,
  477. (void **) &szBuffer,
  478. &uBytes) )
  479. {
  480. if ( *m_szProgId )
  481. {
  482. bSelfReg = TRUE;
  483. }
  484. else
  485. {
  486. err.MsgWrite( 0,
  487. DCT_MSG_FILE_NO_SELF_REGISTRATION_S,
  488. m_szFilePath );
  489. }
  490. }
  491. else
  492. {
  493. bSelfReg = TRUE;
  494. }
  495. }
  496. return bSelfReg;
  497. }
  498. //----------------------------------------------------------------------------
  499. // TDllFile::IsRegistered - determines whether a file is registered
  500. //----------------------------------------------------------------------------
  501. BOOL // ret -TRUE if file is registered
  502. TDllFile::IsRegistered() // -FALSE otherwise
  503. {
  504. BOOL bIsRegistered = FALSE; // is the file registered?
  505. DWORD rc; // OS return code
  506. HRESULT hr; // OLE return code
  507. CLSID clsid; // CLSID for registered class
  508. IClassFactory * pICFGetClassObject; // ClassFactory interface
  509. TCHAR szBuffer[MAX_PATH]; // registry key buffer
  510. // initialize OLE
  511. CoInitialize( NULL );
  512. hr = CLSIDFromProgID( SysAllocString(m_szProgId), &clsid );
  513. if ( SUCCEEDED( hr ) )
  514. {
  515. hr = CoGetClassObject( clsid,
  516. CLSCTX_ALL,
  517. NULL,
  518. IID_IClassFactory,
  519. (void **)&pICFGetClassObject );
  520. if ( SUCCEEDED( hr ) )
  521. {
  522. bIsRegistered = TRUE;
  523. pICFGetClassObject->Release();
  524. }
  525. }
  526. CoUninitialize();
  527. if ( bIsRegistered )
  528. {
  529. WCHAR szKeyName[MAX_PATH];
  530. safecopy(szKeyName,m_szProgId);
  531. UStrCpy(szKeyName + UStrLen(szKeyName),"\\CLSID");
  532. TRegKey regKey;
  533. rc = regKey.OpenRead( szKeyName, HKEY_CLASSES_ROOT );
  534. if ( ! rc )
  535. {
  536. rc = regKey.ValueGetStr( _T(""), szBuffer, sizeof szBuffer );
  537. if ( ! rc )
  538. {
  539. regKey.Close();
  540. UStrCpy(szKeyName,"CLSID\\");
  541. UStrCpy(szKeyName + UStrLen(szKeyName),szBuffer);
  542. UStrCpy(szKeyName + UStrLen(szKeyName),"\\InProcServer32");
  543. rc = regKey.OpenRead( szKeyName, HKEY_CLASSES_ROOT );
  544. if ( ! rc )
  545. {
  546. rc = regKey.ValueGetStr( _T(""), szBuffer, sizeof szBuffer );
  547. if ( ! rc )
  548. {
  549. regKey.Close();
  550. safecopy(m_szRegPath,szBuffer);
  551. bIsRegistered = TRUE;
  552. }
  553. }
  554. }
  555. }
  556. }
  557. return bIsRegistered;
  558. }
  559. //----------------------------------------------------------------------------
  560. // TDllFile::CallDllFunction - call an exported function of a dll
  561. //----------------------------------------------------------------------------
  562. DWORD // ret -TRUE if function call success
  563. TDllFile::CallDllFunction( // FALSE if function call failure
  564. TCHAR const * pszFunctionName, // in -Exported function name
  565. TCHAR const * pszDllName // in -name of dll file
  566. )
  567. {
  568. DWORD rc = 0; // OS return code
  569. HINSTANCE hLib; // handle
  570. WCHAR szDllNameUsed[MAX_PATH];
  571. char pszFunctionNameA[MAX_PATH];
  572. safecopy(pszFunctionNameA,pszFunctionName);
  573. if ( pszDllName )
  574. {
  575. safecopy(szDllNameUsed,pszDllName);
  576. }
  577. else
  578. {
  579. safecopy(szDllNameUsed,m_szFilePath);
  580. }
  581. // load the dll into memory
  582. hLib = LoadLibrary( szDllNameUsed );
  583. if ( ! hLib )
  584. {
  585. rc = GetLastError();
  586. err.SysMsgWrite( 0,
  587. rc,
  588. DCT_MSG_LOAD_LIBRARY_FAILED_SD,
  589. szDllNameUsed,
  590. rc );
  591. }
  592. else
  593. {
  594. // Find the entry point.
  595. FARPROC lpDllEntryPoint = GetProcAddress( hLib, pszFunctionNameA );
  596. if ( lpDllEntryPoint == NULL )
  597. {
  598. rc = GetLastError();
  599. err.SysMsgWrite( 0,
  600. rc,
  601. DCT_MSG_GET_PROC_ADDRESS_FAILED_SSD,
  602. szDllNameUsed,
  603. pszFunctionName,
  604. rc );
  605. }
  606. else
  607. {
  608. // call the dll function
  609. rc = (DWORD)(*lpDllEntryPoint)();
  610. }
  611. FreeLibrary( hLib );
  612. }
  613. return rc;
  614. }
  615. //----------------------------------------------------------------------------
  616. // TDllFile::Register - registers the file
  617. //----------------------------------------------------------------------------
  618. DWORD // ret -last OS return code
  619. TDllFile::Register()
  620. {
  621. DWORD rc = 0; // OS return code
  622. TCHAR const szFunctionName[MAX_PATH] = _T("DllRegisterServer");
  623. if ( m_bRegisterTarget )
  624. {
  625. rc = CallDllFunction( szFunctionName, m_szTargetPath );
  626. }
  627. else
  628. {
  629. rc = CallDllFunction( szFunctionName );
  630. }
  631. if ( rc )
  632. {
  633. err.MsgWrite( 0,
  634. DCT_MSG_DLL_CALL_FAILED_SDS,
  635. szFunctionName,
  636. rc,
  637. "failed to register object classes" );
  638. }
  639. return rc;
  640. }
  641. //----------------------------------------------------------------------------
  642. // TDllFile::Unregister - unregisters the file
  643. //----------------------------------------------------------------------------
  644. DWORD // ret -last OS return code
  645. TDllFile::Unregister()
  646. {
  647. DWORD rc = 0; // OS return code
  648. TCHAR const szFunctionName[MAX_PATH] = _T("DllUnregisterServer");
  649. if ( m_bRegisterTarget )
  650. {
  651. rc = CallDllFunction( szFunctionName, m_szTargetPath );
  652. }
  653. else
  654. {
  655. rc = CallDllFunction( szFunctionName );
  656. }
  657. if ( rc )
  658. {
  659. err.MsgWrite( 0,
  660. DCT_MSG_DLL_CALL_FAILED_SDS,
  661. szFunctionName,
  662. rc,
  663. "failed to unregister object classes" );
  664. }
  665. return rc;
  666. }