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.

931 lines
29 KiB

  1. /******************************************************************************
  2. * Temp conversion utility to take registry entries and populate the class store with those entries.
  3. *****************************************************************************/
  4. /******************************************************************************
  5. includes
  6. ******************************************************************************/
  7. #include "precomp.hxx"
  8. /******************************************************************************
  9. defines and prototypes
  10. ******************************************************************************/
  11. extern CLSID CLSID_ClassStore;
  12. extern const IID IID_IClassStore;
  13. extern const IID IID_IClassAdmin;
  14. LONG
  15. UpdateClassEntryFromAutoConvert(
  16. MESSAGE * pMessage,
  17. BasicRegistry * pCLSID,
  18. CLASS_ENTRY * pClassEntry );
  19. LONG
  20. UpdateClassEntryFromTreatAs(
  21. MESSAGE * pMessage,
  22. BasicRegistry * pCLSID,
  23. CLASS_ENTRY * pClassEntry );
  24. LONG
  25. UpdateClassEntryFromServerType(
  26. MESSAGE * pMessage,
  27. BasicRegistry * pCLSID,
  28. CLASS_ENTRY * pClassEntry );
  29. LONG
  30. UpdateClassEntryFromTypelib(
  31. MESSAGE * pMessage,
  32. BasicRegistry * pCLSID,
  33. CLASS_ENTRY * pClassEntry );
  34. LONG
  35. UpdateClassEntryFromAppID(
  36. MESSAGE * pMessage,
  37. BasicRegistry * pCLSID,
  38. CLASS_ENTRY * pClassEntry,
  39. char * pAppidBuffer );
  40. ULONG
  41. GeneratePackageDetails(
  42. MESSAGE * pMessage,
  43. BasicRegistry * pCLSID,
  44. PACKAGEDETAIL * pPackageDetails );
  45. ULONG
  46. UpdateClassEntryFromServerType(
  47. MESSAGE * pMessage,
  48. APP_ENTRY * pAppEntry,
  49. BasicRegistry * pCLSID );
  50. ULONG
  51. PackageFromServerType(
  52. MESSAGE * pMessage,
  53. DWORD Context,
  54. APP_ENTRY * pAppEntry,
  55. BasicRegistry * pServerTypeKey,
  56. BasicRegistry * pCLSID );
  57. ULONG
  58. UpdateClassEntryFromServerType(
  59. MESSAGE * pMessage,
  60. BasicRegistry * pCLSID,
  61. APP_ENTRY * pAppEntry );
  62. LONG
  63. UpdatePackageFromClsid(
  64. MESSAGE * pMessage,
  65. BasicRegistry * pCLSID,
  66. char * pClsidString,
  67. char * pAppid );
  68. LONG
  69. UpdatePackage(
  70. MESSAGE * pMessage,
  71. BOOL fUsageFlag,
  72. DWORD Context,
  73. char * pClsidString,
  74. char * pAppid,
  75. char * ServerName,
  76. DWORD * pMajorVersion,
  77. DWORD * pMinorVersion,
  78. DWORD * pLocale );
  79. CLASSPATHTYPE
  80. GetPathType(
  81. char * pExtension );
  82. LPOLESTR
  83. GetPath(
  84. char * pPath );
  85. LPOLESTR
  86. GetSetupCommand(
  87. char * pName );
  88. LPOLESTR
  89. MakePackageName(
  90. char * pName );
  91. void
  92. SetCSPlatform( CSPLATFORM * pCSPlatform );
  93. /******************************************************************************
  94. Globals
  95. ******************************************************************************/
  96. extern char * MapDriveToServerName[ 26 ];
  97. LONG
  98. UpdateDatabaseFromCLSID(
  99. MESSAGE * pMessage )
  100. /*****************************************************************************
  101. Purpose:
  102. Update the internal database from clsid entries under the root key
  103. specified by the message.
  104. In Arguments:
  105. Message - A message block that contains the root of the key that has
  106. class id etc related information.
  107. Out Arguments:
  108. None.
  109. InOut Arguments:
  110. None.
  111. Return Arguments:
  112. A Win32 error code specifying success or the kind of failure.
  113. Remarks:
  114. The routine only returns an error code of ERROR_NO_MORE_ITEMS.
  115. *****************************************************************************/
  116. {
  117. BasicRegistry * pHKCR = new BasicRegistry( pMessage->hRoot ); // HKCR
  118. BasicRegistry * pCLSIDUnderHKCR;
  119. CLSDICT * pClsDict = pMessage->pClsDict;
  120. BOOL fNewEntry = 0;
  121. int Index;
  122. LONG CLSIDError = ERROR_SUCCESS;
  123. CLASS_ENTRY * pClassEntry;
  124. //
  125. // Get the first clsid key under HKCR
  126. //
  127. if ( pHKCR->Find( "CLSID", &pCLSIDUnderHKCR ) != ERROR_SUCCESS )
  128. return ERROR_NO_MORE_ITEMS;
  129. //
  130. // Go thru all the subkeys under CLSID and get the details under the keys.
  131. //
  132. for ( Index = 0, fNewEntry = 0;
  133. CLSIDError != ERROR_NO_MORE_ITEMS;
  134. ++Index )
  135. {
  136. char CLSIDBuffer[256];
  137. DWORD SizeOfCLSIDBuffer = sizeof(CLSIDBuffer)/sizeof(char);
  138. char AppidBuffer[ 256 ];
  139. BasicRegistry * pCLSID;
  140. //
  141. // Get the name of the key - the next one under HKCRCLSID that
  142. // matches our time stamp criteria.
  143. //
  144. CLSIDError = pCLSIDUnderHKCR->NextKey(
  145. CLSIDBuffer,
  146. &SizeOfCLSIDBuffer,
  147. &pCLSID,
  148. pMessage->ftLow,
  149. pMessage->ftHigh);
  150. if ( (CLSIDError == ERROR_SUCCESS ) &&
  151. (CLSIDBuffer[0] == '{') )
  152. {
  153. //
  154. // We got a valid classid entry. See if it is in the database
  155. // already, if not make a new entry and update that with the
  156. // classid related details.
  157. //
  158. char * pT = new char [SizeOfCLSIDBuffer+1];
  159. strcpy( pT, CLSIDBuffer );
  160. if ( (pClassEntry = pClsDict->Search( CLSIDBuffer ) ) == 0 )
  161. {
  162. pClassEntry = new CLASS_ENTRY;
  163. fNewEntry = 1;
  164. }
  165. memcpy( pClassEntry->ClsidString,
  166. &CLSIDBuffer,
  167. SIZEOF_STRINGIZED_CLSID );
  168. //
  169. // Update class entry from subkeys.
  170. //
  171. // update frm "autoconvert" value. ignore error, since optional.
  172. UpdateClassEntryFromAutoConvert( pMessage, pCLSID, pClassEntry );
  173. // update frm "treatas" value. ignore error, since optional.
  174. UpdateClassEntryFromTreatAs( pMessage, pCLSID, pClassEntry );
  175. //
  176. // Update from clsid. Although this is optional, the appid setting
  177. // is important in that it determines if a classid falls under an
  178. // appid that is supported by a package or if it is a clsid that
  179. // does not have an appid. A package can have both - clsids
  180. // which have appids or those that dont.
  181. //
  182. BOOL fAdded = FALSE;
  183. // Check if this class id has an app id.
  184. if ( UpdateClassEntryFromAppID( pMessage,
  185. pCLSID,
  186. pClassEntry,
  187. &AppidBuffer[0] ) )
  188. {
  189. // yes this classid has an appid, so enter into the app detail
  190. // structure corresponding to the appid.
  191. fAdded = UpdatePackageFromClsid( pMessage, pCLSID, pT, &AppidBuffer[0] );
  192. }
  193. else
  194. {
  195. // no, this classid does not have an appid associated, so
  196. // enter this into the null appid group.
  197. fAdded = UpdatePackageFromClsid( pMessage, pCLSID, pT, 0 );
  198. }
  199. if ( fNewEntry && fAdded)
  200. pClsDict->Insert( pClassEntry );
  201. }
  202. else if ( CLSIDError == ERROR_SUCCESS )
  203. {
  204. delete pCLSID;
  205. }
  206. }
  207. //
  208. // delete the CLSID key under HKCR
  209. //
  210. delete pCLSIDUnderHKCR;
  211. if ( CLSIDError == ERROR_NO_MORE_ITEMS )
  212. return ERROR_SUCCESS;
  213. return ERROR_SUCCESS;
  214. }
  215. LONG
  216. UpdatePackageFromClsid(
  217. MESSAGE * pMessage,
  218. BasicRegistry * pCLSID,
  219. char * pClsidString,
  220. char * pAppid )
  221. /*****************************************************************************
  222. Purpose:
  223. To update package details from package id.
  224. In Arguments:
  225. pMessage - Message block passing info between modules.
  226. pCLSID - An open Key to the registry for the specified clsid.
  227. pClsidString- A stringized clsid used for entring into appid database.
  228. pAppid - Stringized appid to enter into the package database.
  229. Out Arguments:
  230. None.
  231. InOut Arguments:
  232. None.
  233. Return Arguments:
  234. Status. 1 - need to add CLSID, 0 - don't need to add CLSID
  235. Remarks:
  236. A package is a collection of individual executables. Under the CLSID key
  237. in a registry can be a number of packages: inproc handlers, inproc
  238. servers and local and remote servers. Each of these qualify as
  239. individual packages unless packaged in say a cab file. That overall
  240. packaging is specified by the package path field in the message.
  241. Therefore this routine goes thru all individual packages as specified
  242. under the CLSID key and attempts to generate packages for them. The
  243. Update package routine then decides what the package type is based on
  244. whether the message field has a package path specified. It is very
  245. possible (and happens for .Cab files) for CLSID entries of local server
  246. inproc handler etc to end up in one package
  247. *****************************************************************************/
  248. {
  249. // class context mapping array.
  250. static DWORD ClassContextArray[] =
  251. {
  252. CLSCTX_INPROC_HANDLER,
  253. CLSCTX_INPROC_SERVER,
  254. CLSCTX_LOCAL_SERVER,
  255. CLSCTX_REMOTE_SERVER
  256. // BUGBUG - what about the 16-bit cases?
  257. // ,
  258. // CLSCTX_INPROC_SERVER16,
  259. // CLSCTX_LOCAL_SERVER,
  260. // CLSCTX_INPROC_HANDLER16
  261. };
  262. // Keys that map to a class context.
  263. // Must have same number of elements as ClassContextArray.
  264. static char * pKeyNamesArray[] =
  265. {
  266. "InprocHandler32",
  267. "InprocServer32",
  268. "LocalServer32",
  269. "RemoteServer32"
  270. // ,
  271. // "InprocServer",
  272. // "LocalServer",
  273. // "InprocHandler"
  274. };
  275. LONG lReturn = 0;
  276. int Index;
  277. for ( Index = 0;
  278. Index < sizeof(pKeyNamesArray) / sizeof(pKeyNamesArray[0]) ;
  279. Index++ )
  280. {
  281. // Search for all the server types under the CLSID. If available, create
  282. // packages for those server types.
  283. BasicRegistry * pServerTypeKey;
  284. LONG E;
  285. // check if a potential package of the type specified exists in the
  286. // registry. In other words, check if one of the above specified keys
  287. // exists under the clsid key.
  288. //
  289. E = pCLSID->Find( pKeyNamesArray[ Index ], &pServerTypeKey );
  290. if ( E == ERROR_SUCCESS )
  291. {
  292. //
  293. // Yes, a key for the specified server type exists.
  294. // Get its named value. Based on this we will attempt to enter
  295. // a new package in our database.
  296. //
  297. char ServerName[_MAX_PATH];
  298. DWORD ServerNameLength;
  299. ServerNameLength = sizeof( ServerName) / sizeof( char );
  300. E = pServerTypeKey->QueryValueEx( 0,
  301. &ServerName[0],
  302. &ServerNameLength );
  303. //
  304. // A server name may have a switch specified for execution. That
  305. // is not significant for our class store update, but is significant
  306. // in that it should not be part of the server name to enter into
  307. // the class store. Make sure we ignore it.
  308. //
  309. if ( E == ERROR_SUCCESS )
  310. {
  311. // remove any '/' switch characters, so we dont get confused.
  312. char * p = strchr( &ServerName[0], '/' );
  313. if ( p )
  314. {
  315. while ( *(--p) == ' ' );
  316. *(p+1) = '\0';
  317. }
  318. //
  319. // call common routine to update package from clsid and appid
  320. // details.
  321. //
  322. UpdatePackage( pMessage,
  323. 0, // clsid update - not a typelib id update
  324. ClassContextArray[ Index ],
  325. pClsidString,
  326. pAppid,
  327. &ServerName[0],
  328. 0,
  329. 0,
  330. 0 );
  331. }
  332. else
  333. {
  334. // It is possible that the tag may not have a name, in
  335. // which case we need to create a package entry using the
  336. // original package path.
  337. UpdatePackage( pMessage,
  338. 0, // clsid update
  339. ClassContextArray[ Index ],
  340. pClsidString,
  341. pAppid,
  342. pMessage->pPackagePath,
  343. 0,
  344. 0,
  345. 0 );
  346. }
  347. delete pServerTypeKey;
  348. // We've found one entry and that's enough to get everything we
  349. // need to know to be able to populate the class store so we're
  350. // going to break out of the for loop here.
  351. // BUGBUG - For beta 2 we need to simplify this code so that we
  352. // don't even bother looking for this. Most of this code
  353. // is here to support features that the class store was going to
  354. // have once upon a time. Since then, the class store has been
  355. // redesigned and we really don't need all of this junk.
  356. lReturn = 1;
  357. break;
  358. }
  359. }
  360. return lReturn;
  361. }
  362. LONG
  363. UpdatePackage(
  364. MESSAGE * pMessage,
  365. BOOL fUsage,
  366. DWORD Context,
  367. char * pClsidString,
  368. char * pAppid,
  369. char * ServerName,
  370. DWORD * pMajor,
  371. DWORD * pMinor,
  372. LCID * pLocale )
  373. /*****************************************************************************
  374. Purpose:
  375. Update package details in database based on clsid and appid.
  376. In Arguments:
  377. pMessage - Message block passing arguments between modules.
  378. fUsageFlag - 0 if clsid is being updated in appid list or 1 if a
  379. typelib is being updated in appid list.
  380. pClsidString- A stringized clsid/typelibid used for entring into
  381. appid database.
  382. pAppid - Stringized appid to enter into the package database.
  383. ServerName - String used to identify the original server name.
  384. pMajor - Major version number
  385. pMinor - Minor version number
  386. pLocale - locale.
  387. Out Arguments:
  388. InOut Arguments:
  389. Return Arguments:
  390. Remarks:
  391. Version#s and locale info are pointers. This routine is used by typelib
  392. update routine also. They usually have version and locale info, but
  393. general packages do not. Therefore the routine has pointers to indicate
  394. if info is available and if so, update it.
  395. If the message has a package path, it indicates that the server
  396. supporting the classid is part of that package. So the package path
  397. determines the package type etc and overrides any server names specified
  398. in the CLSID key
  399. We are also making an assumption that there is no appid associated with
  400. a typelib, so we can asssume that all typelib entries go to the null
  401. appid list only. If this changes, then use the AddTypelib method in
  402. APP_ENTRY to update the app entry.
  403. THIS ROUTINE NEEDS CLEANUP - IT IS A HACK AFTER HACK AFTER HACK
  404. *****************************************************************************/
  405. {
  406. PDICT * pPackageDict = pMessage->pPackageDict;
  407. PACKAGE_ENTRY * pPackageEntry;
  408. char Name[ _MAX_FNAME ];
  409. char Ext[ _MAX_EXT ];
  410. char PackageName[ _MAX_PATH ];
  411. PACKAGEDETAIL PackageDetails;
  412. LONG Error = 0;
  413. APP_ENTRY * pAppEntry;
  414. char * p;
  415. CSPLATFORM CSPlatform;
  416. SetCSPlatform( &CSPlatform);
  417. // clear the package details structure.
  418. memset(&PackageDetails, '\0', sizeof( PackageDetails ));
  419. //
  420. // If package path exists, then the extension etc determine the package
  421. // type. If not, the server name (localserver/handler name etc) determines
  422. // the package type.
  423. //
  424. if ( p = pMessage->pPackagePath )
  425. {
  426. _splitpath( pMessage->pPackagePath, NULL, NULL, Name, Ext );
  427. }
  428. else
  429. {
  430. p = ServerName;
  431. _splitpath( ServerName, NULL, NULL, Name, Ext );
  432. }
  433. if (pMessage->pPackageName)
  434. {
  435. strcpy(PackageName, pMessage->pPackageName);
  436. }
  437. else
  438. {
  439. strcpy( PackageName, Name );
  440. strcat( PackageName, Ext );
  441. pMessage->pPackageName = new char[strlen(PackageName)+1];
  442. strcpy(pMessage->pPackageName, PackageName);
  443. }
  444. // Check if we already have the package name in the dictionary.
  445. pPackageEntry = pPackageDict->Search( &PackageName[0], Context );
  446. // if we do not, make a new package entry.
  447. if (!pPackageEntry)
  448. {
  449. pPackageEntry = new PACKAGE_ENTRY;
  450. strcpy( &pPackageEntry->PackageName[0], &PackageName[0] );
  451. PackageDetails.dwContext =( pMessage->pPackagePath )
  452. ? CLSCTX_INPROC_SERVER + CLSCTX_LOCAL_SERVER :
  453. Context; // Context temp workaround
  454. if ( pMessage->fPathTypeKnown )
  455. PackageDetails.PathType = pMessage->PathType;
  456. else
  457. PackageDetails.PathType = GetPathType( &Ext[0] );
  458. if ( (pMessage->pAuxPath) && (PackageDetails.PathType == DrwFilePath))
  459. PackageDetails.pszPath = GetPath( pMessage->pAuxPath );
  460. else
  461. PackageDetails.pszPath = GetPath( p );
  462. PackageDetails.pszIconPath = GetPath( p );
  463. if ( pMessage->pSetupCommand )
  464. PackageDetails.pszSetupCommand = GetPath( pMessage->pSetupCommand );
  465. PackageDetails.dwActFlags = pMessage->ActFlags;
  466. PackageDetails.pszPackageName = MakePackageName( &PackageName[0] );
  467. PackageDetails.pszProductName = MakePackageName( &Name[0] );
  468. PackageDetails.Platform = CSPlatform;
  469. if (pLocale )
  470. PackageDetails.Locale = *pLocale;
  471. else
  472. PackageDetails.Locale =
  473. MAKELCID(
  474. MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
  475. SORT_DEFAULT );
  476. if ( pMajor )
  477. PackageDetails.dwVersionHi = *pMajor;
  478. else
  479. PackageDetails.dwVersionHi = 0;
  480. if ( pMinor )
  481. PackageDetails.dwVersionLo = *pMinor;
  482. else
  483. PackageDetails.dwVersionLo = 0;
  484. PackageDetails.cApps = 0;
  485. PackageDetails.pAppDetail = 0;
  486. // set the package details.
  487. pPackageEntry->SetPackageDetail( &PackageDetails );
  488. // store the original name so that we can dump it.
  489. pPackageEntry->SetOriginalName( ServerName );
  490. // Add this into the package dictionary.
  491. pMessage->pPackageDict->Insert( pPackageEntry );
  492. }
  493. // search for the app entry. The class entry needs to be entered
  494. // there. If there is no app id specified (appentry is null )
  495. // get the app entry whose ID is 0. All classes that do not have
  496. // an app id specified, will go into this bucket. Finally we will
  497. // assign an appid to it and enter into the class store.
  498. if ( !pAppid )
  499. {
  500. // There is no appid. Enter the clsid entry in the null appid.
  501. if ( fUsage == 0 )
  502. pPackageEntry->AddClsidToNullAppid( pClsidString );
  503. else
  504. pPackageEntry->AddTypelibToNullAppid( pClsidString );
  505. }
  506. else
  507. {
  508. pAppEntry = pPackageEntry->SearchAppEntry( pAppid );
  509. if ( !pAppEntry )
  510. {
  511. pAppEntry = new APP_ENTRY;
  512. pAppEntry->SetAppIDString( pAppid );
  513. pPackageEntry->AddAppEntry( pAppEntry );
  514. }
  515. pAppEntry->AddClsid( pClsidString );
  516. }
  517. return 0;
  518. }
  519. CLASSPATHTYPE
  520. GetPathType(
  521. char * pExt )
  522. /*****************************************************************************
  523. Purpose:
  524. Map the file extension to CLASSPATHTYPE
  525. In:
  526. pExt - File Extension to map
  527. Out:
  528. None.
  529. InOut:
  530. None.
  531. Return:
  532. CLASSPATHTYPE of the file extension.
  533. Remarks:
  534. olb is apparently an extension that implies "old type library"-whatever
  535. that is.
  536. If no standard mapping is found, a CLASSPATHTYPE of ExeNamePath is
  537. returned.
  538. *****************************************************************************/
  539. {
  540. // extensions to map.
  541. static char * ExtArray[] =
  542. { ".dll",
  543. ".exe",
  544. ".cab",
  545. ".tlb",
  546. ".inf",
  547. ".olb"
  548. };
  549. // CLASSPATHTYPEs to map the extensions to.
  550. static CLASSPATHTYPE PathType[] =
  551. {
  552. DllNamePath,
  553. ExeNamePath,
  554. CabFilePath,
  555. TlbNamePath,
  556. InfFilePath,
  557. TlbNamePath
  558. };
  559. int index;
  560. int fFound = -1;
  561. for ( index = 0;
  562. index < sizeof( ExtArray ) / sizeof( char * );
  563. ++index )
  564. {
  565. if ( _stricmp( pExt, ExtArray[index] ) == 0 )
  566. {
  567. fFound = index;
  568. break;
  569. }
  570. }
  571. if ( fFound != -1 )
  572. {
  573. return PathType[ index ];
  574. }
  575. else
  576. return ExeNamePath;
  577. }
  578. LPOLESTR
  579. GetPath(
  580. char * pPath )
  581. /*****************************************************************************
  582. Purpose:
  583. Map a char * path to a wide character path
  584. In Arguments:
  585. pPath - Path to the file to translate to wide char.
  586. Out Arguments:
  587. None.
  588. InOut Arguments:
  589. None.
  590. Return Arguments:
  591. The translated file path.
  592. Remarks:
  593. *****************************************************************************/
  594. {
  595. if ( pPath )
  596. {
  597. LPOLESTR p = new OLECHAR[ (MAX_PATH+1) * 2 ];
  598. mbstowcs( p, pPath, strlen(pPath)+1 );
  599. return p;
  600. }
  601. return 0;
  602. }
  603. LPOLESTR
  604. GetSetupCommand(
  605. char * pSetupCommandLine )
  606. /*****************************************************************************
  607. Purpose:
  608. Translate setup command line to wide char.
  609. In Arguments:
  610. Setup command line.
  611. Out Arguments:
  612. None.
  613. InOut Arguments:
  614. None.
  615. Return Arguments:
  616. The translated setup command line.
  617. Remarks:
  618. For now the setup command line is setup.exe
  619. *****************************************************************************/
  620. {
  621. LPOLESTR p = new OLECHAR[ (MAX_PATH+1) * 2 ];
  622. mbstowcs( p, "setup.exe", strlen("setup.exe")+1 );
  623. return p;
  624. }
  625. LPOLESTR
  626. MakePackageName(
  627. char * pName )
  628. /*****************************************************************************
  629. Purpose:
  630. Translate package name to wide char.
  631. In Arguments:
  632. package name to translate.
  633. Out Arguments:
  634. None.
  635. InOut Arguments:
  636. None.
  637. Return Arguments:
  638. translated command line
  639. Remarks:
  640. *****************************************************************************/
  641. {
  642. LPOLESTR p = new OLECHAR[ (MAX_PATH+1) * 2 ];
  643. mbstowcs( p, pName, strlen(pName)+1 );
  644. return p;
  645. }
  646. LONG
  647. UpdateClassEntryFromAutoConvert(
  648. MESSAGE * pMessage,
  649. BasicRegistry * pCLSID,
  650. CLASS_ENTRY * pClassEntry )
  651. /*****************************************************************************
  652. Purpose:
  653. Update the classid entry in the data base with the autoconvert field.
  654. In Arguments:
  655. pMessage - Message block passing arguments between modules.
  656. pCLSID - pointer to class representing the registry key.
  657. pClassEntry - The class entry data structure to update.
  658. Out Arguments:
  659. None.
  660. InOut Arguments:
  661. None.
  662. Return Arguments:
  663. Status.
  664. Remarks:
  665. *****************************************************************************/
  666. {
  667. LONG error;
  668. char Data[SIZEOF_STRINGIZED_CLSID];
  669. DWORD SizeOfData = sizeof(Data)/sizeof(char);
  670. error = pCLSID->QueryValue( "AutoConvertTo", &Data[0], &SizeOfData );
  671. if ( error == ERROR_SUCCESS )
  672. {
  673. StringToCLSID(
  674. &Data[1],
  675. &pClassEntry->ClassAssociation.AutoConvertClsid );
  676. }
  677. return error;
  678. }
  679. LONG
  680. UpdateClassEntryFromTreatAs(
  681. MESSAGE * pMessage,
  682. BasicRegistry * pCLSID,
  683. CLASS_ENTRY * pClassEntry )
  684. /*****************************************************************************
  685. Purpose:
  686. Update the class entry in the database with the Treatas key.
  687. In Arguments:
  688. pMessage - Message block passing arguments between modules.
  689. pCLSID - pointer to class representing the registry key.
  690. pClassEntry - The class entry data structure to update.
  691. Out Arguments:
  692. None.
  693. InOut Arguments:
  694. None.
  695. Return Arguments:
  696. Status.
  697. Remarks:
  698. *****************************************************************************/
  699. {
  700. LONG error;
  701. char Data[SIZEOF_STRINGIZED_CLSID];
  702. DWORD SizeOfData = sizeof(Data)/sizeof(char);
  703. error = pCLSID->QueryValue( "TreatAs", &Data[0], &SizeOfData );
  704. if ( error == ERROR_SUCCESS )
  705. {
  706. StringToCLSID(
  707. &Data[1],
  708. &pClassEntry->ClassAssociation.TreatAsClsid );
  709. }
  710. return error;
  711. }
  712. LONG
  713. UpdateClassEntryFromAppID(
  714. MESSAGE * pMessage,
  715. BasicRegistry * pCLSID,
  716. CLASS_ENTRY * pClassEntry,
  717. char * pAppidBuffer )
  718. /*****************************************************************************
  719. Purpose:
  720. Update the class entry in the database with the Appid key.
  721. In Arguments:
  722. pMessage - Message block passing arguments between modules.
  723. pCLSID - pointer to class representing the registry key.
  724. pClassEntry - The class entry data structure to update.
  725. Out Arguments:
  726. pAppIdBuffer- Buffer which receives the stringized appid value.
  727. InOut Arguments:
  728. None.
  729. Return Arguments:
  730. Status.
  731. Remarks:
  732. This routine looks for the presence of an appid on a clsid. The appid
  733. key will determine the appdetails structure that the clsid will go into.
  734. *****************************************************************************/
  735. {
  736. LONG error;
  737. APP_ENTRY * pAppEntry = 0;
  738. DWORD SizeOfAppIDValue = SIZEOF_STRINGIZED_CLSID;
  739. char AppIDValue[ SIZEOF_STRINGIZED_CLSID ];
  740. BOOL fNewEntry = 0;
  741. error = pCLSID->QueryValueEx( "AppID", &AppIDValue[0], &SizeOfAppIDValue );
  742. if ( error == ERROR_SUCCESS )
  743. {
  744. memcpy( pAppidBuffer, &AppIDValue[0], SIZEOF_STRINGIZED_CLSID );
  745. return 1;
  746. }
  747. else
  748. return 0;
  749. }
  750. void
  751. SetCSPlatform(
  752. CSPLATFORM * pCSPlatform )
  753. {
  754. // OSVERSIONINFO VersionInformation;
  755. // VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  756. // GetVersionEx(&VersionInformation);
  757. // pCSPlatform->dwPlatformId = VersionInformation.dwPlatformId;
  758. // pCSPlatform->dwVersionHi = VersionInformation.dwMajorVersion;
  759. // pCSPlatform->dwVersionLo = VersionInformation.dwMinorVersion;
  760. #if 0
  761. // this is not supported for Beta 1
  762. pCSPlatform->dwPlatformId = -1; // any OS platform
  763. pCSPlatform->dwVersionHi = 0;
  764. pCSPlatform->dwVersionLo = 0;
  765. #else
  766. pCSPlatform->dwPlatformId = VER_PLATFORM_WIN32_NT;
  767. pCSPlatform->dwVersionHi = 5;
  768. pCSPlatform->dwVersionLo = 0;
  769. #endif
  770. // pCSPlatform->dwProcessorArch = PROCESSOR_ARCHITECTURE_INTEL;
  771. SYSTEM_INFO si;
  772. GetSystemInfo(&si);
  773. pCSPlatform->dwProcessorArch = si.wProcessorArchitecture;
  774. }