Source code of Windows XP (NT5)
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.

865 lines
29 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. if ( rc == ERROR_SHARING_VIOLATION || rc == ERROR_USER_MAPPED_FILE )
  201. {
  202. // file was busy, we need to rename it and try again
  203. // create temp filename
  204. TCHAR szDestDir[MAX_PATH];
  205. TCHAR szTempFile[MAX_PATH];
  206. safecopy(szDestDir,pszDestinationPath);
  207. TCHAR * lastSlash = _tcsrchr(szDestDir,_T('\\'));
  208. if ( lastSlash )
  209. {
  210. (*lastSlash) = 0;
  211. }
  212. if ( ! ::GetTempFileName( szDestDir, TEXT("~MC"), 0, szTempFile ) )
  213. {
  214. rc = GetLastError();
  215. err.SysMsgWrite( 0,
  216. rc,
  217. DCT_MSG_GET_TEMP_FILENAME_FAILED_D,
  218. rc );
  219. }
  220. else
  221. {
  222. DeleteFile( szTempFile );
  223. // rename destination to temp filename
  224. if ( ! ::MoveFile( pszDestinationPath, szTempFile ) )
  225. {
  226. rc = GetLastError();
  227. err.SysMsgWrite( 0,
  228. rc,
  229. DCT_MSG_MOVE_FILE_FAILED_SSD,
  230. pszDestinationPath,
  231. szTempFile,
  232. rc );
  233. // can't rename, try rename on reboot
  234. if ( ! ::CopyFile( m_szFilePath, szTempFile, FALSE ) )
  235. {
  236. rc = GetLastError();
  237. err.SysMsgWrite( 0,
  238. rc,
  239. DCT_MSG_COPY_FILE_FAILED_SSD,
  240. m_szFilePath,
  241. szTempFile,
  242. rc );
  243. }
  244. else
  245. {
  246. err.MsgWrite( 0,
  247. DCT_MSG_SOURCE_COPIED_TO_TEMP_SS,
  248. m_szFilePath,
  249. szTempFile );
  250. if ( ! ::MoveFileEx( szTempFile, pszDestinationPath,
  251. MOVEFILE_DELAY_UNTIL_REBOOT ) )
  252. {
  253. rc = GetLastError();
  254. err.SysMsgWrite( 0,
  255. rc,
  256. DCT_MSG_MOVE_FILE_EX_FAILED_SSD,
  257. szTempFile,
  258. pszDestinationPath,
  259. rc );
  260. }
  261. else
  262. {
  263. err.MsgWrite( 0,
  264. DCT_MSG_RENAME_ON_REBOOT_SS,
  265. szTempFile,
  266. pszDestinationPath );
  267. }
  268. }
  269. }
  270. else
  271. {
  272. err.MsgWrite( 0,
  273. DCT_MSG_BUSY_FILE_RENAMED_SS,
  274. pszDestinationPath,
  275. szTempFile );
  276. if ( ! ::MoveFileEx( szTempFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT ) )
  277. {
  278. rc = GetLastError();
  279. err.SysMsgWrite( 0,
  280. rc,
  281. DCT_MSG_MOVE_FILE_EX_FAILED_SSD,
  282. szTempFile,
  283. L"NULL",
  284. rc );
  285. }
  286. // try to copy again
  287. if ( ! ::CopyFile( m_szFilePath, pszDestinationPath, FALSE ) )
  288. {
  289. rc = GetLastError();
  290. err.SysMsgWrite( 0,
  291. rc,
  292. DCT_MSG_COPY_FILE_FAILED_SSD,
  293. m_szFilePath,
  294. pszDestinationPath,
  295. rc );
  296. }
  297. else
  298. {
  299. err.MsgWrite( 0,
  300. DCT_MSG_FILE_COPIED_2ND_ATTEMPT_SS,
  301. m_szFilePath,
  302. pszDestinationPath );
  303. }
  304. }
  305. }
  306. }
  307. }
  308. return rc;
  309. }
  310. //----------------------------------------------------------------------------
  311. // TInstallFile::CompareFile - compares the version, date, and size of the
  312. // file object to the given target file object
  313. //----------------------------------------------------------------------------
  314. int // ret -(-1) if source < target
  315. TInstallFile::CompareFile( // ( 0) if source = target
  316. // ( 1) if source > target
  317. TInstallFile * pFileTrg // in -target file object
  318. )
  319. {
  320. int nComp; // comparison result
  321. nComp = CompareFileVersion( pFileTrg );
  322. if ( nComp == 0 )
  323. {
  324. // versions are the same, compare dates
  325. nComp = CompareFileDateTime( pFileTrg );
  326. if ( nComp <= 0 )
  327. {
  328. // source date is less than or equal to target date
  329. // compare file size
  330. nComp = CompareFileSize( pFileTrg );
  331. if ( nComp != 0 )
  332. {
  333. // file sizes are not equal, return (source > target)
  334. nComp = 1;
  335. }
  336. }
  337. }
  338. return nComp;
  339. }
  340. //----------------------------------------------------------------------------
  341. // TInstallFile::CompareFileSize - compares the file size of the this file
  342. // object with the size of the target file object
  343. //----------------------------------------------------------------------------
  344. int // ret -(-1) if source < target
  345. TInstallFile::CompareFileSize( // ( 0) if source = target
  346. // ( 1) if source > target
  347. TInstallFile * pFileTrg // in -target file object
  348. )
  349. {
  350. int nCompResult = 0; // comparison result
  351. DWORD dwSrcFileSize = 0; // source file size
  352. DWORD dwTrgFileSize = 0; // target file size
  353. dwSrcFileSize = m_FileData.nFileSizeLow;
  354. dwTrgFileSize = pFileTrg->m_FileData.nFileSizeLow;
  355. if ( dwSrcFileSize && dwTrgFileSize )
  356. {
  357. if ( dwSrcFileSize < dwTrgFileSize )
  358. {
  359. nCompResult = -1;
  360. }
  361. else if ( dwSrcFileSize > dwTrgFileSize )
  362. {
  363. nCompResult = 1;
  364. }
  365. }
  366. return nCompResult;
  367. }
  368. //----------------------------------------------------------------------------
  369. // TInstallFile::CompareFileDateTime - compares the file modification time of
  370. // this file object with the time of the target file object
  371. //----------------------------------------------------------------------------
  372. int // ret -(-1) if source < target
  373. TInstallFile::CompareFileDateTime( // ( 0) if source = target
  374. // ( 1) if source > target
  375. TInstallFile * pFileTrg // in -target file object
  376. )
  377. {
  378. int nCompResult = 0; // comparison result
  379. __int64 cmp = *(__int64*)&m_FileData.ftLastWriteTime -
  380. *(__int64*)&pFileTrg->m_FileData.ftLastWriteTime;
  381. if ( cmp )
  382. {
  383. // The following lines do a "fuzzy" compare so that file systems that
  384. // store timestamps with different precision levels can be compared for
  385. // equivalence. 20,000,000 represents the number of 100ns intervals in
  386. // a FAT/HPFS twosec file timestamp.
  387. if ( cmp < 0 )
  388. {
  389. cmp = -cmp;
  390. }
  391. if ( cmp >= 20000000 )
  392. {
  393. // the timestamps differ by more than 2 seconds, so we need to
  394. // compare the filetime structures
  395. nCompResult = CompareFileTime( &m_FileData.ftLastWriteTime,
  396. &pFileTrg->m_FileData.ftLastWriteTime );
  397. }
  398. }
  399. return nCompResult;
  400. }
  401. //---------------------------------------------------------------
  402. // TInstallFile::CompareFileVersion - compares the version of this
  403. // file object with the version of the target file object
  404. //---------------------------------------------------------------
  405. int // ret -(-1) if source version < target version
  406. TInstallFile::CompareFileVersion( // ( 0) if source version = target version
  407. // ( 1) if source version > target version
  408. TInstallFile * pFileTrg // in -target file object
  409. )
  410. {
  411. int nCompResult = 0; // comparison result
  412. DWORDLONG dwlSrcVersion = 0; // source version
  413. DWORDLONG dwlTrgVersion = 0; // target version
  414. dwlSrcVersion = ((DWORDLONG)m_FixedFileInfo.dwFileVersionMS << 32) |
  415. (DWORDLONG)m_FixedFileInfo.dwFileVersionLS;
  416. dwlTrgVersion = ((DWORDLONG)pFileTrg->m_FixedFileInfo.dwFileVersionMS << 32) |
  417. (DWORDLONG)pFileTrg->m_FixedFileInfo.dwFileVersionLS;
  418. if ( dwlTrgVersion )
  419. {
  420. if ( dwlSrcVersion < dwlTrgVersion )
  421. {
  422. nCompResult = -1;
  423. }
  424. else if ( dwlSrcVersion > dwlTrgVersion )
  425. {
  426. nCompResult = 1;
  427. }
  428. }
  429. else
  430. {
  431. nCompResult = 1;
  432. }
  433. return nCompResult;
  434. }
  435. //---------------------------------------------------------------
  436. // TInstallFile::GetFileVersion - retrieves the version as separate
  437. // components: Major, Minor, Release, Modification
  438. //---------------------------------------------------------------
  439. void
  440. TInstallFile::GetFileVersion(
  441. UINT * uVerMaj, // out -major version
  442. UINT * uVerMin, // out -minor version
  443. UINT * uVerRel, // out -release version
  444. UINT * uVerMod // out -modification version
  445. )
  446. {
  447. *uVerMaj = HIWORD(m_FixedFileInfo.dwFileVersionMS);
  448. *uVerMin = LOWORD(m_FixedFileInfo.dwFileVersionMS);
  449. *uVerRel = HIWORD(m_FixedFileInfo.dwFileVersionLS);
  450. *uVerMod = LOWORD(m_FixedFileInfo.dwFileVersionLS);
  451. }
  452. //---------------------------------------------------------------
  453. // TInstallFile::GetFileVersionString - retrieves the FileVersion
  454. // string of the version resource
  455. //---------------------------------------------------------------
  456. TCHAR * // ret -version string
  457. TInstallFile::GetFileVersionString()
  458. {
  459. UINT uBytes; // size of version info
  460. TCHAR * szBuffer; // version info buffer
  461. if ( m_VersionInfo && m_szFileVersion[0] == 0 )
  462. {
  463. TCHAR szStrFileInfo[MAX_PATH];
  464. _stprintf(szStrFileInfo,TEXT( "\\StringFileInfo\\%04X%04X\\FileVersion"),
  465. LOWORD(m_dwLanguageCode), HIWORD(m_dwLanguageCode) );
  466. if ( ! VerQueryValue( m_VersionInfo,
  467. szStrFileInfo,
  468. (void **) &szBuffer,
  469. &uBytes) )
  470. {
  471. err.MsgWrite( 0,
  472. DCT_MSG_VER_QUERY_VALUE_FAILED_SS,
  473. m_szFilePath,
  474. szStrFileInfo );
  475. }
  476. else
  477. {
  478. safecopy(m_szFileVersion,szBuffer);
  479. }
  480. }
  481. return m_szFileVersion;
  482. }
  483. //---------------------------------------------------------------
  484. // TInstallFile::GetFileSizeString - retrieves the file size as a string
  485. //---------------------------------------------------------------
  486. TCHAR * // ret -file size string
  487. TInstallFile::GetFileSizeString()
  488. {
  489. _stprintf(m_szFileSize,TEXT("%ld"), m_FileData.nFileSizeLow );
  490. return m_szFileSize;
  491. }
  492. //---------------------------------------------------------------
  493. // TInstallFile::GetFileDateTimeString - retrieves the file modification
  494. // time as a string
  495. //---------------------------------------------------------------
  496. TCHAR * // ret -file mod string
  497. TInstallFile::GetFileDateTimeString(
  498. TCHAR const * szFormatString // in -date/time format string
  499. )
  500. {
  501. //safecopy(m_szFileDateTime,ctime(m_FileData.ftLastWriteTime));
  502. return m_szFileDateTime;
  503. }
  504. //----------------------------------------------------------------------------
  505. // TInstallFile::IsBusy - determines if the file is busy by trying to open it
  506. // for reading and writing.
  507. //----------------------------------------------------------------------------
  508. BOOL // ret -TRUE if the file is busy
  509. TInstallFile::IsBusy() // -FALSE otherwise
  510. {
  511. BOOL bIsBusy = FALSE; // is the file busy?
  512. HANDLE hFile; // file handle
  513. DWORD rc; // OS return code
  514. // try to open file for read and write
  515. hFile = CreateFile( m_szFilePath,
  516. GENERIC_READ | GENERIC_WRITE,
  517. 0,
  518. NULL,
  519. OPEN_EXISTING,
  520. FILE_ATTRIBUTE_NORMAL,
  521. NULL );
  522. if ( hFile == INVALID_HANDLE_VALUE )
  523. {
  524. rc = GetLastError();
  525. if ( rc == ERROR_ACCESS_DENIED || rc == ERROR_SHARING_VIOLATION )
  526. {
  527. err.MsgWrite( 0,
  528. DCT_MSG_FILE_IN_USE_S,
  529. m_szFilePath );
  530. bIsBusy = TRUE;
  531. }
  532. else
  533. {
  534. if ( ! m_bSilent )
  535. err.SysMsgWrite( 0,
  536. rc,
  537. DCT_MSG_CREATE_FILE_FAILED_SD,
  538. m_szFilePath,
  539. rc );
  540. }
  541. }
  542. else
  543. {
  544. CloseHandle( hFile );
  545. }
  546. return bIsBusy;
  547. }
  548. //----------------------------------------------------------------------------
  549. // TDllFile::TDllFile - constructor for DLL file objects.
  550. //----------------------------------------------------------------------------
  551. TDllFile::TDllFile(
  552. TCHAR const * pszFileName, // in -file name (not a full path)
  553. TCHAR const * pszFileDir, // in -directory (without file name)
  554. TCHAR const * pszProgId, // in -Prog ID (for OCX's)
  555. BOOL bSystemFile // in -TRUE if file is a system file
  556. ) : TInstallFile( pszFileName, pszFileDir )
  557. {
  558. m_bSystemFile = bSystemFile;
  559. m_bRegistrationNeeded = FALSE;
  560. m_bRegisterTarget = FALSE;
  561. m_szProgId[0] = 0;
  562. m_szRegPath[0] = 0;
  563. if ( pszProgId )
  564. {
  565. safecopy(m_szProgId,pszProgId);
  566. }
  567. }
  568. //----------------------------------------------------------------------------
  569. // TDllFile::SupportsSelfReg - determines whether the file supports self-registration
  570. //----------------------------------------------------------------------------
  571. BOOL // ret -TRUE if file supports self-reg
  572. TDllFile::SupportsSelfReg() // -FALSE otherwise
  573. {
  574. BOOL bSelfReg = FALSE; // supports self-reg?
  575. UINT uBytes; // size of version info
  576. TCHAR * szBuffer; // version info buffer
  577. if ( m_VersionInfo )
  578. {
  579. TCHAR szStrFileInfo[MAX_PATH];
  580. _stprintf(szStrFileInfo,TEXT("\\StringFileInfo\\%04X%04X\\OLESelfRegister"),
  581. LOWORD(m_dwLanguageCode), HIWORD(m_dwLanguageCode) );
  582. if ( ! VerQueryValue( m_VersionInfo,
  583. szStrFileInfo,
  584. (void **) &szBuffer,
  585. &uBytes) )
  586. {
  587. if ( *m_szProgId )
  588. {
  589. bSelfReg = TRUE;
  590. }
  591. else
  592. {
  593. err.MsgWrite( 0,
  594. DCT_MSG_FILE_NO_SELF_REGISTRATION_S,
  595. m_szFilePath );
  596. }
  597. }
  598. else
  599. {
  600. bSelfReg = TRUE;
  601. }
  602. }
  603. return bSelfReg;
  604. }
  605. //----------------------------------------------------------------------------
  606. // TDllFile::IsRegistered - determines whether a file is registered
  607. //----------------------------------------------------------------------------
  608. BOOL // ret -TRUE if file is registered
  609. TDllFile::IsRegistered() // -FALSE otherwise
  610. {
  611. BOOL bIsRegistered = FALSE; // is the file registered?
  612. DWORD rc; // OS return code
  613. HRESULT hr; // OLE return code
  614. CLSID clsid; // CLSID for registered class
  615. IClassFactory * pICFGetClassObject; // ClassFactory interface
  616. TCHAR szBuffer[MAX_PATH]; // registry key buffer
  617. // initialize OLE
  618. CoInitialize( NULL );
  619. hr = CLSIDFromProgID( SysAllocString(m_szProgId), &clsid );
  620. if ( SUCCEEDED( hr ) )
  621. {
  622. hr = CoGetClassObject( clsid,
  623. CLSCTX_ALL,
  624. NULL,
  625. IID_IClassFactory,
  626. (void **)&pICFGetClassObject );
  627. if ( SUCCEEDED( hr ) )
  628. {
  629. bIsRegistered = TRUE;
  630. pICFGetClassObject->Release();
  631. }
  632. }
  633. CoUninitialize();
  634. if ( bIsRegistered )
  635. {
  636. WCHAR szKeyName[MAX_PATH];
  637. safecopy(szKeyName,m_szProgId);
  638. UStrCpy(szKeyName + UStrLen(szKeyName),"\\CLSID");
  639. TRegKey regKey;
  640. rc = regKey.OpenRead( szKeyName, HKEY_CLASSES_ROOT );
  641. if ( ! rc )
  642. {
  643. rc = regKey.ValueGetStr( _T(""), szBuffer, sizeof szBuffer );
  644. if ( ! rc )
  645. {
  646. regKey.Close();
  647. UStrCpy(szKeyName,"CLSID\\");
  648. UStrCpy(szKeyName + UStrLen(szKeyName),szBuffer);
  649. UStrCpy(szKeyName + UStrLen(szKeyName),"\\InProcServer32");
  650. rc = regKey.OpenRead( szKeyName, HKEY_CLASSES_ROOT );
  651. if ( ! rc )
  652. {
  653. rc = regKey.ValueGetStr( _T(""), szBuffer, sizeof szBuffer );
  654. if ( ! rc )
  655. {
  656. regKey.Close();
  657. safecopy(m_szRegPath,szBuffer);
  658. bIsRegistered = TRUE;
  659. }
  660. }
  661. }
  662. }
  663. }
  664. return bIsRegistered;
  665. }
  666. //----------------------------------------------------------------------------
  667. // TDllFile::CallDllFunction - call an exported function of a dll
  668. //----------------------------------------------------------------------------
  669. DWORD // ret -TRUE if function call success
  670. TDllFile::CallDllFunction( // FALSE if function call failure
  671. TCHAR const * pszFunctionName, // in -Exported function name
  672. TCHAR const * pszDllName // in -name of dll file
  673. )
  674. {
  675. DWORD rc = 0; // OS return code
  676. HINSTANCE hLib; // handle
  677. WCHAR szDllNameUsed[MAX_PATH];
  678. char pszFunctionNameA[MAX_PATH];
  679. safecopy(pszFunctionNameA,pszFunctionName);
  680. if ( pszDllName )
  681. {
  682. safecopy(szDllNameUsed,pszDllName);
  683. }
  684. else
  685. {
  686. safecopy(szDllNameUsed,m_szFilePath);
  687. }
  688. // load the dll into memory
  689. hLib = LoadLibrary( szDllNameUsed );
  690. if ( ! hLib )
  691. {
  692. rc = GetLastError();
  693. err.SysMsgWrite( 0,
  694. rc,
  695. DCT_MSG_LOAD_LIBRARY_FAILED_SD,
  696. szDllNameUsed,
  697. rc );
  698. }
  699. else
  700. {
  701. // Find the entry point.
  702. FARPROC lpDllEntryPoint = GetProcAddress( hLib, pszFunctionNameA );
  703. if ( lpDllEntryPoint == NULL )
  704. {
  705. rc = GetLastError();
  706. err.SysMsgWrite( 0,
  707. rc,
  708. DCT_MSG_GET_PROC_ADDRESS_FAILED_SSD,
  709. szDllNameUsed,
  710. pszFunctionName,
  711. rc );
  712. }
  713. else
  714. {
  715. // call the dll function
  716. rc = (DWORD)(*lpDllEntryPoint)();
  717. }
  718. FreeLibrary( hLib );
  719. }
  720. return rc;
  721. }
  722. //----------------------------------------------------------------------------
  723. // TDllFile::Register - registers the file
  724. //----------------------------------------------------------------------------
  725. DWORD // ret -last OS return code
  726. TDllFile::Register()
  727. {
  728. DWORD rc = 0; // OS return code
  729. TCHAR const szFunctionName[MAX_PATH] = _T("DllRegisterServer");
  730. if ( m_bRegisterTarget )
  731. {
  732. rc = CallDllFunction( szFunctionName, m_szTargetPath );
  733. }
  734. else
  735. {
  736. rc = CallDllFunction( szFunctionName );
  737. }
  738. if ( rc )
  739. {
  740. err.MsgWrite( 0,
  741. DCT_MSG_DLL_CALL_FAILED_SDS,
  742. szFunctionName,
  743. rc,
  744. "failed to register object classes" );
  745. }
  746. return rc;
  747. }
  748. //----------------------------------------------------------------------------
  749. // TDllFile::Unregister - unregisters the file
  750. //----------------------------------------------------------------------------
  751. DWORD // ret -last OS return code
  752. TDllFile::Unregister()
  753. {
  754. DWORD rc = 0; // OS return code
  755. TCHAR const szFunctionName[MAX_PATH] = _T("DllUnregisterServer");
  756. if ( m_bRegisterTarget )
  757. {
  758. rc = CallDllFunction( szFunctionName, m_szTargetPath );
  759. }
  760. else
  761. {
  762. rc = CallDllFunction( szFunctionName );
  763. }
  764. if ( rc )
  765. {
  766. err.MsgWrite( 0,
  767. DCT_MSG_DLL_CALL_FAILED_SDS,
  768. szFunctionName,
  769. rc,
  770. "failed to unregister object classes" );
  771. }
  772. return rc;
  773. }